Documentation
¶
Index ¶
- type AlwaysReplaceStrategy
- type CMap
- func (m *CMap) Clear()
- func (m *CMap) Delete(key string)
- func (m *CMap) Get(key string) (int64, bool)
- func (m *CMap) Range(f func(key string, value int64) bool)
- func (m *CMap) Replace(key string, value int64) bool
- func (m *CMap) Set(key string, value int64)
- func (m *CMap) SetDefaultCompare(compare CompareFunc[int64])
- func (m *CMap) SetDefaultStrategy(strategy ReplaceStrategy[int64])
- func (m *CMap) Size() int
- type CMapGen
- func (m *CMapGen[K, V]) Clear()
- func (m *CMapGen[K, V]) Delete(key K)
- func (m *CMapGen[K, V]) Get(key K) (V, bool)
- func (m *CMapGen[K, V]) Range(f func(key K, value V) bool)
- func (m *CMapGen[K, V]) Replace(key K, value V) bool
- func (m *CMapGen[K, V]) ReplaceAlways(key K, value V) bool
- func (m *CMapGen[K, V]) ReplaceIfNotExists(key K, value V) bool
- func (m *CMapGen[K, V]) ReplaceWithCompare(key K, value V, compare CompareFunc[V]) bool
- func (m *CMapGen[K, V]) ReplaceWithStrategy(key K, value V, strategy ReplaceStrategy[V]) bool
- func (m *CMapGen[K, V]) Set(key K, value V)
- func (m *CMapGen[K, V]) SetDefaultCompare(compare CompareFunc[V])
- func (m *CMapGen[K, V]) SetDefaultStrategy(strategy ReplaceStrategy[V])
- func (m *CMapGen[K, V]) Size() int
- func (m *CMapGen[K, V]) UpsertWithCallback(key K, value V, callback func(exists bool, oldValue, newValue V) V) bool
- type CompareFunc
- type IMap
- type NumericGreaterStrategy
- type ReplaceStrategy
- type TimestampStrategy
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AlwaysReplaceStrategy ¶
type AlwaysReplaceStrategy[V any] struct{}
AlwaysReplaceStrategy is a ReplaceStrategy that unconditionally signals that the old value should be replaced by the new value.
func (AlwaysReplaceStrategy[V]) ShouldReplace ¶
func (s AlwaysReplaceStrategy[V]) ShouldReplace(oldValue, newValue V) bool
ShouldReplace always returns true, indicating the value should always be replaced.
type CMap ¶
type CMap struct {
// contains filtered or unexported fields
}
CMap is a thread-safe map with string keys and int64 values, backed by a concurrent map implementation. It satisfies the IMap[string, int64] interface.
func (*CMap) Get ¶
Get retrieves the value for the given key and a boolean indicating whether the key was found.
func (*CMap) Range ¶
Range iterates over all key-value pairs in the map, calling f for each one. Iteration stops early if f returns false.
func (*CMap) Replace ¶
Replace updates the value for the given key only when the new value is greater than the existing value. If the key does not exist, it is created with the new value. Returns true if the value was stored.
func (*CMap) Set ¶
Set stores the given value under the specified key, overwriting any existing value.
func (*CMap) SetDefaultCompare ¶
func (m *CMap) SetDefaultCompare(compare CompareFunc[int64])
SetDefaultCompare is a no-op for CMap; custom comparison functions are not supported on this implementation.
func (*CMap) SetDefaultStrategy ¶
func (m *CMap) SetDefaultStrategy(strategy ReplaceStrategy[int64])
SetDefaultStrategy is a no-op for CMap; the replacement strategy is fixed (greater-value wins) and cannot be customised on this implementation.
type CMapGen ¶
type CMapGen[K comparable, V any] struct { // contains filtered or unexported fields }
CMapGen is a generic, thread-safe concurrent map with comparable keys of type K and values of type V. Keys are converted to strings internally using keyToString. It supports pluggable replacement strategies and comparison functions.
func NewCMapGen ¶
func NewCMapGen[K comparable, V any]() *CMapGen[K, V]
NewCMapGen creates and returns a new CMapGen with no default replacement strategy configured. Until SetDefaultCompare or SetDefaultStrategy is called, Replace behaves like ReplaceAlways (unconditional overwrite) — see Replace's doc comment. V is unconstrained ("any"), so a strategy cannot be wired up automatically here: NumericGreaterStrategy, the built-in greater-value strategy, requires V to satisfy cmp.Ordered, which not every V does (e.g. a struct value type). Call SetDefaultStrategy(NumericGreaterStrategy[V]{}) explicitly when V is ordered and "new value wins" is the desired behaviour.
Example ¶
ExampleNewCMapGen shows how to create a generic concurrent map with string keys and int64 values, and configure a default comparison function so that Replace only updates when the new value is strictly greater.
package main
import (
"fmt"
"github.com/phcp-tech/common-library-golang/maps"
)
func main() {
m := maps.NewCMapGen[string, int64]()
m.SetDefaultCompare(func(old, new int64) bool { return new > old })
m.Set("USDJPY", 15000)
fmt.Println(m.Replace("USDJPY", 15100)) // true
fmt.Println(m.Replace("USDJPY", 14900)) // false
fmt.Println(m.Size())
}
Output: true false 1
func (*CMapGen[K, V]) Clear ¶
func (m *CMapGen[K, V]) Clear()
Clear removes all key-value pairs from the map.
func (*CMapGen[K, V]) Delete ¶
func (m *CMapGen[K, V]) Delete(key K)
Delete removes the entry associated with the given key from the map.
func (*CMapGen[K, V]) Get ¶
Get retrieves the value for the given key and a boolean indicating whether the key was found.
func (*CMapGen[K, V]) Range ¶
Range iterates over all key-value pairs in the map, calling f for each one. Iteration stops early if f returns false.
Example ¶
ExampleCMapGen_Range shows how to iterate over all entries. Returning false from the callback stops iteration early.
package main
import (
"fmt"
"github.com/phcp-tech/common-library-golang/maps"
)
func main() {
m := maps.NewCMapGen[string, int64]()
m.Set("A", 1)
m.Range(func(key string, val int64) bool {
fmt.Println(key, val)
return true
})
}
Output: A 1
func (*CMapGen[K, V]) Replace ¶
Replace conditionally updates the value for the given key according to the configured strategy. If a default compare function is set it takes precedence; otherwise the default strategy is used. If neither is configured, Replace always overwrites — identical to ReplaceAlways — since V is unconstrained and there is no generally-correct way to compare two arbitrary values without one. If the key does not exist it is always created. Returns true if the value was stored.
func (*CMapGen[K, V]) ReplaceAlways ¶
ReplaceAlways unconditionally stores value under key, overwriting any existing entry. It always returns true.
Example ¶
ExampleCMapGen_ReplaceAlways shows unconditional overwrite regardless of value.
package main
import (
"fmt"
"github.com/phcp-tech/common-library-golang/maps"
)
func main() {
m := maps.NewCMapGen[string, int64]()
m.Set("NZDUSD", 6500)
m.ReplaceAlways("NZDUSD", 6000) // always stored, even though 6000 < 6500
val, _ := m.Get("NZDUSD")
fmt.Println(val)
}
Output: 6000
func (*CMapGen[K, V]) ReplaceIfNotExists ¶
ReplaceIfNotExists stores value under key only when the key is not already present. Returns true if the value was stored, false if the key already existed.
Example ¶
ExampleCMapGen_ReplaceIfNotExists shows set-once semantics: value is stored only when the key is not already present.
package main
import (
"fmt"
"github.com/phcp-tech/common-library-golang/maps"
)
func main() {
m := maps.NewCMapGen[string, int64]()
fmt.Println(m.ReplaceIfNotExists("CADUSD", 7500)) // true — key absent
fmt.Println(m.ReplaceIfNotExists("CADUSD", 8000)) // false — key exists
val, _ := m.Get("CADUSD")
fmt.Println(val)
}
Output: true false 7500
func (*CMapGen[K, V]) ReplaceWithCompare ¶
func (m *CMapGen[K, V]) ReplaceWithCompare(key K, value V, compare CompareFunc[V]) bool
ReplaceWithCompare updates the value for the given key using the provided comparison function. The value is stored only when compare(existingValue, newValue) returns true. If the key does not exist the value is always stored. Returns true if the value was stored.
func (*CMapGen[K, V]) ReplaceWithStrategy ¶
func (m *CMapGen[K, V]) ReplaceWithStrategy(key K, value V, strategy ReplaceStrategy[V]) bool
ReplaceWithStrategy updates the value for the given key using the provided strategy. The value is stored only when strategy.ShouldReplace(existingValue, newValue) returns true. If the key does not exist the value is always stored. Returns true if the value was stored.
Example ¶
ExampleCMapGen_ReplaceWithStrategy shows how to supply a strategy ad-hoc without modifying the map's default configuration.
package main
import (
"fmt"
"github.com/phcp-tech/common-library-golang/maps"
)
func main() {
m := maps.NewCMapGen[string, int64]()
m.Set("AUDUSD", 7000)
// NumericGreaterStrategy replaces only when the new value is greater.
replaced := m.ReplaceWithStrategy("AUDUSD", 7200, maps.NumericGreaterStrategy[int64]{})
fmt.Println(replaced)
val, _ := m.Get("AUDUSD")
fmt.Println(val)
}
Output: true 7200
func (*CMapGen[K, V]) Set ¶
func (m *CMapGen[K, V]) Set(key K, value V)
Set stores the given value under the specified key, overwriting any existing value.
func (*CMapGen[K, V]) SetDefaultCompare ¶
func (m *CMapGen[K, V]) SetDefaultCompare(compare CompareFunc[V])
SetDefaultCompare sets the comparison function used by Replace to decide whether to overwrite an existing value. Setting a compare function clears any previously configured replacement strategy.
func (*CMapGen[K, V]) SetDefaultStrategy ¶
func (m *CMapGen[K, V]) SetDefaultStrategy(strategy ReplaceStrategy[V])
SetDefaultStrategy sets the replacement strategy used by Replace when no compare function is configured. Setting a strategy clears any previously configured compare function.
func (*CMapGen[K, V]) Size ¶
Size returns the number of key-value pairs currently stored in the map.
func (*CMapGen[K, V]) UpsertWithCallback ¶
func (m *CMapGen[K, V]) UpsertWithCallback(key K, value V, callback func(exists bool, oldValue, newValue V) V) bool
UpsertWithCallback inserts or updates the value for key using the provided callback. The callback receives whether the key existed, the old value (zero value if not), and the new value, and returns the value that should ultimately be stored. Always returns true.
Example ¶
ExampleCMapGen_UpsertWithCallback shows how to perform a read-modify-write using a callback. The callback receives whether the key existed, the old value, and the candidate new value, and returns the value to store.
This is NOT atomic across concurrent callers of the same key: Get and Set are two independent, separately-locked operations with the callback running in between, so two goroutines racing on the same key can both read the same old value and the last Set wins, regardless of which callback result should logically have won. It is safe under concurrent writes to different keys, and safe (no corruption/panic) even for the same key — it just doesn't guarantee the logically-correct value is the one that ends up stored. For a true atomic read-modify-write on a single key, use the underlying cmap.ConcurrentMap.Upsert directly, which holds the shard lock for the whole callback.
package main
import (
"fmt"
"github.com/phcp-tech/common-library-golang/maps"
)
func main() {
m := maps.NewCMapGen[string, int64]()
m.Set("CHFUSD", 1000)
// Keep the larger of the two values.
m.UpsertWithCallback("CHFUSD", 1200, func(exists bool, old, new int64) int64 {
if !exists || new > old {
return new
}
return old
})
val, _ := m.Get("CHFUSD")
fmt.Println(val)
}
Output: 1200
type CompareFunc ¶
CompareFunc is a function type used to compare an existing (old) map value against a candidate (new) value. It returns true when the new value should overwrite the old one.
type IMap ¶
type IMap[K comparable, V any] interface { // Set stores value under key, overwriting any existing entry. Set(key K, value V) // Get retrieves the value associated with key and reports whether the key was found. Get(key K) (V, bool) // Replace conditionally updates the value for key according to the configured strategy // or comparison function. Returns true if the value was stored. Replace(key K, value V) bool // Delete removes the entry associated with key from the map. Delete(key K) // Range iterates over all key-value pairs, calling f for each one. // Iteration stops early if f returns false. Range(f func(key K, value V) bool) // Size returns the number of key-value pairs currently stored in the map. Size() int // Clear removes all key-value pairs from the map. Clear() // SetDefaultStrategy sets the replacement strategy used by Replace when no compare // function is configured. SetDefaultStrategy(strategy ReplaceStrategy[V]) // SetDefaultCompare sets the comparison function used by Replace to decide whether // to overwrite an existing value. SetDefaultCompare(compare CompareFunc[V]) }
IMap defines a generic, thread-safe key-value map interface with pluggable replacement strategies. Implementations must support conditional replacement via Replace as well as configurable strategies and comparison functions.
func NewCMap ¶
NewCMap creates and returns a new CMap instance that satisfies the IMap[string, int64] interface.
Example ¶
ExampleNewCMap shows how to create a thread-safe string→int64 map and perform basic Set / Get / Replace / Delete operations.
package main
import (
"fmt"
"github.com/phcp-tech/common-library-golang/maps"
)
func main() {
m := maps.NewCMap()
m.Set("EURUSD", 10500)
m.Set("GBPUSD", 12800)
val, ok := m.Get("EURUSD")
fmt.Println(val, ok)
// Replace only stores the new value when it is greater than the stored one.
fmt.Println(m.Replace("EURUSD", 10600)) // true — 10600 > 10500
fmt.Println(m.Replace("EURUSD", 10400)) // false — 10400 < 10600
m.Delete("GBPUSD")
fmt.Println(m.Size())
}
Output: 10500 true true false 1
type NumericGreaterStrategy ¶
NumericGreaterStrategy is a ReplaceStrategy that replaces the old value only when newValue is greater than oldValue. V must satisfy cmp.Ordered (numeric types and string), so the comparison is a real ordered comparison — not a comparison of the values' string representations, which would give wrong answers for numeric types whenever the two values' formatted lengths differ (e.g. 9 vs 10).
func (NumericGreaterStrategy[V]) ShouldReplace ¶
func (s NumericGreaterStrategy[V]) ShouldReplace(oldValue, newValue V) bool
ShouldReplace returns true when newValue is greater than oldValue.
type ReplaceStrategy ¶
type ReplaceStrategy[V any] interface { // ShouldReplace returns true when the old value should be overwritten by the new value. ShouldReplace(oldValue, newValue V) bool }
ReplaceStrategy defines the interface for a pluggable replacement strategy used by map implementations.
type TimestampStrategy ¶
type TimestampStrategy struct {
MinInterval int64 // minimum required difference (newValue - oldValue) for a replacement to occur
}
TimestampStrategy is a ReplaceStrategy that accepts a new int64 value only when the difference between the new and old value meets a minimum threshold. Typical use case: accept a new timestamp only when it is sufficiently newer than the stored one.
Example ¶
ExampleTimestampStrategy shows how to accept a new value only when it exceeds the stored value by at least a minimum interval.
package main
import (
"fmt"
"github.com/phcp-tech/common-library-golang/maps"
)
func main() {
m := maps.NewCMapGen[string, int64]()
m.Set("tick", 1000)
s := maps.TimestampStrategy{MinInterval: 10}
fmt.Println(m.ReplaceWithStrategy("tick", 1015, s)) // true — diff 15 >= 10
fmt.Println(m.ReplaceWithStrategy("tick", 1020, s)) // true — diff 5 < 10? no, 1020-1015=5
val, _ := m.Get("tick")
fmt.Println(val)
}
Output: true false 1015
func (TimestampStrategy) ShouldReplace ¶
func (s TimestampStrategy) ShouldReplace(oldValue, newValue int64) bool
ShouldReplace returns true when newValue-oldValue is at least MinInterval.