omap

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 15, 2026 License: MIT Imports: 4 Imported by: 0

README

OMAP an Ordered Map

Yet another sorted map in go.. but not really.

Technically the omap package implements very minital btree using a slice. The drivers of the design process, were the performance objectives. The btree implementation is ordered and does not allow for duplicates; The internals manage keys by splicing the internal slice, without the use of a temporary slice. The side effect of this design results in what operates exactly like ordered map.

Performance objectives while maintinaing a sorted map:

  • Lookups for both Put and Get operations are always a fixed complexity: o(log n).
  • All iteration operations are fixed cost of o(1).
  • Finding or removing elements between 2 points is always a fixed cost of o(log(n) + log(n)).
  • Finding elements before or after a given point is always a fixed cost of o(log n)
  • Mass Removal of unordered elements that may or may not exist has a maximum complexity of o(log(n) + log(k) + k)
  • Pre-emptive but predictable growth, this is done by setting the Growth size.

When Should you use omap?

Any one of these is a practical use case:

  • An ordered map is required
  • Fuzzy logic is required, IE the ability to find points in between keys
  • When a combination of freequent updates and searching by ranges is requried
  • Memory is more important than cpu time for your maps

Basic usage

The omap package provides a common interface OrderedMap implemented by the following:

Creating ThreadSafe instance Example:

	kv:=NewTs[string,string](cmp.Compare)
	// Save a value
	kv.Put("Hello"," ")
	kv.Put("World","!\n")

	// Itertor
	for k,v :=range kv.All {
		fmt.Printf("%s%s",k,v)
	}

The resulting output will be:

	"Hello World!\n"

We can now make things a bit smaller by removing things by a range.

// Note, both "Sell" and "Universe", were never added to the instance,
// but the between operation works on these keys any ways.
kv.RemoveBetween("Sell","Universe")

// Itertor
for k,v :=range kv.All() {
   fmt.Printf("%s%s\n",k,v)
}

The resulting output will now be:

"Hello \n"

Why this works?

  • The string "Sell" comes before the string "World"
  • The string "Universe" comes after the string "World"

How this works

The index lookup creates 2 values for each potential key:

  • Array postion, example: 0
  • Offset can be any of the following: -1,0,1

Since lookups create both an index position and offsett, it becomes possible to look for the following:

  • Elements before the array
  • Positions between elements of the array
  • Elements after the array
  • Elements to overwrite

API

Constructors

The omap package supports any key type you can provide a compare function for, but a map in go only supports a comparable key type. This means any map can be converted to an OrderedMap instance, but not every OrderedMap instance can be converted to a map.

Function Types Arguments Returns Thread Safe
omap.New K any, V any func(a, b K) int *SliceTree[K, V] false
omap.NewFromMap [K comparable, V any] map[K]V, func(a, b K) int *SliceTree[K, V] false
omap.NewSliceTree K any, V any int, func(a, b K) int *SliceTree[K, V] false
omap.NewTs K any, V any func(a, b K) int OrderedMap[K, V] true
omap.ToMap K comparable, V any OrderedMap[K, V] map[K]V false

As a note, any instance of SliceTree can create a thread safe instance of itself, by calling the s.ToTs() method. If you create a thread safe instance, you should stop using the old instance.

Example conversion from map to a thread safe OrderedMap instance:

s:=omap.NewFromMap(myMap,cb).ToTs()

To check if an instance is thread safe call the s.ThreadSafe() method.

var om OrderedMap[string,int]=New(cb)

if !om.ThreadSafe() {
	om=om.ToTs()
}

Why not always provide a thread safe instance? A thread safe instance requires mutex locking, this limits what can be done even when operations are atomic. Example: You may have a perfectly valid reason to call an iterator from within an iterator on the same instance; This cannot be done when a mutex lock is applied to an existing instance.

OrderedMap Methods

The following table provides a general overview of the methods in OrderedMap.

