Documentation
¶
Overview ¶
Package hybrid provides hybrid index structures that combine HNSW with complementary indexing approaches to overcome limitations in specific scenarios.
Index ¶
- type AdaptiveConfig
- type AdaptiveHybridIndex
- func (idx *AdaptiveHybridIndex[K]) Add(key K, vector []float32) error
- func (idx *AdaptiveHybridIndex[K]) BatchAdd(keys []K, vectors [][]float32) error
- func (idx *AdaptiveHybridIndex[K]) Count() int
- func (idx *AdaptiveHybridIndex[K]) Delete(key K) error
- func (idx *AdaptiveHybridIndex[K]) GetStats() map[string]interface{}
- func (idx *AdaptiveHybridIndex[K]) ResetStats()
- func (idx *AdaptiveHybridIndex[K]) Search(query []float32, k int) ([]K, []float32, error)
- type AdaptiveSelector
- func (s *AdaptiveSelector[K]) GetStats() map[string]interface{}
- func (s *AdaptiveSelector[K]) RecordQueryMetrics(metrics QueryMetrics)
- func (s *AdaptiveSelector[K]) ResetStats()
- func (s *AdaptiveSelector[K]) SelectStrategy(query []float32, k int) IndexType
- func (s *AdaptiveSelector[K]) UpdateDatasetSize(size int)
- type DistanceStats
- type ExactAdapter
- func (a *ExactAdapter[K]) Add(key K, vector []float32) error
- func (a *ExactAdapter[K]) BatchAdd(keys []K, vectors [][]float32) []error
- func (a *ExactAdapter[K]) BatchDelete(keys []K) []bool
- func (a *ExactAdapter[K]) Close()
- func (a *ExactAdapter[K]) Delete(key K) bool
- func (a *ExactAdapter[K]) Len() int
- func (a *ExactAdapter[K]) Search(query []float32, k int) ([]K, []float32)
- type ExactIndex
- func (idx *ExactIndex[K]) Add(key K, vector []float32) error
- func (idx *ExactIndex[K]) BatchAdd(keys []K, vectors [][]float32) error
- func (idx *ExactIndex[K]) BatchDelete(keys []K) []bool
- func (idx *ExactIndex[K]) Close() error
- func (idx *ExactIndex[K]) Delete(key K) bool
- func (idx *ExactIndex[K]) Len() int
- func (idx *ExactIndex[K]) Search(query []float32, k int) ([]hnsw.Node[K], error)
- type HNSWAdapter
- func (a *HNSWAdapter[K]) Add(key K, vector []float32) error
- func (a *HNSWAdapter[K]) BatchAdd(keys []K, vectors [][]float32) []error
- func (a *HNSWAdapter[K]) BatchDelete(keys []K) []bool
- func (a *HNSWAdapter[K]) Close()
- func (a *HNSWAdapter[K]) Delete(key K) bool
- func (a *HNSWAdapter[K]) Len() int
- func (a *HNSWAdapter[K]) Search(query []float32, k int) ([]K, []float32)
- type HybridIndex
- func (idx *HybridIndex[K]) Add(key K, vector []float32) error
- func (idx *HybridIndex[K]) BatchAdd(keys []K, vectors [][]float32) error
- func (idx *HybridIndex[K]) BatchDelete(keys []K) []bool
- func (idx *HybridIndex[K]) Close() error
- func (idx *HybridIndex[K]) Delete(key K) bool
- func (idx *HybridIndex[K]) ForceRebalance()
- func (idx *HybridIndex[K]) GetPartitionStats() []int
- func (idx *HybridIndex[K]) GetStats() IndexStats
- func (idx *HybridIndex[K]) Len() int
- func (idx *HybridIndex[K]) Search(query []float32, k int) ([]hnsw.Node[K], error)
- type IndexConfig
- type IndexStats
- type IndexType
- type LSHAdapter
- func (a *LSHAdapter[K]) Add(key K, vector []float32) error
- func (a *LSHAdapter[K]) BatchAdd(keys []K, vectors [][]float32) []error
- func (a *LSHAdapter[K]) BatchDelete(keys []K) []bool
- func (a *LSHAdapter[K]) Close()
- func (a *LSHAdapter[K]) Delete(key K) bool
- func (a *LSHAdapter[K]) Len() int
- func (a *LSHAdapter[K]) Search(query []float32, k int) ([]K, []float32)
- type LSHIndex
- func (idx *LSHIndex[K]) Add(key K, vector []float32) error
- func (idx *LSHIndex[K]) BatchAdd(keys []K, vectors [][]float32) []error
- func (idx *LSHIndex[K]) BatchDelete(keys []K) []bool
- func (idx *LSHIndex[K]) Close()
- func (idx *LSHIndex[K]) Delete(key K) bool
- func (idx *LSHIndex[K]) GetCandidates(query []float32) []K
- func (idx *LSHIndex[K]) Len() int
- func (idx *LSHIndex[K]) Search(query []float32, k int) ([]K, []float32)
- type MultiIndexAdapter
- func (a *MultiIndexAdapter[K]) Add(key K, vector []float32) error
- func (a *MultiIndexAdapter[K]) BatchAdd(keys []K, vectors [][]float32) []error
- func (a *MultiIndexAdapter[K]) BatchDelete(keys []K) []bool
- func (a *MultiIndexAdapter[K]) Close()
- func (a *MultiIndexAdapter[K]) Delete(key K) bool
- func (a *MultiIndexAdapter[K]) Len() int
- func (a *MultiIndexAdapter[K]) Search(query []float32, k int) ([]K, []float32)
- type Partitioner
- func (p *Partitioner[K]) AssignPartition(vector []float32) int
- func (p *Partitioner[K]) AssignVectorToPartition(key K, vector []float32) int
- func (p *Partitioner[K]) GetPartition(partitionIdx int) []K
- func (p *Partitioner[K]) GetPartitionStats() []int
- func (p *Partitioner[K]) Rebalance(vectors map[K][]float32)
- func (p *Partitioner[K]) RemoveFromPartitions(key K)
- func (p *Partitioner[K]) UpdateCentroids(vectors map[K][]float32)
- type QueryMetrics
- type SearchableIndex
- type StrategyStats
- type VectorIndex
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AdaptiveConfig ¶
type AdaptiveConfig struct { // Window size for moving averages WindowSize int // Weight factors for the decision function LatencyWeight float64 RecallWeight float64 SuccessRateWeight float64 // Learning rate for adaptive thresholds LearningRate float64 // Initial thresholds InitialExactThreshold int InitialDimThreshold int // Exploration vs exploitation trade-off ExplorationFactor float64 // Minimum number of samples before adapting MinSamplesForAdaptation int }
AdaptiveConfig contains configuration for the adaptive strategy selector
func DefaultAdaptiveConfig ¶
func DefaultAdaptiveConfig() AdaptiveConfig
DefaultAdaptiveConfig returns default configuration for adaptive selection
type AdaptiveHybridIndex ¶
AdaptiveHybridIndex implements a hybrid index that dynamically selects the best strategy for each query based on runtime performance metrics
func NewAdaptiveHybridIndex ¶
func NewAdaptiveHybridIndex[K cmp.Ordered]( exactIndex *ExactIndex[K], hnswGraph *hnsw.Graph[K], lshIndex *LSHIndex[K], distFunc hnsw.DistanceFunc, config AdaptiveConfig, ) *AdaptiveHybridIndex[K]
NewAdaptiveHybridIndex creates a new adaptive hybrid index
func (*AdaptiveHybridIndex[K]) Add ¶
func (idx *AdaptiveHybridIndex[K]) Add(key K, vector []float32) error
Add adds a vector to the index
func (*AdaptiveHybridIndex[K]) BatchAdd ¶
func (idx *AdaptiveHybridIndex[K]) BatchAdd(keys []K, vectors [][]float32) error
BatchAdd adds multiple vectors to the index
func (*AdaptiveHybridIndex[K]) Count ¶
func (idx *AdaptiveHybridIndex[K]) Count() int
Count returns the number of vectors in the index
func (*AdaptiveHybridIndex[K]) Delete ¶
func (idx *AdaptiveHybridIndex[K]) Delete(key K) error
Delete removes a vector from the index
func (*AdaptiveHybridIndex[K]) GetStats ¶
func (idx *AdaptiveHybridIndex[K]) GetStats() map[string]interface{}
GetStats returns statistics about the adaptive index
func (*AdaptiveHybridIndex[K]) ResetStats ¶
func (idx *AdaptiveHybridIndex[K]) ResetStats()
ResetStats resets all performance statistics
type AdaptiveSelector ¶
AdaptiveSelector implements dynamic strategy selection based on runtime metrics
func NewAdaptiveSelector ¶
func NewAdaptiveSelector[K cmp.Ordered]( exactIndex *ExactIndex[K], hnswIndex *hnsw.Graph[K], lshIndex *LSHIndex[K], partitioner *Partitioner[K], config AdaptiveConfig, ) *AdaptiveSelector[K]
NewAdaptiveSelector creates a new adaptive strategy selector
func (*AdaptiveSelector[K]) GetStats ¶
func (s *AdaptiveSelector[K]) GetStats() map[string]interface{}
GetStats returns the current statistics and thresholds
func (*AdaptiveSelector[K]) RecordQueryMetrics ¶
func (s *AdaptiveSelector[K]) RecordQueryMetrics(metrics QueryMetrics)
RecordQueryMetrics records metrics for a completed query
func (*AdaptiveSelector[K]) ResetStats ¶
func (s *AdaptiveSelector[K]) ResetStats()
ResetStats resets all statistics
func (*AdaptiveSelector[K]) SelectStrategy ¶
func (s *AdaptiveSelector[K]) SelectStrategy(query []float32, k int) IndexType
SelectStrategy chooses the best strategy for a given query
func (*AdaptiveSelector[K]) UpdateDatasetSize ¶
func (s *AdaptiveSelector[K]) UpdateDatasetSize(size int)
UpdateDatasetSize updates the dataset size in the selector
type DistanceStats ¶
type DistanceStats struct { Min float32 // Minimum distance Max float32 // Maximum distance Mean float32 // Mean distance Variance float32 // Variance of distances }
DistanceStats captures statistics about distances in query results
type ExactAdapter ¶
ExactAdapter adapts the ExactIndex to the SearchableIndex interface. This allows the ExactIndex to be used in the hybrid index.
func NewExactAdapter ¶
func NewExactAdapter[K cmp.Ordered](index *ExactIndex[K]) *ExactAdapter[K]
NewExactAdapter creates a new adapter for an ExactIndex.
func (*ExactAdapter[K]) Add ¶
func (a *ExactAdapter[K]) Add(key K, vector []float32) error
Add adds a vector to the index.
func (*ExactAdapter[K]) BatchAdd ¶
func (a *ExactAdapter[K]) BatchAdd(keys []K, vectors [][]float32) []error
BatchAdd adds multiple vectors to the index.
func (*ExactAdapter[K]) BatchDelete ¶
func (a *ExactAdapter[K]) BatchDelete(keys []K) []bool
BatchDelete removes multiple vectors from the index.
func (*ExactAdapter[K]) Close ¶
func (a *ExactAdapter[K]) Close()
Close releases resources used by the index.
func (*ExactAdapter[K]) Delete ¶
func (a *ExactAdapter[K]) Delete(key K) bool
Delete removes a vector from the index.
func (*ExactAdapter[K]) Len ¶
func (a *ExactAdapter[K]) Len() int
Len returns the number of vectors in the index.
type ExactIndex ¶
ExactIndex implements a brute-force exact search index. This is used for small datasets where exact search is fast enough.
func NewExactIndex ¶
func NewExactIndex[K cmp.Ordered](distance hnsw.DistanceFunc) *ExactIndex[K]
NewExactIndex creates a new exact search index.
func (*ExactIndex[K]) Add ¶
func (idx *ExactIndex[K]) Add(key K, vector []float32) error
Add adds a vector to the index.
func (*ExactIndex[K]) BatchAdd ¶
func (idx *ExactIndex[K]) BatchAdd(keys []K, vectors [][]float32) error
BatchAdd adds multiple vectors to the index.
func (*ExactIndex[K]) BatchDelete ¶
func (idx *ExactIndex[K]) BatchDelete(keys []K) []bool
BatchDelete removes multiple vectors from the index.
func (*ExactIndex[K]) Close ¶
func (idx *ExactIndex[K]) Close() error
Close releases resources used by the index.
func (*ExactIndex[K]) Delete ¶
func (idx *ExactIndex[K]) Delete(key K) bool
Delete removes a vector from the index.
func (*ExactIndex[K]) Len ¶
func (idx *ExactIndex[K]) Len() int
Len returns the number of vectors in the index.
type HNSWAdapter ¶
HNSWAdapter adapts the HNSW Graph to the SearchableIndex interface. This allows the HNSW graph to be used in the hybrid index.
func NewHNSWAdapter ¶
func NewHNSWAdapter[K cmp.Ordered](graph *hnsw.Graph[K], distance hnsw.DistanceFunc) *HNSWAdapter[K]
NewHNSWAdapter creates a new adapter for an HNSW graph.
func (*HNSWAdapter[K]) Add ¶
func (a *HNSWAdapter[K]) Add(key K, vector []float32) error
Add adds a vector to the index.
func (*HNSWAdapter[K]) BatchAdd ¶
func (a *HNSWAdapter[K]) BatchAdd(keys []K, vectors [][]float32) []error
BatchAdd adds multiple vectors to the index.
func (*HNSWAdapter[K]) BatchDelete ¶
func (a *HNSWAdapter[K]) BatchDelete(keys []K) []bool
BatchDelete removes multiple vectors from the index.
func (*HNSWAdapter[K]) Close ¶
func (a *HNSWAdapter[K]) Close()
Close releases resources used by the index.
func (*HNSWAdapter[K]) Delete ¶
func (a *HNSWAdapter[K]) Delete(key K) bool
Delete removes a vector from the index.
func (*HNSWAdapter[K]) Len ¶
func (a *HNSWAdapter[K]) Len() int
Len returns the number of vectors in the index.
type HybridIndex ¶
HybridIndex is the main implementation of the VectorIndex interface that combines multiple indexing approaches.
func NewHybridIndex ¶
func NewHybridIndex[K cmp.Ordered](config IndexConfig) (*HybridIndex[K], error)
NewHybridIndex creates a new hybrid index with the given configuration
func (*HybridIndex[K]) Add ¶
func (idx *HybridIndex[K]) Add(key K, vector []float32) error
Add adds a vector to the index
func (*HybridIndex[K]) BatchAdd ¶
func (idx *HybridIndex[K]) BatchAdd(keys []K, vectors [][]float32) error
BatchAdd adds multiple vectors to the index
func (*HybridIndex[K]) BatchDelete ¶
func (idx *HybridIndex[K]) BatchDelete(keys []K) []bool
BatchDelete removes multiple vectors from the index
func (*HybridIndex[K]) Close ¶
func (idx *HybridIndex[K]) Close() error
Close releases resources used by the index
func (*HybridIndex[K]) Delete ¶
func (idx *HybridIndex[K]) Delete(key K) bool
Delete removes a vector from the index
func (*HybridIndex[K]) ForceRebalance ¶
func (idx *HybridIndex[K]) ForceRebalance()
ForceRebalance forces a rebalance of the partitions.
func (*HybridIndex[K]) GetPartitionStats ¶
func (idx *HybridIndex[K]) GetPartitionStats() []int
GetPartitionStats returns statistics about the partitions.
func (*HybridIndex[K]) GetStats ¶
func (idx *HybridIndex[K]) GetStats() IndexStats
GetStats returns statistics about the index
func (*HybridIndex[K]) Len ¶
func (idx *HybridIndex[K]) Len() int
Len returns the number of vectors in the index
type IndexConfig ¶
type IndexConfig struct { // The type of index to use Type IndexType // The threshold for switching between exact and HNSW search // (number of vectors) ExactThreshold int // HNSW configuration M int Ml float64 EfSearch int Distance hnsw.DistanceFunc // LSH configuration NumHashTables int NumHashBits int // Partitioning configuration NumPartitions int PartitionSize int }
IndexConfig contains configuration options for the hybrid index
func DefaultIndexConfig ¶
func DefaultIndexConfig() IndexConfig
DefaultIndexConfig returns a default configuration for the hybrid index
type IndexStats ¶
type IndexStats struct { TotalVectors int ExactVectors int HNSWVectors int NumPartitions int AvgPartitionSize float64 }
IndexStats contains statistics about the index
type IndexType ¶
type IndexType int
IndexType represents the type of index to use
func (IndexType) UsePartitioning ¶
UsePartitioning returns whether the index type uses partitioning
type LSHAdapter ¶
LSHAdapter adapts the LSHIndex to the SearchableIndex interface. This allows the LSHIndex to be used in the hybrid index.
func NewLSHAdapter ¶
func NewLSHAdapter[K cmp.Ordered](index *LSHIndex[K]) *LSHAdapter[K]
NewLSHAdapter creates a new adapter for an LSHIndex.
func (*LSHAdapter[K]) Add ¶
func (a *LSHAdapter[K]) Add(key K, vector []float32) error
Add adds a vector to the index.
func (*LSHAdapter[K]) BatchAdd ¶
func (a *LSHAdapter[K]) BatchAdd(keys []K, vectors [][]float32) []error
BatchAdd adds multiple vectors to the index.
func (*LSHAdapter[K]) BatchDelete ¶
func (a *LSHAdapter[K]) BatchDelete(keys []K) []bool
BatchDelete removes multiple vectors from the index.
func (*LSHAdapter[K]) Close ¶
func (a *LSHAdapter[K]) Close()
Close releases resources used by the index.
func (*LSHAdapter[K]) Delete ¶
func (a *LSHAdapter[K]) Delete(key K) bool
Delete removes a vector from the index.
func (*LSHAdapter[K]) Len ¶
func (a *LSHAdapter[K]) Len() int
Len returns the number of vectors in the index.
type LSHIndex ¶
LSHIndex implements a Locality-Sensitive Hashing index for approximate nearest neighbor search. This is particularly useful for high-dimensional data where HNSW might struggle.
func NewLSHIndex ¶
NewLSHIndex creates a new LSH index.
func (*LSHIndex[K]) BatchDelete ¶
BatchDelete removes multiple vectors from the index.
func (*LSHIndex[K]) Close ¶
func (idx *LSHIndex[K]) Close()
Close releases resources used by the index.
func (*LSHIndex[K]) GetCandidates ¶
GetCandidates returns candidate keys that might be close to the query vector.
type MultiIndexAdapter ¶
MultiIndexAdapter combines multiple indexes into a single SearchableIndex. This allows searching across multiple indexes and combining the results.
func NewMultiIndexAdapter ¶
func NewMultiIndexAdapter[K cmp.Ordered](indexes ...SearchableIndex[K]) *MultiIndexAdapter[K]
NewMultiIndexAdapter creates a new adapter for multiple indexes.
func (*MultiIndexAdapter[K]) Add ¶
func (a *MultiIndexAdapter[K]) Add(key K, vector []float32) error
Add adds a vector to all indexes.
func (*MultiIndexAdapter[K]) BatchAdd ¶
func (a *MultiIndexAdapter[K]) BatchAdd(keys []K, vectors [][]float32) []error
BatchAdd adds multiple vectors to all indexes.
func (*MultiIndexAdapter[K]) BatchDelete ¶
func (a *MultiIndexAdapter[K]) BatchDelete(keys []K) []bool
BatchDelete removes multiple vectors from all indexes.
func (*MultiIndexAdapter[K]) Close ¶
func (a *MultiIndexAdapter[K]) Close()
Close releases resources used by all indexes.
func (*MultiIndexAdapter[K]) Delete ¶
func (a *MultiIndexAdapter[K]) Delete(key K) bool
Delete removes a vector from all indexes.
func (*MultiIndexAdapter[K]) Len ¶
func (a *MultiIndexAdapter[K]) Len() int
Len returns the number of vectors in the first index. Note: This assumes all indexes have the same content.
type Partitioner ¶
Partitioner implements data-aware partitioning for the hybrid index. It assigns vectors to partitions based on their similarity.
func NewPartitioner ¶
func NewPartitioner[K cmp.Ordered](numPartitions int, distance hnsw.DistanceFunc) *Partitioner[K]
NewPartitioner creates a new partitioner.
func (*Partitioner[K]) AssignPartition ¶
func (p *Partitioner[K]) AssignPartition(vector []float32) int
AssignPartition assigns a vector to a partition and returns the partition index.
func (*Partitioner[K]) AssignVectorToPartition ¶
func (p *Partitioner[K]) AssignVectorToPartition(key K, vector []float32) int
AssignVectorToPartition assigns a vector with a key to a partition.
func (*Partitioner[K]) GetPartition ¶
func (p *Partitioner[K]) GetPartition(partitionIdx int) []K
GetPartition returns all keys in a partition.
func (*Partitioner[K]) GetPartitionStats ¶
func (p *Partitioner[K]) GetPartitionStats() []int
GetPartitionStats returns statistics about the partitions.
func (*Partitioner[K]) Rebalance ¶
func (p *Partitioner[K]) Rebalance(vectors map[K][]float32)
Rebalance reassigns vectors to partitions based on updated centroids. This is used to improve partitioning quality after updating centroids.
func (*Partitioner[K]) RemoveFromPartitions ¶
func (p *Partitioner[K]) RemoveFromPartitions(key K)
RemoveFromPartitions removes a key from all partitions.
func (*Partitioner[K]) UpdateCentroids ¶
func (p *Partitioner[K]) UpdateCentroids(vectors map[K][]float32)
UpdateCentroids recalculates centroids based on the current partition assignments. This is used to improve partitioning quality after adding many vectors.
type QueryMetrics ¶
type QueryMetrics struct { Strategy IndexType // Strategy used for the query QueryVector []float32 // The query vector Dimension int // Dimensionality of the vector K int // Number of neighbors requested Duration time.Duration // Time taken to execute the query ResultCount int // Number of results returned Recall float64 // Recall rate (if ground truth available) DistanceStats DistanceStats // Statistics about distances in the results }
QueryMetrics stores performance metrics for a single query
type SearchableIndex ¶
type SearchableIndex[K cmp.Ordered] interface { // Add adds a vector to the index. Add(key K, vector []float32) error // BatchAdd adds multiple vectors to the index. BatchAdd(keys []K, vectors [][]float32) []error // Search finds the k nearest neighbors to the query vector. Search(query []float32, k int) ([]K, []float32) // Delete removes a vector from the index. Delete(key K) bool // BatchDelete removes multiple vectors from the index. BatchDelete(keys []K) []bool // Len returns the number of vectors in the index. Len() int // Close releases resources used by the index. Close() }
SearchableIndex defines the interface for any index that can be used in the hybrid index.
type StrategyStats ¶
type StrategyStats struct { TotalQueries int // Total number of queries executed with this strategy TotalDuration time.Duration // Total time spent on queries AvgDuration time.Duration // Average duration per query P95Duration time.Duration // 95th percentile duration AvgRecall float64 // Average recall (if available) SuccessRate float64 // Rate of successful queries LastUsed time.Time // When this strategy was last used RecentPerformance []time.Duration // Recent query durations (sliding window) }
StrategyStats tracks performance metrics for each strategy
type VectorIndex ¶
type VectorIndex[K cmp.Ordered] interface { // Add adds a vector to the index Add(key K, vector []float32) error // BatchAdd adds multiple vectors to the index BatchAdd(keys []K, vectors [][]float32) error // Search finds the k nearest neighbors to the query vector Search(query []float32, k int) ([]hnsw.Node[K], error) // Delete removes a vector from the index Delete(key K) bool // BatchDelete removes multiple vectors from the index BatchDelete(keys []K) []bool // Len returns the number of vectors in the index Len() int // Close releases resources used by the index Close() error }
VectorIndex defines a common interface for all vector indexing structures. This allows different implementations to be used interchangeably.