-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmightymap.go
129 lines (114 loc) · 4.26 KB
/
mightymap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Package mightymap provides a thread-safe, generic map implementation with configurable storage backends.
// It offers type-safe operations through Go generics and flexibility in choosing different storage engines
// depending on performance and feature requirements.
//
// The package supports multiple storage backends:
// - Default in-memory map with mutex locking
// - Swiss storage for optimized performance using swiss tables
// - BadgerDB storage for persistent key-value storage
//
// Key features:
// - Thread-safe operations
// - Generic support for any comparable key type and any value type
// - Configurable overwrite behavior
// - Pluggable storage backends
// - Comprehensive API including Store, Load, Delete, Range, Pop, and more
//
// Example usage:
//
// cm := mightymap.New[int, string](true)
// c.Store(1, "one")
// value, ok := c.Load(1)
//
// For custom storage backends:
//
// store := storage.NewMightyMapDefaultStorage[int, string]()
// cm := mightymap.New[int, string](true, store)
package mightymap
import (
"context"
"github.com/thisisdevelopment/mightymap/storage"
)
// Map provides a thread-safe map implementation with configurable storage backend.
// Type parameters:
// - K: the key type, must be comparable
// - V: the value type, can be any type
type Map[K comparable, V any] struct {
storage storage.IMightyMapStorage[K, V]
allowOverwrite bool
}
// New creates a new concurrent map instance.
// Parameters:
// - allowOverwrite: if true, existing keys can be overwritten with Store(); if false, Store() will only insert new keys
// - storages: optional storage implementation; if none provided, uses default storage (map[K]V with mutex locking)
//
// Returns a new Map instance with the specified storage engine (or default) and overwrite behavior
func New[K comparable, V any](allowOverwrite bool, storages ...storage.IMightyMapStorage[K, V]) *Map[K, V] {
var store storage.IMightyMapStorage[K, V]
if len(storages) == 0 {
store = storage.NewMightyMapDefaultStorage[K, V]()
} else {
store = storages[0]
}
return &Map[K, V]{
storage: store,
allowOverwrite: allowOverwrite,
}
}
// Load retrieves a value from the map for the given key.
// Returns the value and true if found, zero value and false if not present.
func (m *Map[K, V]) Load(ctx context.Context, key K) (value V, ok bool) {
return m.storage.Load(ctx, key)
}
// Has checks if a key exists in the map.
// Returns true if the key exists, false otherwise.
func (m *Map[K, V]) Has(ctx context.Context, key K) (ok bool) {
_, ok = m.storage.Load(ctx, key)
return
}
// Store inserts or updates a value in the map for the given key.
// If allowOverwrite is false, it will only insert if the key doesn't exist.
func (m *Map[K, V]) Store(ctx context.Context, key K, value V) {
if _, ok := m.storage.Load(ctx, key); !ok || m.allowOverwrite {
m.storage.Store(ctx, key, value)
}
}
// Delete removes one or more keys and their associated values from the map.
func (m *Map[K, V]) Delete(ctx context.Context, keys ...K) {
m.storage.Delete(ctx, keys...)
}
// Range iterates over the map's key-value pairs in an unspecified order,
// calling the provided function for each pair.
// If the function returns false, iteration stops.
func (m *Map[K, V]) Range(ctx context.Context, f func(key K, value V) bool) {
m.storage.Range(ctx, f)
}
// Pop retrieves and removes a value from the map.
// Returns the value and true if found, zero value and false if not present.
func (m *Map[K, V]) Pop(ctx context.Context, key K) (value V, ok bool) {
value, ok = m.storage.Load(ctx, key)
if !ok {
return value, ok
}
m.storage.Delete(ctx, key)
return value, true
}
// Next returns the next key-value pair from the map.
// The iteration order is not specified.
// Returns zero values and false when there are no more items.
func (m *Map[K, V]) Next(ctx context.Context) (value V, key K, ok bool) {
key, value, ok = m.storage.Next(ctx)
return
}
// Len returns the number of key-value pairs in the map.
func (m *Map[K, V]) Len(ctx context.Context) int {
return m.storage.Len(ctx)
}
// Clear removes all key-value pairs from the map.
func (m *Map[K, V]) Clear(ctx context.Context) {
m.storage.Clear(ctx)
}
// Close closes the map
func (m *Map[K, V]) Close(ctx context.Context) error {
return m.storage.Close(ctx)
}