Method Arguments Teturn types Description
All iter.Seq2[K, V] iterator for all Keys and Values
Keys iter.Seq[K] iterator for all keys
Values iter.Seq[V] iterator for all Values
Exists key K bool true if the key was found
Contains key K bool true if the key is between both the FirstKey and LastKey
Put key K, value V int Sets the key and value pair
Get key K value V, ok bool Returned the value for the key if ok is true
Remove key K value V, ok bool If ok is true, the returned value was removed based on the given key
RemoveAll int Clears all elements and returns how many elements were removed
MassRemove keys ...K int Tries to remove all keys provided, returns how many keys were removed
MassRemoveKV keys ...K iter.Seq2[int, K] Tries to remove all keys provided. The iterator with a copy of all key value pairs that were removed
Size int returns the number of key/value pairs in the instance
FirstKey key K, ok bool When ok is true the first key in the instance is returned
LastKey key K, ok bool When ok is true the last key in the instance is returned
Between a,b K, opt ...int total int Returns the number of elements between a and b. For options See
BetweenKV a,b K, opt ...int iter.Seq2[int, K] Returns an iterator that contains the key/value pairs between a and b. For options See
RemoveBetween a,b K, opt ...int int Returns the number of elements removed between a and b. For options See
RemoveBetweenKV a,b K, opt ...int iter.Seq2[int, K] Returns an iterator that contains the key/value pairs that were moved from between a and b. For options See
ThreadSafe bool Returns true if this instance is thread safe
Merge set OrderedMap[K, V] int Merges set into this instance
SetOverwrite cb func(key K, oldValue, newValue V) Sets the callback method that fires before a value is overwritten
SetGrowth grow int Sets the internal growth value for the slice
ToTs() OrderedMap[K, V] If this instance is not contained in a thread safe wrapper, returns this instance in a thread safe wrapper, other wise returns this instance
Between Options

The following table exlains the usage and possible values for functions that support between operations.

opt[id] Options Description
0 omap.FIRST_KEY When set, the a field is ignored and s.FirstKey is used in its place
0 omap.LAST_KEY When set, the b field is ignored and s.LastKey is used in its place
0 omap.FIRST_KEY|omap.LAST_KEY This causes both a and b to be ignored

Example using s.BetweenKV:

  for k,v :=s.BetweenKV("","Tomorrow",omap.FIRSTKEY) {
    fmt.Printf("Key: [%s], Value: [%d]\n")
  }

Returns all values up to "Tomorrow".

Benchmarks

So benchmarks are always very subjective, but the real question is: what do we compare omap too? The only real answer is the native map in go. Now this is in no way a fair comparison.. The omap package can use any data set, so long as a compare function can be provided, while the map in go only needs to be optimized internally for hashing bytes, so we would expected the native map feature to be an order of magnitude faster.

How well does omap compare native map feature in go?:

BenchmarkNew/Native_map,_size:_[4],_keys:_[100]-10                623304              1788 ns/op            5464 B/op          4 allocs/op
BenchmarkNew/Slicetree,_size_[4],_count_[100]-10                  298898              3862 ns/op            2736 B/op          2 allocs/op
BenchmarkNew/Native_map,_Get_size:_[4],_keys:_[100]-10            755082              1581 ns/op               0 B/op          0 allocs/op
BenchmarkNew/SliceTree,_Get_size:_[4],_keys:_[100]-10             331154              3565 ns/op               0 B/op          0 allocs/op
BenchmarkNew/Native_map,_size:_[4],_keys:_[400]-10                151936              7871 ns/op           21848 B/op          4 allocs/op
BenchmarkNew/Slicetree,_size_[4],_count_[400]-10                   57602             20789 ns/op            9776 B/op          2 allocs/op
BenchmarkNew/Native_map,_Get_size:_[4],_keys:_[400]-10             89725             13153 ns/op               0 B/op          0 allocs/op
BenchmarkNew/SliceTree,_Get_size:_[4],_keys:_[400]-10              37513             31975 ns/op               0 B/op          0 allocs/op
BenchmarkNew/Native_map,_size:_[4],_keys:_[900]-10                 53892             22983 ns/op           98432 B/op          6 allocs/op
BenchmarkNew/Slicetree,_size_[4],_count_[900]-10                   21109             56476 ns/op           21808 B/op          2 allocs/op
BenchmarkNew/Native_map,_Get_size:_[4],_keys:_[900]-10             31167             38754 ns/op               0 B/op          0 allocs/op
BenchmarkNew/SliceTree,_Get_size:_[4],_keys:_[900]-10              15006             79956 ns/op               0 B/op          0 allocs/op
BenchmarkNew/Native_map,_size:_[4],_keys:_[1600]-10                43485             27773 ns/op           98432 B/op          6 allocs/op
BenchmarkNew/Slicetree,_size_[4],_count_[1600]-10                   9874            117807 ns/op           41008 B/op          2 allocs/op
BenchmarkNew/Native_map,_Get_size:_[4],_keys:_[1600]-10            10000            108882 ns/op               0 B/op          0 allocs/op
BenchmarkNew/SliceTree,_Get_size:_[4],_keys:_[1600]-10              7345            147573 ns/op               0 B/op          0 allocs/op

