c65gm/internal/utils/multiindex.go

57 lines
1.1 KiB
Go

package utils
import (
"strings"
)
type MultiIndex[T any] struct {
items []T
indexes []map[string]*T
}
func NewMultiIndex[T any](numIndexes int) *MultiIndex[T] {
m := &MultiIndex[T]{
items: make([]T, 0),
indexes: make([]map[string]*T, numIndexes),
}
for i := range m.indexes {
m.indexes[i] = make(map[string]*T)
}
return m
}
func (m *MultiIndex[T]) AddItem(item T, searchKeys [][]string) {
if len(searchKeys) != len(m.indexes) {
panic("searchKeys length must match number of indexes")
}
m.items = append(m.items, item)
itemPtr := &m.items[len(m.items)-1]
for i, key := range searchKeys {
m.indexes[i][keyToString(key)] = itemPtr
}
}
func (m *MultiIndex[T]) FindItem(indexNum int, key []string) (T, bool) {
var zero T
if indexNum < 0 || indexNum >= len(m.indexes) {
return zero, false
}
itemPtr, found := m.indexes[indexNum][keyToString(key)]
if !found {
return zero, false
}
return *itemPtr, true
}
func (m *MultiIndex[T]) Items() []T {
result := make([]T, len(m.items))
copy(result, m.items)
return result
}
func keyToString(parts []string) string {
return strings.Join(parts, "\x00")
}