-
Notifications
You must be signed in to change notification settings - Fork 4
/
snapmblock.go
65 lines (54 loc) · 1.66 KB
/
snapmblock.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
package bubt
import "fmt"
import "bytes"
import "encoding/binary"
type msnap []byte
func (m msnap) findkey(
adjust int, index blkindex, key []byte) (level byte, fpos int64) {
//fmt.Printf("mfindkey %v %v %q\n", adjust, len(index), key)
switch len(index) {
case 0:
panic(fmt.Errorf("impossible situation"))
case 1:
cmp, vpos := m.compareat(adjust, key)
if cmp >= 0 { // key >= adjust
level, fpos = byte(vpos>>56), int64(vpos&0x00FFFFFFFFFFFFFF)
//fmt.Printf("mfindkey %x %x\n", level, fpos)
return
}
//fmt.Println("mfindkey", 0)
return 0, 0
default:
half := len(index) / 2
cmp, vpos := m.compareat(adjust+half, key)
if cmp == 0 { // key == adjust+half
//fmt.Println("mfindkey", "default")
return byte(vpos >> 56), int64(vpos & 0x00FFFFFFFFFFFFFF)
} else if cmp > 0 { // key > adjust+half
return m.findkey(adjust+half, index[half:], key)
} else if len(index) == 2 || len(index) == 3 {
_, vpos := m.compareat(adjust, key)
return byte(vpos >> 56), int64(vpos & 0x00FFFFFFFFFFFFFF)
}
return m.findkey(adjust, index[:half], key)
}
panic("unreachable code")
}
func (m msnap) compareat(i int, key []byte) (int, uint64) {
offset := 4 + (i * 4)
x := binary.BigEndian.Uint32(m[offset : offset+4])
me := mentry(m[x : x+mentrysize])
ln, vpos := uint32(me.keylen()), me.vpos()
x += mentrysize
cmp := bytes.Compare(key, m[x:x+ln])
//fmt.Printf("m.compareat %v %s %s %v\n", i, key, m[x:x+ln], cmp)
return cmp, vpos
}
func (m msnap) getindex(index blkindex) blkindex {
nums, n := binary.BigEndian.Uint32(m[:4]), 4
for i := uint32(0); i < nums; i++ {
index = append(index, binary.BigEndian.Uint32(m[n:n+4]))
n += 4
}
return index
}