So what do these numbers really tell us? Well nothing we didn't all ready know prior to the benchmark. The map feature of go trades memory for read and write speed, in particular on wirte. Usually platforms are more cpu constrained than memory constrained, but that isn't always the case.

On write:

  • Go map map is on average 45%-70% faster than omap.SliceTree.

On read:

  • Go map on average is about 27%-55% faster Than omap.SliceTree

Where the native map in go always perfoms worse is in memory usage:

  • Go map uses about 45%-70% more memory than omap.SliceTree.

So is there an order of magnitued in the performance difference? No.. but a map in go is faster for general put/get operations. In truth the average difference in memory cost is about the same difference in read and write speed. The omap package is not a replacement for maps in go, omap is a solution to a very niche set of problems for go.

Documentation

Overview

Yet another sorted map in go.. but not really.

Technically the omap package implements very minital btree using a slice. The drivers of the design process, were the performance objectives. The btree implementation is ordered and does not allow for duplicates; The internals manage keys by splicing the internal slice, without the use of a temporary slice. The side effect of this design results in what operates exactly like an ordered map.

Unlike a map in go, keys are not constrained to a comparable type. In stead a compare funciton must be passed to the constructor.

Performance objectives:

  • Lookups for both Put and Get operations are always a fixed complexity: o(log n).
  • All iteration operations are fixed cost of o(1).
  • Finding or removing elements between 2 elements is always a fixed cost of o(log(n) + log(n)).
  • Finding elements before or after a given point is always a fixed cost of o(log n)
  • Mass Removal of unordered elements that may or may not exist has a maximum complexity of o(log(n) + log(k) + k)
  • Pre-emptive but predictable growth, this is done by setting the Growth size.

The omap package provides a common interface OrderedMap implemented by the following:

Basic Example:

kv:=New[string,string](cmp.Compare)
// Save a value
kv.Put("Hello"," ")
kv.Put("World","!\n")

// Itertor
for k,v :=range kv.All {
	fmt.Printf("%s%s",k,v)
}

The resulting output will be:

"Hello World!\n"

We can now make things a bit smaller by removing things by a range.

kv.RemoveBetween("Sell","Universe")

// Itertor
for k,v :=range kv.All {
	fmt.Printf("%s%s\n",k,v)
}

The resulting output will now be:

"Hello \n"

The index lookup creates 2 values for each potential key:

  • Array postion, example: 0
  • Offset can be any of the following: -1,0,1

Since lookups create both an index position and offsett, it becomes possible to look for the following:

  • Elements before the array
  • Positions between elements of the array
  • Elements after the array
  • Elements to overwrite

Index

Constants

View Source
const (
	FIRST_KEY = 1
	LAST_KEY  = 2
)

Variables

This section is empty.

Functions

func GetIndex

func GetIndex[K any, V any](k K, Cmp func(a, b K) int, Slices []KvSet[K, V]) (index, offset int)

Returns the index and offset of a given key.

The index is the current relative postion in the slice.

