-
Notifications
You must be signed in to change notification settings - Fork 2
/
node_storage.go
155 lines (133 loc) · 3.24 KB
/
node_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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package storage
import (
"container/list"
"fmt"
)
type ReadOnlyNodeStorage interface {
GetByKey(key string) ([]*DBRecord, error)
GetByGid(gid string) (*DBRecord, error)
AllNodes() ([]*DBRecord, error)
}
type NodeStorage interface {
ReadOnlyNodeStorage
Add(record *DBRecord) error
Replace(old string, new *DBRecord) error
Merge(other ReadOnlyNodeStorage) error
}
type NodeStorageImpl struct {
l *list.List
keyIndex map[string]*list.List
gidIndex map[string]*list.Element
}
func (n *NodeStorageImpl) Init() {
n.clear()
}
func (n *NodeStorageImpl) clear() {
n.l = list.New()
n.keyIndex = make(map[string]*list.List)
n.gidIndex = make(map[string]*list.Element)
}
func (n *NodeStorageImpl) getByGidInternal(gid string) *list.Element {
e, ok := n.gidIndex[gid]
if !ok {
return nil
}
return e
}
func (n *NodeStorageImpl) addNodeInternal(record *DBRecord) error {
result := n.getByGidInternal(record.CurrentLogGid)
if result != nil {
return fmt.Errorf("node exists")
}
e := n.l.PushBack(record)
elements, ok := n.keyIndex[record.Key]
if !ok {
elements = list.New()
n.keyIndex[record.Key] = elements
}
elements.PushBack(e)
n.gidIndex[record.CurrentLogGid] = e
return nil
}
// make sure e is not nil and e is in n.l
func (n *NodeStorageImpl) delNodeInternal(e *list.Element) {
record := n.l.Remove(e).(*DBRecord)
delete(n.gidIndex, record.CurrentLogGid)
elements, ok := n.keyIndex[record.Key]
if ok {
for e1 := elements.Front(); e1 != nil; e1 = e1.Next() {
if e1.Value.(*list.Element).Value.(*DBRecord).CurrentLogGid == record.CurrentLogGid {
elements.Remove(e1)
break
}
}
}
}
func (n *NodeStorageImpl) GetByKey(key string) ([]*DBRecord, error) {
elements, ok := n.keyIndex[key]
if !ok {
return nil, nil
}
records := make([]*DBRecord, elements.Len())
for e := elements.Front(); e != nil; e = e.Next() {
record := e.Value.(*list.Element).Value.(*DBRecord)
records = append(records, record)
}
return records, nil
}
func (n *NodeStorageImpl) GetByGid(gid string) (*DBRecord, error) {
result := n.getByGidInternal(gid)
if result != nil {
return result.Value.(*DBRecord), nil
}
return nil, nil
}
func (n *NodeStorageImpl) Add(record *DBRecord) error {
return n.addNodeInternal(record)
}
func (n *NodeStorageImpl) Replace(old string, new *DBRecord) error {
e := n.getByGidInternal(old)
if e == nil {
return fmt.Errorf("old not exist")
}
e1 := n.getByGidInternal(new.CurrentLogGid)
if e1 != nil {
return fmt.Errorf("new node already exist")
}
if e.Value.(*DBRecord).Key != new.Key {
return fmt.Errorf("key not match")
}
if err := n.addNodeInternal(new); err != nil {
return err
}
n.delNodeInternal(e)
return nil
}
func (n *NodeStorageImpl) del(gid string) error {
e := n.getByGidInternal(gid)
if e == nil {
return nil
}
n.delNodeInternal(e)
return nil
}
func (n *NodeStorageImpl) AllNodes() ([]*DBRecord, error) {
results := make([]*DBRecord, 0, n.l.Len())
for e := n.l.Front(); e != nil; e = e.Next() {
results = append(results, e.Value.(*DBRecord))
}
return results, nil
}
func (n *NodeStorageImpl) Merge(other ReadOnlyNodeStorage) error {
all, err := other.AllNodes()
if err != nil {
return err
}
for _, node := range all {
if node == nil {
continue
}
_ = n.Add(node)
}
return nil
}