// Copyright 2026 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package sgutil import "iter" type InsertMap[K comparable, V any] struct { m map[K]uint32 // Maps keys to their insertion index in the values slice. v []V // Stores values in their insertion order. k []K // Lazy slice of keys in insertion order, for iterators. } // Put inserts or updates a key-value pair in the map. // If the key already exists, its value is updated while its insertion order // remains unchanged. Returns the old value if there is one, // and a boolean indicating whether an update occurred. func (im *InsertMap[K, V]) Put(key K, val V) (old V, updated bool) { if im.m == nil { im.m = make(map[K]uint32) } var index uint32 index, updated = im.m[key] if updated { // Key already exists; update its value in-place in the values slice. old = im.v[index] im.v[index] = val return } // Keep the keys slice synchronized if it has already been initialized. if len(im.v) > 0 && len(im.k) == len(im.v) { im.k = append(im.k, key) } // Record the new key's insertion index and append the value. im.m[key] = uint32(len(im.v)) im.v = append(im.v, val) return } // updateKeys synchronizes the lazy keys slice (im.k) with the values slice (im.v). // It populates im.k with keys at their respective insertion indices using // the mapping stored in im.m. func (im *InsertMap[K, V]) updateKeys() { if len(im.k) == len(im.v) { return } im.k = make([]K, len(im.v)) for k, i := range im.m { im.k[i] = k } } // Contains reports whether the map contains the specified key. func (im *InsertMap[K, V]) Contains(key K) bool { if im.m == nil { return false } _, ok := im.m[key] return ok } // Get returns the value associated with the specified key. // If the key does not exist, the zero value of type V is returned. func (im *InsertMap[K, V]) Get(key K) V { if im.m != nil { index, ok := im.m[key] if ok { return im.v[index] } } var v V return v } // GetOk returns the value associated with the specified key and // a boolean indicating whether the key exists in the map. // If the key is not in the map, the zero value is returned along with false. func (im *InsertMap[K, V]) GetOk(key K) (V, bool) { if im.m != nil { index, ok := im.m[key] if ok { return im.v[index], true } } var v V return v, false } // Compare compares two keys based on their insertion order. // It returns: // - -1 if 'a' was inserted before 'b' // - 1 if 'a' was inserted after 'b' // - 0 if 'a' and 'b' are equal, or if neither key exists in the map. // // If only one of the keys exists in the map, the existing key is considered // to be "before" (less than) the non-existing key, returning -1 if 'a' exists, // and 1 if 'b' exists. func (im *InsertMap[K, V]) Compare(a, b K) int { if im.m == nil { return 0 } ai, aok := im.m[a] bi, bok := im.m[b] if aok != bok { if aok { return -1 } return 1 } if !aok { return 0 } if ai < bi { return -1 } if ai > bi { return 1 } return 0 } // All returns an iterator over the key-value pairs of the map in insertion order. func (im *InsertMap[K, V]) All() iter.Seq2[K, V] { return func(yield func(K, V) bool) { im.updateKeys() for i, k := range im.k { if !yield(k, im.v[i]) { return } } } } // Keys returns an iterator over the keys of the map in insertion order. func (im *InsertMap[K, V]) Keys() iter.Seq[K] { return func(yield func(K) bool) { im.updateKeys() for _, k := range im.k { if !yield(k) { return } } } } // Values returns an iterator over the values of the map in insertion order. func (im *InsertMap[K, V]) Values() iter.Seq[V] { return func(yield func(V) bool) { for _, v := range im.v { if !yield(v) { return } } } }