The offset represents where the item would be placed:

  • offset of 0, at index value.
  • offset of 1, expand the slice after the inddex and put the value to the right of the index
  • offset of -1, expand the slice before the index and put the value to left of the current postion

Complexity: o(log n)

func KvIter

func KvIter[K any, V any](set []KvSet[K, V]) iter.Seq2[K, V]

func Merge

func Merge[K comparable, V any](dst OrderedMap[K, V], src map[K]V) int

Merges a map into an OrderedMap instance.

func ToMap

func ToMap[K comparable, V any](src OrderedMap[K, V]) map[K]V

Utility method, to convert from an OrderedMap instance to a regular map. Due to constraints placed on maps in go, this feature is implemented as a function, not a method.

func TsKvIterWrapper

func TsKvIterWrapper[K any, V any](seq iter.Seq2[K, V]) iter.Seq2[K, V]

Takes an existing K,V iterator and returns a thread safe version.

Types

type KvSet

type KvSet[K any, V any] struct {
	Key   K
	Value V
}

type OrderedMap

type OrderedMap[K any, V any] interface {
	// Should return an iterator for all key/value pairs
	All() iter.Seq2[K, V]

	// Returns all keys, the int just expected to be a sequential number
	Keys() iter.Seq[K]

	// Returns all the values, the int is expected to be a sequential number
	Values() iter.Seq[V]

	// Returns true if the key exists, false if it does not.
	Exists(key K) bool

	// Returns true if the key is between the first and last key
	Contains(key K) bool

	// Sets the key to the value, returns the index id.
	Put(key K, value V)

	// Tries to get the value using the given key.
	// If the key exists, found is set to true, if the key does not exists then found is set to false.
	Get(key K) (value V, found bool)

	// Tries to remove the given key, returns value is set if ok is true.
	Remove(key K) (value V, ok bool)

	// Removes all elements.
	// Returns how many element were removed.
	RemoveAll() int

	// Attempts to remove all keys, returns the number of keys removed.
	MassRemove(keys ...K) (total int)

	// Attempts to remove all keys, returns an iterator with the key/value pairs
	MassRemoveKV(keys ...K) iter.Seq2[K, V]

	// Returns the current number of key/value pairs.
	Size() int

	// If ok is true, returns the first key.
	FirstKey() (key K, ok bool)

	// If ok is true, returns the last key.
	LastKey() (key K, ok bool)

	// Returns total number of elements between a and b.
	// Neither a or b are required to exist.
	//
	// The the optional opt argument:
	//  - When: opt[0]==omap.FIRST_KEY, a is ignored and the FirstKey is used.
	//  - When: opt[0]==omap.LAST_KEY, b is ignored and the LastKey is used.
	//  - To Ignore both a and b, set: opt[0]==omap.FIRST_KEY|omap.LAST_KEY.
	Between(a, b K, opt ...int) (total int)

	// Returns an iterator that contains the key value sets between a and b.
	// Neither a or b are required to exist.
	//
	// The the optional opt argument:
	//  - When: opt[0]==omap.FIRST_KEY, a is ignored and the FirstKey is used.
	//  - When: opt[0]==omap.LAST_KEY, b is ignored and the LastKey is used.
	//  - To Ignore both a and b, set: opt[0]==omap.FIRST_KEY|omap.LAST_KEY.
	BetweenKV(a, b K, opt ...int) (seq iter.Seq2[K, V])

	// Trys to delete the elements between a and b, returns the total number of elements deleted.
	// Neither a or b are required to exist.
	//
	// The the optional opt argument:
	//  - When: opt[0]==omap.FIRST_KEY, a is ignored and the FirstKey is used.
	//  - When: opt[0]==omap.LAST_KEY, b is ignored and the LastKey is used.
	//  - To Ignore both a and b, set: opt[0]==omap.FIRST_KEY|omap.LAST_KEY.
	RemoveBetween(a, b K, opt ...int) (total int)

	// Trys to delete the elements between a and b, returns an iterator that contains removed K,V pairs.
	// Neither a or b are required to exist.
	//
	// The the optional opt argument:
	RemoveBetweenKV(a, b K, opt ...int) (seq iter.Seq2[K, V])

	// Should return true if the instance is thread safe, fakse if not.
	ThreadSafe() bool

	// Merges a given [OrderedMap] into this one.
	// Returns the number of keys added
	Merge(set OrderedMap[K, V]) int

	// Sets the overwrite notice.  Its good to know when things change!
	SetOverwrite(cb func(key K, oldValue, newValue V))

	// Sets the growth value.
	SetGrowth(grow int)

	// Returns a thread safe instance.
	// If the instance is all ready thread safe, then the current instance is returned.
	ToTs() OrderedMap[K, V]
}

