57 lines
1.1 KiB
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")
|
|
}
|