-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.go
97 lines (80 loc) · 1.82 KB
/
index.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package xisdb
import (
"strings"
"github.com/alexsward/xisdb/indexes"
"github.com/alexsward/xisdb/tree"
)
// IndexType -- an index can be added to either the Key or Value of an Item
type IndexType int
const (
// KeyIndex will index on an item's Key
KeyIndex IndexType = iota
// ValueIndex will index on an item's Value
ValueIndex
)
// indexMatcher is a fucntion that determines if an Item matches an index
type indexMatcher func(*Item) bool
func newIndexMatcher(it IndexType, matcher indexes.Matcher) indexMatcher {
return func(item *Item) bool {
str := item.Key
if it == ValueIndex {
str = item.Value
}
return matcher(str)
}
}
type index struct {
name string
match indexMatcher
tree tree.BTree
}
func (i *index) String() string {
return i.name
}
var (
// NaturalOrderKeyComparison -- string.Compare two Items by Key
NaturalOrderKeyComparison = func(k1, k2 tree.Key) int {
// TODO: these comparators need to be way better
return strings.Compare(k1.(string), k1.(string))
}
)
type indexNode struct {
item *Item
}
func (in indexNode) Key() tree.Key {
return in.item.Key
}
func (in indexNode) Value() interface{} {
return in.item
}
func newIndex(name string, it IndexType, m indexes.Matcher, comp tree.Comparator) (*index, error) {
tree, err := tree.NewTree(3, NaturalOrderKeyComparison)
if err != nil {
return nil, err
}
idx := &index{
name: name,
match: newIndexMatcher(it, m),
tree: tree,
}
return idx, err
}
func (i *index) add(item *Item) {
i.tree.Insert(&indexNode{item})
}
func (i *index) remove(item *Item) {
i.tree.Remove(&indexNode{item})
}
func (i *index) iterate() <-chan Item {
ch := make(chan Item)
go func(c chan Item) {
defer close(c)
if i.tree.Size() == 0 {
return
}
for item := range i.tree.IterateAll() {
ch <- *(item.(*indexNode).item)
}
}(ch)
return ch
}