func NewTs

func NewTs[K any, V any](Cmp func(a, b K) int) (Map OrderedMap[K, V])

Creates a new thread safe OrderedMap instance.

type SliceTree

type SliceTree[K any, V any] struct {

	// Internally managed keys slice
	Slices []KvSet[K, V]

	// Compare function.
	Cmp func(a, b K) int

	// Required non 0 value, determins by what capacity we grow the internal
	// Slice.  Default is 1.
	Growth int

	// Required non nil value, called when ever a value is overwritten.
	// Seting this funtion saves on having to write a check when data is overwritten.
	OnOverWrite func(key K, oldValue V, newValue V)
}

func New

func New[K any, V any](cb func(a, b K) int) *SliceTree[K, V]

Creates a new SliceTee with the default Slices size of 100. If you require more control over the starting size of the slice use the NewSliceTree function in stead.

func NewFromMap

func NewFromMap[K comparable, V any](m map[K]V, cb func(a, b K) int) *SliceTree[K, V]

func NewSliceTree

func NewSliceTree[K any, V any](size int, cb func(a, b K) int) *SliceTree[K, V]

Creatss a new SliceTree with the internal Slice set to "size".

func (*SliceTree[K, V]) All

func (s *SliceTree[K, V]) All() iter.Seq2[K, V]

Returns an iterator for key/value pars. The internals of this iterator do not lock the tree or prevent updates. You can safely call an iterator from with an iterator. and not run into deadlocks.

func (*SliceTree[K, V]) Between

func (s *SliceTree[K, V]) Between(a, b K, opt ...int) (total int)

Between implements OrderedMap

func (*SliceTree[K, V]) BetweenKV

func (s *SliceTree[K, V]) BetweenKV(a, b K, opt ...int) (seq iter.Seq2[K, V])

BetweenKV implements OrderedMap

func (*SliceTree[K, V]) Contains

func (s *SliceTree[K, V]) Contains(key K) bool

func (*SliceTree[K, V]) Exists

func (s *SliceTree[K, V]) Exists(k K) bool

Returns true if the k exists in the slcie. Complexity: o(log n)

func (*SliceTree[K, V]) FirstKey

func (s *SliceTree[K, V]) FirstKey() (key K, ok bool)

GetFirstKey implements OrderedMap

func (*SliceTree[K, V]) Get

func (s *SliceTree[K, V]) Get(k K) (value V, found bool)

Tries to fetch value based on key of k, if k does not exist, found is false.

func (*SliceTree[K, V]) Keys

func (s *SliceTree[K, V]) Keys() iter.Seq[K]

Returns an iterator for the current keys. The internals of this iterator do not lock the tree or prevent updates. You can safely call an iterator from with an iterator. and not run into deadlocks.

func (*SliceTree[K, V]) LastKey

func (s *SliceTree[K, V]) LastKey() (key K, ok bool)

GetLastKey implements OrderedMap

func (*SliceTree[K, V]) MassRemove

func (s *SliceTree[K, V]) MassRemove(args ...K) (total int)

Attempts to remove the keys from the tree in bulk. Returns the number of keys removed.

This is almost always faster than just looping over a list of keys and calling Remove one key at a time. The internals of The MassRemove method deletes elements in squential contiguys blocks: reducing on the number of internal splice operations.

Complexity:

