diff --git a/README.md b/README.md index 8914f6f..eae0813 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,57 @@ # safe-map +A thread-safe map implementation for Go with simple API and full concurrency support. +## Features +- ✅ Thread-safe operations +- ✅ Generic type support +- ✅ Simple and intuitive API +- ✅ Full concurrency support +- ✅ Lightweight implementation + +## Installation +```bash +go get git.neurocipta.com/rogerferdinan/safe-map +``` + +## Usage +```go +package main + +import ( + "fmt" + "log" + safemap "git.neurocipta.com/rogerferdinan/safe-map" +) + +func main() { + // Create a new SafeMap with string keys and int values + m := safemap.NewSafeMap[string, int]() + + // Store data to SafeMap + m.Store("abc", 1) // Add + m.Store("abc", 2) // Update existing key-value + + // Get length of SafeMap + length := m.Len() + fmt.Printf("Map length: %d\n", length) + + // Load key-value + value, ok := m.Load("abc") + if !ok { + log.Fatal("abc is not exists") + } + fmt.Printf("Value for 'abc': %v\n", value) + + // Iterate over all key-value pairs + m.Range(func(k string, v int) bool { + fmt.Printf("key: %s, value: %v\n", k, v) + return true // true = continue the loop, false = break the loop + }) + + // Delete key-value + m.Delete("abc") +} +``` + +## Thread Safety +All operations are thread-safe and can be safely called from multiple goroutines simultaneously. \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..bbfee6c --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.neurocipta.com/rogerferdinan/safe-map + +go 1.24.5 diff --git a/map.go b/map.go new file mode 100644 index 0000000..dd56cc8 --- /dev/null +++ b/map.go @@ -0,0 +1,49 @@ +package safemap + +import "sync" + +type SafeMap[K comparable, V any] struct { + m sync.Map +} + +func NewSafeMap[K comparable, V any]() *SafeMap[K, V] { + return &SafeMap[K, V]{ + m: sync.Map{}, + } +} + +func (sm *SafeMap[K, V]) Store(key K, value V) { + sm.m.Store(key, value) +} + +func (sm *SafeMap[K, V]) Load(key K) (value V, ok bool) { + val, loaded := sm.m.Load(key) + if !loaded { + return *new(V), false + } + return val.(V), true +} + +func (sm *SafeMap[K, V]) Delete(key K) { + sm.m.Delete(key) +} + +func (sm *SafeMap[K, V]) Range(f func(K, V) bool) { + sm.m.Range(func(key, value any) bool { + k, ok1 := key.(K) + v, ok2 := value.(V) + if !ok1 || !ok2 { + return true + } + return f(k, v) + }) +} + +func (sm *SafeMap[K, V]) Len() int { + count := 0 + sm.Range(func(_ K, _ V) bool { + count++ + return true + }) + return count +}