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

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

Issue 2604943002: impl/memory: Replace gkvlite with "treapstore". (Closed)
Patch Set: Update API for get/create. Created 3 years, 12 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
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 gtrea.Compare function for *storeEntry.
iannucci 2017/01/07 19:06:17 gtreap
dnj 2017/01/08 03:38:14 Done.
22 func storeEntryCompare(a, b interface{}) int {
iannucci 2017/01/07 19:06:17 that's unfortunate :/ no way we can hack up gtreap
dnj 2017/01/08 03:38:14 Yeah we totally could do this. Might be worth dete
23 return bytes.Compare(a.(*storeEntry).key, b.(*storeEntry).key)
24 }
25
26 func memStoreCollide(o, n memCollection, f func(k, ov, nv []byte)) {
27 var oldIter, newIter memIterator
28 if o != nil {
29 if !o.IsReadOnly() {
30 panic("old collection is r/w")
31 }
32 oldIter = o.Iterator(nil)
33 } else {
34 oldIter = nilIterator{}
35 }
36
37 if n != nil {
38 if !n.IsReadOnly() {
39 panic("new collection is r/w")
40 }
41 newIter = n.Iterator(nil)
42 } else {
43 newIter = nilIterator{}
44 }
45
46 l, r := oldIter.Next(), newIter.Next()
47 for {
48 switch {
49 case l == nil:
50 // No more "old" items, use up the rest of "new" and fin ish.
51 for r != nil {
52 f(r.key, nil, r.value)
53 r = newIter.Next()
54 }
55 return
56
57 case r == nil:
58 // No more "new" items, use up the rest of "old" and fin ish.
59 for l != nil {
60 f(l.key, l.value, nil)
61 l = oldIter.Next()
62 }
63 return
64
65 default:
66 switch bytes.Compare(l.key, r.key) {
67 case -1: // l < r
68 f(l.key, l.value, nil)
69 l = oldIter.Next()
70 case 0: // l == r
71 f(l.key, l.value, r.value)
72 l, r = oldIter.Next(), newIter.Next()
73 case 1: // l > r
74 f(r.key, nil, r.value)
75 r = newIter.Next()
76 }
77 }
78 }
79 }
80
81 // memStore is a generic interface modeled after treapstore.Store.
82 type memStore interface {
83 datastore.TestingSnapshot
84
85 GetCollection(name string) memCollection
86 GetCollectionNames() []string
87 GetOrCreateCollection(name string) memCollection
88 Snapshot() memStore
89
90 IsReadOnly() bool
91 }
92
93 // memIterator is an iterator over a memStore's contents.
94 type memIterator interface {
95 Next() *storeEntry
96 }
97
98 // memCollection is a generic interface modeled after treapstore.Collection.
99 type memCollection interface {
100 Name() string
101 Delete(k []byte)
102 Get(k []byte) []byte
103 MinItem() *storeEntry
104 Set(k, v []byte)
105 Iterator(pivot []byte) memIterator
106
107 IsReadOnly() bool
108 }
109
110 type memStoreImpl struct {
111 s *treapstore.Store
112 }
113
114 var _ memStore = (*memStoreImpl)(nil)
115
116 func (*memStoreImpl) ImATestingSnapshot() {}
117
118 func (ms *memStoreImpl) IsReadOnly() bool { return ms.s.IsReadOnly() }
119
120 func newMemStore() memStore {
121 ret := memStore(&memStoreImpl{treapstore.New()})
122 if *logMemCollectionFolder != "" {
123 ret = wrapTracingMemStore(ret)
124 }
125 return ret
126 }
127
128 func (ms *memStoreImpl) Snapshot() memStore {
129 if ms.s.IsReadOnly() {
130 return ms
131 }
132 return &memStoreImpl{ms.s.Snapshot()}
133 }
134
135 func (ms *memStoreImpl) GetCollection(name string) memCollection {
136 coll := ms.s.GetCollection(name)
137 if coll == nil {
138 return nil
139 }
140 return &memCollectionImpl{coll}
141 }
142
143 func (ms *memStoreImpl) GetOrCreateCollection(name string) memCollection {
144 coll := ms.s.GetCollection(name)
145 if coll == nil {
146 coll = ms.s.CreateCollection(name, storeEntryCompare)
147 }
148 return &memCollectionImpl{coll}
149 }
150
151 func (ms *memStoreImpl) GetCollectionNames() []string { return ms.s.GetCollectio nNames() }
152
153 type memIteratorImpl struct {
154 base *gtreap.Iterator
155 }
156
157 func (it *memIteratorImpl) Next() *storeEntry {
158 v, ok := it.base.Next()
159 if !ok {
160 return nil
161 }
162 return v.(*storeEntry)
163 }
164
165 type memCollectionImpl struct {
166 c *treapstore.Collection
167 }
168
169 var _ memCollection = (*memCollectionImpl)(nil)
170
171 func (mc *memCollectionImpl) Name() string { return mc.c.Name() }
172 func (mc *memCollectionImpl) IsReadOnly() bool { return mc.c.IsReadOnly() }
173
174 func (mc *memCollectionImpl) Get(k []byte) []byte {
175 if ent := mc.c.Get(storeKey(k)); ent != nil {
176 return ent.(*storeEntry).value
177 }
178 return nil
179 }
180
181 func (mc *memCollectionImpl) MinItem() *storeEntry {
182 ent, _ := mc.c.Min().(*storeEntry)
183 return ent
184 }
185
186 func (mc *memCollectionImpl) Set(k, v []byte) { mc.c.Put(&storeEntry{k, v}) }
187 func (mc *memCollectionImpl) Delete(k []byte) { mc.c.Delete(storeKey(k)) }
188
189 func (mc *memCollectionImpl) Iterator(target []byte) memIterator {
190 if !mc.c.IsReadOnly() {
191 // We prevent this to ensure our internal logic, not because it' s actually
192 // an invalid operation.
193 panic("attempting to get Iterator from r/w memCollection")
194 }
195 return &memIteratorImpl{mc.c.Iterator(storeKey(target))}
196 }
197
198 func storeKey(k []byte) *storeEntry { return &storeEntry{k, nil} }
199
200 // nilIterator is a memIterator that begins in a depleted state.
201 type nilIterator struct{}
202
203 func (it nilIterator) Next() *storeEntry { return nil }
204
205 func forEachItem(mc memCollection, cb func(k, v []byte) bool) {
206 it := mc.Iterator(nil)
207 for ent := it.Next(); ent != nil; ent = it.Next() {
208 if !cb(ent.key, ent.value) {
209 break
210 }
211 }
212 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698