-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdb_interface.go
78 lines (65 loc) · 1.8 KB
/
db_interface.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
package hnswindex
import (
"bytes"
"math"
"github.com/cockroachdb/pebble"
)
type DB struct {
db *pebble.DB
}
func New(path string) (*DB, error) {
db, err := pebble.Open(path, &pebble.Options{})
if err != nil {
return nil, err
}
return &DB{db}, nil
}
func (db *DB) Close() {
db.db.Close()
}
func (db *DB) NewGraph(name string, dim int, M uint8, efCount int) (*Graph, error) {
h := Graph{name: name, m: M, db: db, dim: dim, efCount: efCount}
// default values used in c++ implementation
h.levelMult = 1 / math.Log(float64(M))
return &h, nil
}
func (db *DB) insertGraphVector(graphid uint32, name []byte, vec []float32) (uint64, error) {
//TODO: add mutex
nameKey := NameKeyEncode(graphid, name)
nameId, err := db.newVectorID(graphid)
if err != nil {
return 0, err
}
nameValue := NameValueEncode(nameId)
db.db.Set(nameKey, nameValue, nil)
vecKey := VectorKeyEncode(graphid, nameId)
vecValue := VectorValueEncode(vec)
db.db.Set(vecKey, vecValue, nil)
db.db.Set(NameRevKeyEncode(graphid, nameId), name, nil)
return nameId, nil
}
func (db *DB) newVectorID(graphId uint32) (uint64, error) {
prefix := NameRevGraphPrefix(graphId)
iter, err := db.db.NewIter(&pebble.IterOptions{LowerBound: prefix})
if err != nil {
return 0, err
}
defer iter.Close()
//TODO: there is probably a more efficient way to do this, like starting above and going backward
maxID := uint64(0)
for iter.SeekGE(prefix); iter.Valid() && bytes.HasPrefix(iter.Key(), prefix); iter.Next() {
_, maxID = NameRevKeyParse(iter.Key())
}
return maxID + 1, nil
}
func (db *DB) getVectorName(graphId uint32, id uint64) ([]byte, error) {
key := NameRevKeyEncode(graphId, id)
val, closer, err := db.db.Get(key)
if err != nil {
return nil, err
}
defer closer.Close()
out := make([]byte, len(val))
copy(out, val)
return out, nil
}