forked from akrennmair/epos
/
index.go
95 lines (78 loc) · 1.93 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
package epos
import (
"encoding/binary"
"io"
"os"
)
type index struct {
file *os.File
field string
data map[string][]indexEntry
}
type indexEntry struct {
deleted bool
value string
id int64
fpos int64
}
func newIndex(file *os.File, field string) *index {
idx := &index{file: file, field: field, data: make(map[string][]indexEntry)}
return idx
}
func (idx *index) Add(e indexEntry) {
if entry_list, contains := idx.data[e.value]; contains {
entry_list = append(entry_list, e)
idx.data[e.value] = entry_list
} else {
idx.data[e.value] = []indexEntry{e}
}
}
func (e *indexEntry) Deleted() bool {
return e.deleted
}
func (e *indexEntry) ReadFrom(r io.Reader) (n int64, err error) {
var deleted byte
if err = binary.Read(r, binary.BigEndian, &deleted); err != nil {
return 0, err
}
e.deleted = (deleted != 0)
var value_len uint32
if err = binary.Read(r, binary.BigEndian, &value_len); err != nil {
return 0, err
}
value := make([]byte, int(value_len))
for i := 0; i < int(value_len); i++ {
var b byte
if err = binary.Read(r, binary.BigEndian, &b); err != nil {
return 0, err
}
value[i] = b
}
e.value = string(value)
var id int64
if err = binary.Read(r, binary.BigEndian, &id); err != nil {
return 0, err
}
e.id = id
return int64(binary.Size(deleted) + binary.Size(value) + binary.Size(id)), nil
}
func (e *indexEntry) WriteTo(w io.Writer) (n int64, err error) {
deleted := byte(0)
if e.deleted {
deleted = 1
}
if err = binary.Write(w, binary.BigEndian, deleted); err != nil {
return 0, err
}
value_len := uint32(len(e.value))
if err = binary.Write(w, binary.BigEndian, value_len); err != nil {
return 0, err
}
if err = binary.Write(w, binary.BigEndian, []byte(e.value)); err != nil {
return 0, err
}
if err = binary.Write(w, binary.BigEndian, e.id); err != nil {
return 0, err
}
return int64(binary.Size(deleted) + binary.Size([]byte(e.value)) + binary.Size(e.id)), nil
}