Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: impl/memory/memstore.go

Issue 2604943002: impl/memory: Replace gkvlite with "treapstore". (Closed)
Patch Set: Comments. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « impl/memory/gkvlite_utils_test.go ('k') | impl/memory/memstore_iter.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 package memory
6
7 import (
8 "bytes"
9
10 "github.com/luci/gae/service/datastore"
11
12 "github.com/luci/gtreap"
13 "github.com/luci/luci-go/common/data/treapstore"
14 )
15
16 type storeEntry struct {
17 key []byte
18 value []byte
19 }
20
21 // storeEntryCompare is a gtreap.Compare function for *storeEntry.
22 func storeEntryCompare(a, b interface{}) int {
23 // TODO(dnj): Investigate optimizing this by removing the type assertion s,
24 // either by explicitly tailoring gtreap / treapstore to use []byte or b y
25 // optimizing via special-case interface.
26 return bytes.Compare(a.(*storeEntry).key, b.(*storeEntry).key)
27 }
28
29 func memStoreCollide(o, n memCollection, f func(k, ov, nv []byte)) {
30 var oldIter, newIter memIterator
31 if o != nil {
32 if !o.IsReadOnly() {
33 panic("old collection is r/w")
34 }
35 oldIter = o.Iterator(nil)
36 } else {
37 oldIter = nilIterator{}
38 }
39
40 if n != nil {
41 if !n.IsReadOnly() {
42 panic("new collection is r/w")
43 }
44 newIter = n.Iterator(nil)
45 } else {
46 newIter = nilIterator{}
47 }
48
49 l, r := oldIter.Next(), newIter.Next()
50 for {
51 switch {
52 case l == nil:
53 // No more "old" items, use up the rest of "new" and fin ish.
54 for r != nil {
55 f(r.key, nil, r.value)
56 r = newIter.Next()
57 }
58 return
59
60 case r == nil:
61 // No more "new" items, use up the rest of "old" and fin ish.
62 for l != nil {
63 f(l.key, l.value, nil)
64 l = oldIter.Next()
65 }
66 return
67
68 default:
69 switch bytes.Compare(l.key, r.key) {
70 case -1: // l < r
71 f(l.key, l.value, nil)
72 l = oldIter.Next()
73 case 0: // l == r
74 f(l.key, l.value, r.value)
75 l, r = oldIter.Next(), newIter.Next()
76 case 1: // l > r
77 f(r.key, nil, r.value)
78 r = newIter.Next()
79 }
80 }
81 }
82 }
83
84 // memStore is a generic interface modeled after treapstore.Store.
85 type memStore interface {
86 datastore.TestingSnapshot
87
88 GetCollection(name string) memCollection
89 GetCollectionNames() []string
90 GetOrCreateCollection(name string) memCollection
91 Snapshot() memStore
92
93 IsReadOnly() bool
94 }
95
96 // memIterator is an iterator over a memStore's contents.
97 type memIterator interface {
98 Next() *storeEntry
99 }
100
101 // memVisitor is a callback for ForEachItem.
102 type memVisitor func(k, v []byte) bool
103
104 // memCollection is a generic interface modeled after treapstore.Collection.
105 type memCollection interface {
106 Name() string
107 Delete(k []byte)
108 Get(k []byte) []byte
109 MinItem() *storeEntry
110 Set(k, v []byte)
111 Iterator(pivot []byte) memIterator
112 ForEachItem(memVisitor)
113
114 IsReadOnly() bool
115 }
116
117 type memStoreImpl struct {
118 s *treapstore.Store
119 }
120
121 var _ memStore = (*memStoreImpl)(nil)
122
123 func (*memStoreImpl) ImATestingSnapshot() {}
124
125 func (ms *memStoreImpl) IsReadOnly() bool { return ms.s.IsReadOnly() }
126
127 func newMemStore() memStore {
128 ret := memStore(&memStoreImpl{treapstore.New()})
129 if *logMemCollectionFolder != "" {
130 ret = wrapTracingMemStore(ret)
131 }
132 return ret
133 }
134
135 func (ms *memStoreImpl) Snapshot() memStore {
136 if ms.s.IsReadOnly() {
137 return ms
138 }
139 return &memStoreImpl{ms.s.Snapshot()}
140 }
141
142 func (ms *memStoreImpl) GetCollection(name string) memCollection {
143 coll := ms.s.GetCollection(name)
144 if coll == nil {
145 return nil
146 }
147 return &memCollectionImpl{coll}
148 }
149
150 func (ms *memStoreImpl) GetOrCreateCollection(name string) memCollection {
151 coll := ms.s.GetCollection(name)
152 if coll == nil {
153 coll = ms.s.CreateCollection(name, storeEntryCompare)
154 }
155 return &memCollectionImpl{coll}
156 }
157
158 func (ms *memStoreImpl) GetCollectionNames() []string { return ms.s.GetCollectio nNames() }
159
160 type memIteratorImpl struct {
161 base *gtreap.Iterator
162 }
163
164 func (it *memIteratorImpl) Next() *storeEntry {
165 v, ok := it.base.Next()
166 if !ok {
167 return nil
168 }
169 return v.(*storeEntry)
170 }
171
172 type memCollectionImpl struct {
173 c *treapstore.Collection
174 }
175
176 var _ memCollection = (*memCollectionImpl)(nil)
177
178 func (mc *memCollectionImpl) Name() string { return mc.c.Name() }
179 func (mc *memCollectionImpl) IsReadOnly() bool { return mc.c.IsReadOnly() }
180
181 func (mc *memCollectionImpl) Get(k []byte) []byte {
182 if ent := mc.c.Get(storeKey(k)); ent != nil {
183 return ent.(*storeEntry).value
184 }
185 return nil
186 }
187
188 func (mc *memCollectionImpl) MinItem() *storeEntry {
189 ent, _ := mc.c.Min().(*storeEntry)
190 return ent
191 }
192
193 func (mc *memCollectionImpl) Set(k, v []byte) { mc.c.Put(&storeEntry{k, v}) }
194 func (mc *memCollectionImpl) Delete(k []byte) { mc.c.Delete(storeKey(k)) }
195
196 func (mc *memCollectionImpl) Iterator(target []byte) memIterator {
197 if !mc.c.IsReadOnly() {
198 // We prevent this to ensure our internal logic, not because it' s actually
199 // an invalid operation.
200 panic("attempting to get Iterator from r/w memCollection")
201 }
202 return &memIteratorImpl{mc.c.Iterator(storeKey(target))}
203 }
204
205 func (mc *memCollectionImpl) ForEachItem(fn memVisitor) {
206 mc.c.VisitAscend(storeKey(nil), func(it gtreap.Item) bool {
207 ent := it.(*storeEntry)
208 return fn(ent.key, ent.value)
209 })
210 }
211
212 func storeKey(k []byte) *storeEntry { return &storeEntry{k, nil} }
213
214 // nilIterator is a memIterator that begins in a depleted state.
215 type nilIterator struct{}
216
217 func (it nilIterator) Next() *storeEntry { return nil }
OLDNEW
« no previous file with comments | « impl/memory/gkvlite_utils_test.go ('k') | impl/memory/memstore_iter.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698