Worst case shown (Per key removed or k): o(log(n) + o(log k) + 2*k).

In truth, the real world complexity is drastically reduced by the following:

  • Deletetion of duplicate keys.
  • Keys being deleted do not exist.

The complexity is defined by the steps required:

  • Index lookups: o(log n) +k
  • child index is created to de-duplicate and order keys for deletion: o(log k)
  • key deletion is done in contiguous blocks: k

func (*SliceTree[K, V]) MassRemoveKV

func (s *SliceTree[K, V]) MassRemoveKV(args ...K) iter.Seq2[K, V]

func (*SliceTree[K, V]) Merge

func (s *SliceTree[K, V]) Merge(set OrderedMap[K, V]) int

Merge implements OrderedMap

func (*SliceTree[K, V]) Put

func (s *SliceTree[K, V]) Put(k K, v V)

Sets the key/vale pair and returns the index id. Comlexity: o(log n)

func (*SliceTree[K, V]) Remove

func (s *SliceTree[K, V]) Remove(k K) (value V, ok bool)

Tries to remove the element of k, returns false if it fails. Complexity: o(log n)

func (*SliceTree[K, V]) RemoveAll

func (s *SliceTree[K, V]) RemoveAll() int

Removes all elements in the slice, but keeps the memory allocated.

func (*SliceTree[K, V]) RemoveBetween

func (s *SliceTree[K, V]) RemoveBetween(a, b K, opt ...int) (total int)

RemoveBetween implements OrderedMap

func (*SliceTree[K, V]) RemoveBetweenKV

func (s *SliceTree[K, V]) RemoveBetweenKV(a, b K, opt ...int) (removed iter.Seq2[K, V])

RemoveBetween implements OrderedMap

func (*SliceTree[K, V]) Set

func (s *SliceTree[K, V]) Set(index int, v V) (status bool)

Sets the value in the index to v. The last index value returned from Put to update the last index point. This lets you bypass the o(log n) update complexity for writing to the same element over and over again. The internals still call s.OnOverWrite for you.

func (*SliceTree[K, V]) SetGrowth

func (s *SliceTree[K, V]) SetGrowth(grow int)

SetGrowth implements OrderedMap

func (*SliceTree[K, V]) SetIndex

func (s *SliceTree[K, V]) SetIndex(idx, offset int, k K, v V) (index int)

Sets the given k,v pair based on the index and offset provided by a call to GetIndex. Returns the resulting array index id.

Using a combinaiton of GetIndex and SetIndex lets you bypass the o(log n) comlexity when wiring to the same node over and over again. The value reutrned from Put can be used to update the internals using SetIndex with the offset being 0.

func (*SliceTree[K, V]) SetOverwrite

func (s *SliceTree[K, V]) SetOverwrite(cb func(key K, oldValue, newValue V))

Sets the internal OnOverWrite function.

func (*SliceTree[K, V]) Size

func (s *SliceTree[K, V]) Size() int

Returns the total number key/value pairs in the slice.

func (*SliceTree[K, V]) ThreadSafe

func (s *SliceTree[K, V]) ThreadSafe() bool

Returns false.

func (*SliceTree[K, V]) ToTs

func (s *SliceTree[K, V]) ToTs() OrderedMap[K, V]

Returns a thread safe instnace from the current instance.

func (*SliceTree[K, V]) UnSafeMassRemove

func (s *SliceTree[K, V]) UnSafeMassRemove(keys ...K)

This method is by defenition, unsafe, but fast.

Only use if the keys being removed meet all of the following requirements:

  • no duplicate keys
  • keys are in ascending ordered
  • all keys currently exist in the internals of the tree

Complexity: key=keys; o(log n +k)

func (*SliceTree[K, V]) Values

func (s *SliceTree[K, V]) Values() iter.Seq[V]

Returns an iterator for the current values The internals of this iterator do not lock the tree or prevent updates. You can safely call an iterator from with an iterator. and not run into deadlocks.

type ThreadSafeOrderedMap

