-
Notifications
You must be signed in to change notification settings - Fork 5
/
storage.go
108 lines (84 loc) · 2.34 KB
/
storage.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
98
99
100
101
102
103
104
105
106
107
108
package fbptree
import "fmt"
// storage an abstraction over the storing mechanism.
type storage struct {
pager *pager
records *records
}
func newStorage(path string, pageSize uint16) (*storage, error) {
pager, err := openPager(path, pageSize)
if err != nil {
return nil, fmt.Errorf("failed to instantiate the pager: %w", err)
}
return &storage{pager: pager, records: newRecords(pager)}, nil
}
func (s *storage) loadMetadata() (*treeMetadata, error) {
data, err := s.pager.readCustomMetadata()
if err != nil {
return nil, fmt.Errorf("failed to read metadata: %w", err)
}
if data == nil {
return nil, nil
}
metadata, err := decodeTreeMetadata(data)
if err != nil {
return nil, fmt.Errorf("failed to decode tree metadata: %w", err)
}
return metadata, nil
}
func (s *storage) updateMetadata(metadata *treeMetadata) error {
data := encodeTreeMetadata(metadata)
err := s.pager.writeCustomMetadata(data)
if err != nil {
return fmt.Errorf("failed to write metadata: %w", err)
}
return nil
}
func (s *storage) deleteMetadata() error {
var empty [0]byte
err := s.pager.writeCustomMetadata(empty[:])
if err != nil {
return fmt.Errorf("failed to write metadata: %w", err)
}
return nil
}
func (s *storage) newNode() (uint32, error) {
recordID, err := s.records.new()
if err != nil {
return 0, fmt.Errorf("failed to instantiate new record: %w", err)
}
return recordID, nil
}
func (s *storage) updateNodeByID(nodeID uint32, node *node) error {
data := encodeNode(node)
err := s.records.write(nodeID, data)
if err != nil {
return fmt.Errorf("failed to write the record %d: %w", nodeID, err)
}
return nil
}
func (s *storage) loadNodeByID(nodeID uint32) (*node, error) {
data, err := s.records.read(nodeID)
if err != nil {
return nil, fmt.Errorf("failed to read record %d: %w", nodeID, err)
}
node, err := decodeNode(data)
if err != nil {
return nil, fmt.Errorf("failed to decode record %d: %w", nodeID, err)
}
return node, nil
}
func (s *storage) deleteNodeByID(nodeID uint32) error {
err := s.records.free(nodeID)
if err != nil {
return fmt.Errorf("failed to free the record %d: %w", nodeID, err)
}
return nil
}
// Close closes the tree and free the underlying resources.
func (s *storage) close() error {
if err := s.pager.close(); err != nil {
return fmt.Errorf("failed to close the pager: %w", err)
}
return nil
}