2023-12-13 15:06:39 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
|
|
|
|
package index
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
|
|
|
iradix "github.com/hashicorp/go-immutable-radix/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Index struct {
|
|
|
|
name string
|
|
|
|
required bool
|
|
|
|
indexer MultiIndexer
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(name string, i Indexer, opts ...IndexOption) *Index {
|
|
|
|
if name == "" {
|
|
|
|
panic("all indexers must have a non-empty name")
|
|
|
|
}
|
|
|
|
if i == nil {
|
|
|
|
panic("no indexer was supplied when creating a new cache Index")
|
|
|
|
}
|
|
|
|
|
|
|
|
var multiIndexer MultiIndexer
|
|
|
|
switch v := i.(type) {
|
|
|
|
case SingleIndexer:
|
|
|
|
multiIndexer = singleIndexWrapper{indexer: v}
|
|
|
|
case MultiIndexer:
|
|
|
|
multiIndexer = v
|
|
|
|
default:
|
|
|
|
panic("The Indexer must also implement one of the SingleIndexer or MultiIndexer interfaces")
|
|
|
|
}
|
|
|
|
|
|
|
|
idx := &Index{
|
|
|
|
name: name,
|
|
|
|
indexer: multiIndexer,
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, opt := range opts {
|
|
|
|
opt(idx)
|
|
|
|
}
|
|
|
|
|
|
|
|
return idx
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *Index) Name() string {
|
|
|
|
return i.name
|
|
|
|
}
|
|
|
|
|
2024-02-09 18:00:21 +00:00
|
|
|
// IndexedData combines the Index with an radix tree for index and resource storage.
|
|
|
|
func (i *Index) IndexedData() *IndexedData {
|
|
|
|
return &IndexedData{
|
|
|
|
Index: i,
|
|
|
|
tree: iradix.New[[]*pbresource.Resource](),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// IndexedData is a wrapper around an Index and an radix tree for index and resource storage.
|
|
|
|
type IndexedData struct {
|
|
|
|
*Index
|
|
|
|
tree *iradix.Tree[[]*pbresource.Resource]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *IndexedData) Txn() Txn {
|
2023-12-13 15:06:39 +00:00
|
|
|
return &txn{
|
|
|
|
inner: i.tree.Txn(),
|
|
|
|
index: i,
|
|
|
|
dirty: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *Index) fromArgs(args ...any) ([]byte, error) {
|
|
|
|
return i.indexer.FromArgs(args...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *Index) fromResource(r *pbresource.Resource) (bool, [][]byte, error) {
|
|
|
|
return i.indexer.FromResource(r)
|
|
|
|
}
|
|
|
|
|
|
|
|
type singleIndexWrapper struct {
|
|
|
|
indexer SingleIndexer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s singleIndexWrapper) FromArgs(args ...any) ([]byte, error) {
|
|
|
|
return s.indexer.FromArgs(args...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s singleIndexWrapper) FromResource(r *pbresource.Resource) (bool, [][]byte, error) {
|
|
|
|
indexed, val, err := s.indexer.FromResource(r)
|
|
|
|
if err != nil || !indexed {
|
|
|
|
return false, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return true, [][]byte{val}, nil
|
|
|
|
}
|