diff options
author | 2022-11-11 12:18:38 +0100 | |
---|---|---|
committer | 2022-11-11 12:18:38 +0100 | |
commit | edcee14d07bae129e2d1a06d99c30fc6f659ff5e (patch) | |
tree | 5b9d605654347fe104c55bf4b0e7fb1e1533e2a0 /vendor/codeberg.org/gruf/go-maps/ordered.go | |
parent | [feature] S3: add config flag to proxy S3 media (#1014) (diff) | |
download | gotosocial-edcee14d07bae129e2d1a06d99c30fc6f659ff5e.tar.xz |
[feature] Read + Write tombstones for deleted Actors (#1005)
* [feature] Read + Write tombstones for deleted Actors
* copyTombstone
* update to use resultcache instead of old ttl cache
Signed-off-by: kim <grufwub@gmail.com>
* update go-cache library to fix result cache capacity / ordering bugs
Signed-off-by: kim <grufwub@gmail.com>
* bump go-cache/v3 to v3.1.6 to fix bugs
Signed-off-by: kim <grufwub@gmail.com>
* switch on status code
* better explain ErrGone reasoning
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: kim <grufwub@gmail.com>
Diffstat (limited to 'vendor/codeberg.org/gruf/go-maps/ordered.go')
-rw-r--r-- | vendor/codeberg.org/gruf/go-maps/ordered.go | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-maps/ordered.go b/vendor/codeberg.org/gruf/go-maps/ordered.go new file mode 100644 index 000000000..ca8ebe8a0 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-maps/ordered.go @@ -0,0 +1,159 @@ +package maps + +import ( + "fmt" + "reflect" +) + +// OrderedMap provides a hashmap implementation that tracks the order in which keys are added. +type OrderedMap[K comparable, V any] struct { + ordered[K, V] +} + +// NewOrdered returns a new instance of LRUMap with given initializing length and maximum capacity. +func NewOrdered[K comparable, V any](len int) *OrderedMap[K, V] { + m := new(OrderedMap[K, V]) + m.Init(len) + return m +} + +// Init will initialize this map with initial length. +func (m *OrderedMap[K, V]) Init(len int) { + if m.pool != nil { + panic("ordered map already initialized") + } + m.ordered.hmap = make(map[K]*elem[K, V], len) + m.ordered.pool = allocElems[K, V](len) +} + +// Get will fetch value for given key from map. Returns false if not found. +func (m *OrderedMap[K, V]) Get(key K) (V, bool) { + if elem, ok := m.hmap[key]; ok { + return elem.V, true + } + var z V // zero value + return z, false +} + +// Add will add the given key-value pair to the map, returns false if already exists. +func (m *OrderedMap[K, V]) Add(key K, value V) bool { + // Ensure safe + m.write_check() + + // Look for existing elem + elem, ok := m.hmap[key] + if ok { + return false + } + + // Allocate elem + elem = m.alloc() + elem.K = key + elem.V = value + + // Add element map entry + m.hmap[key] = elem + + // Push to back of list + m.list.PushBack(elem) + return true +} + +// Set will ensure that given key-value pair exists in the map, by either adding new or updating existing. +func (m *OrderedMap[K, V]) Set(key K, value V) { + // Ensure safe + m.write_check() + + // Look for existing elem + elem, ok := m.hmap[key] + + if ok { + // Update existing + elem.V = value + } else { + // Allocate elem + elem = m.alloc() + elem.K = key + elem.V = value + + // Add element map entry + m.hmap[key] = elem + + // Push to back of list + m.list.PushBack(elem) + } +} + +// Index returns the key-value pair at index from map. Returns false if index out of range. +func (m *OrderedMap[K, V]) Index(idx int) (K, V, bool) { + if idx < 0 || idx >= m.list.len { + var ( + zk K + zv V + ) // zero values + return zk, zv, false + } + elem := m.list.Index(idx) + return elem.K, elem.V, true +} + +// Push will insert the given key-value pair at index in the map. Panics if index out of range. +func (m *OrderedMap[K, V]) Push(idx int, key K, value V) { + // Check index within bounds of map + if idx < 0 || idx >= m.list.len { + panic("index out of bounds") + } + + // Ensure safe + m.write_check() + + // Get element at index + next := m.list.Index(idx) + + // Allocate new elem + elem := m.alloc() + elem.K = key + elem.V = value + + // Add element map entry + m.hmap[key] = elem + + // Move next forward + elem.next = next + elem.prev = next.prev + + // Link up elem in chain + next.prev.next = elem + next.prev = elem +} + +// Pop will remove and return the key-value pair at index in the map. Panics if index out of range. +func (m *OrderedMap[K, V]) Pop(idx int) (K, V) { + // Check index within bounds of map + if idx < 0 || idx >= m.list.len { + panic("index out of bounds") + } + + // Ensure safe + m.write_check() + + // Get element at index + elem := m.list.Index(idx) + + // Unlink elem from list + m.list.Unlink(elem) + + // Get elem values + k := elem.K + v := elem.V + + // Release to pool + m.free(elem) + + return k, v +} + +// Format implements fmt.Formatter, allowing performant string formatting of map. +func (m *OrderedMap[K, V]) Format(state fmt.State, verb rune) { + m.format(reflect.TypeOf(m), state, verb) +} |