type ThreadSafeOrderedMap[K any, V any] struct {
	// Instance to wrap for locking
	Tree OrderedMap[K, V]
	// contains filtered or unexported fields
}

func (*ThreadSafeOrderedMap[K, V]) All

func (s *ThreadSafeOrderedMap[K, V]) All() iter.Seq2[K, V]

All implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) Between

func (s *ThreadSafeOrderedMap[K, V]) Between(a, b K, opt ...int) (total int)

Between implements OrderedMap

func (*ThreadSafeOrderedMap[K, V]) BetweenKV

func (s *ThreadSafeOrderedMap[K, V]) BetweenKV(a, b K, opt ...int) (seq iter.Seq2[K, V])

BetweenKV implements OrderedMap

func (*ThreadSafeOrderedMap[K, V]) Contains

func (s *ThreadSafeOrderedMap[K, V]) Contains(key K) bool

func (*ThreadSafeOrderedMap[K, V]) Exists

func (s *ThreadSafeOrderedMap[K, V]) Exists(key K) bool

Exists implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) FirstKey

func (s *ThreadSafeOrderedMap[K, V]) FirstKey() (key K, ok bool)

GetFirstKey implements OrderedMap

func (*ThreadSafeOrderedMap[K, V]) Get

func (s *ThreadSafeOrderedMap[K, V]) Get(key K) (value V, found bool)

Get implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) Keys

func (s *ThreadSafeOrderedMap[K, V]) Keys() iter.Seq[K]

Keys implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) LastKey

func (s *ThreadSafeOrderedMap[K, V]) LastKey() (key K, ok bool)

GetLastKey implements OrderedMap

func (*ThreadSafeOrderedMap[K, V]) MassRemove

func (s *ThreadSafeOrderedMap[K, V]) MassRemove(keys ...K) (total int)

MassRemove implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) MassRemoveKV

func (s *ThreadSafeOrderedMap[K, V]) MassRemoveKV(keys ...K) iter.Seq2[K, V]

func (*ThreadSafeOrderedMap[K, V]) Merge

func (s *ThreadSafeOrderedMap[K, V]) Merge(set OrderedMap[K, V]) int

Merge implements OrderedMap

func (*ThreadSafeOrderedMap[K, V]) Put

func (s *ThreadSafeOrderedMap[K, V]) Put(key K, value V)

Put implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) Remove

func (s *ThreadSafeOrderedMap[K, V]) Remove(key K) (V, bool)

Remove implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) RemoveAll

func (s *ThreadSafeOrderedMap[K, V]) RemoveAll() int

RemoveAll implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) RemoveBetween

func (s *ThreadSafeOrderedMap[K, V]) RemoveBetween(a, b K, opt ...int) (total int)

RemoveBetween implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) RemoveBetweenKV

func (s *ThreadSafeOrderedMap[K, V]) RemoveBetweenKV(a, b K, opt ...int) (seq iter.Seq2[K, V])

RemoveBetweenKV implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) SetGrowth

func (s *ThreadSafeOrderedMap[K, V]) SetGrowth(grow int)

func (*ThreadSafeOrderedMap[K, V]) SetOverwrite

func (s *ThreadSafeOrderedMap[K, V]) SetOverwrite(cb func(key K, oldValue, newValue V))

SetOverwrite implements OrderedMap

func (*ThreadSafeOrderedMap[K, V]) Size

func (s *ThreadSafeOrderedMap[K, V]) Size() int

Size implements OrderedMap.

func (*ThreadSafeOrderedMap[K, V]) ThreadSafe

func (s *ThreadSafeOrderedMap[K, V]) ThreadSafe() bool

Always returns true.

func (*ThreadSafeOrderedMap[K, V]) ToTs

func (s *ThreadSafeOrderedMap[K, V]) ToTs() OrderedMap[K, V]

Always returns this instance.

func (*ThreadSafeOrderedMap[K, V]) Values

func (s *ThreadSafeOrderedMap[K, V]) Values() iter.Seq[V]

Values implements OrderedMap.

Directories

Path Synopsis
examples
Iterators command
hello command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL