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") }