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

Side by Side Diff: impl/memory/gkvlite_utils.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_tracing_utils.go ('k') | impl/memory/gkvlite_utils_test.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 "runtime"
10
11 "github.com/luci/gae/service/datastore"
12 "github.com/luci/gkvlite"
13 )
14
15 func gkvCollide(o, n memCollection, f func(k, ov, nv []byte)) {
16 if o != nil && !o.IsReadOnly() {
17 panic("old collection is r/w")
18 }
19 if n != nil && !n.IsReadOnly() {
20 panic("new collection is r/w")
21 }
22
23 // TODO(riannucci): reimplement in terms of *iterator.
24 oldItems, newItems := make(chan *gkvlite.Item), make(chan *gkvlite.Item)
25 walker := func(c memCollection, ch chan<- *gkvlite.Item) {
26 defer close(ch)
27 if c != nil {
28 c.VisitItemsAscend(nil, true, func(i *gkvlite.Item) bool {
29 ch <- i
30 return true
31 })
32 }
33 }
34
35 go walker(o, oldItems)
36 go walker(n, newItems)
37
38 l, r := <-oldItems, <-newItems
39 for {
40 switch {
41 case l == nil && r == nil:
42 return
43
44 case l == nil:
45 f(r.Key, nil, r.Val)
46 r = <-newItems
47
48 case r == nil:
49 f(l.Key, l.Val, nil)
50 l = <-oldItems
51
52 default:
53 switch bytes.Compare(l.Key, r.Key) {
54 case -1: // l < r
55 f(l.Key, l.Val, nil)
56 l = <-oldItems
57 case 0: // l == r
58 f(l.Key, l.Val, r.Val)
59 l, r = <-oldItems, <-newItems
60 case 1: // l > r
61 f(r.Key, nil, r.Val)
62 r = <-newItems
63 }
64 }
65 }
66 }
67
68 // memStore is a gkvlite.Store which will panic for anything which might
69 // otherwise return an error.
70 //
71 // This is reasonable for in-memory Store objects, since the only errors that
72 // should occur happen with file IO on the underlying file (which of course
73 // doesn't exist).
74 type memStore interface {
75 datastore.TestingSnapshot
76
77 GetCollection(name string) memCollection
78 GetCollectionNames() []string
79 GetOrCreateCollection(name string) memCollection
80 Snapshot() memStore
81
82 IsReadOnly() bool
83 }
84
85 // memCollection is a gkvlite.Collection which will panic for anything which
86 // might otherwise return an error.
87 //
88 // This is reasonable for in-memory Store objects, since the only errors that
89 // should occur happen with file IO on the underlying file (which of course
90 // doesn't exist.
91 type memCollection interface {
92 Name() string
93 Delete(k []byte) bool
94 Get(k []byte) []byte
95 GetTotals() (numItems, numBytes uint64)
96 MinItem(withValue bool) *gkvlite.Item
97 Set(k, v []byte)
98 VisitItemsAscend(target []byte, withValue bool, visitor gkvlite.ItemVisi tor)
99
100 IsReadOnly() bool
101 }
102
103 type memStoreImpl struct {
104 s *gkvlite.Store
105 ro bool
106 }
107
108 var _ memStore = (*memStoreImpl)(nil)
109
110 func (*memStoreImpl) ImATestingSnapshot() {}
111
112 func (ms *memStoreImpl) IsReadOnly() bool { return ms.ro }
113
114 func newMemStore() memStore {
115 store, err := gkvlite.NewStore(nil)
116 memoryCorruption(err)
117 ret := memStore(&memStoreImpl{store, false})
118 if *logMemCollectionFolder != "" {
119 ret = wrapTracingMemStore(ret)
120 }
121 return ret
122 }
123
124 func (ms *memStoreImpl) Snapshot() memStore {
125 if ms.ro {
126 return ms
127 }
128 ret := ms.s.Snapshot()
129 runtime.SetFinalizer(ret, func(s *gkvlite.Store) { go s.Close() })
130 return &memStoreImpl{ret, true}
131 }
132
133 func (ms *memStoreImpl) GetCollection(name string) memCollection {
134 coll := ms.s.GetCollection(name)
135 if coll == nil {
136 return nil
137 }
138 return &memCollectionImpl{coll, ms.ro}
139 }
140
141 func (ms *memStoreImpl) GetOrCreateCollection(name string) memCollection {
142 coll := ms.GetCollection(name)
143 if coll == nil {
144 coll = &memCollectionImpl{(ms.s.SetCollection(name, nil)), ms.ro }
145 }
146 return coll
147 }
148
149 func (ms *memStoreImpl) GetCollectionNames() []string {
150 return ms.s.GetCollectionNames()
151 }
152
153 type memCollectionImpl struct {
154 c *gkvlite.Collection
155 ro bool
156 }
157
158 var _ memCollection = (*memCollectionImpl)(nil)
159
160 func (mc *memCollectionImpl) Name() string { return mc.c.Name() }
161 func (mc *memCollectionImpl) IsReadOnly() bool { return mc.ro }
162
163 func (mc *memCollectionImpl) Get(k []byte) []byte {
164 ret, err := mc.c.Get(k)
165 memoryCorruption(err)
166 return ret
167 }
168
169 func (mc *memCollectionImpl) MinItem(withValue bool) *gkvlite.Item {
170 ret, err := mc.c.MinItem(withValue)
171 memoryCorruption(err)
172 return ret
173 }
174
175 func (mc *memCollectionImpl) Set(k, v []byte) {
176 err := mc.c.Set(k, v)
177 memoryCorruption(err)
178 }
179
180 func (mc *memCollectionImpl) Delete(k []byte) bool {
181 ret, err := mc.c.Delete(k)
182 memoryCorruption(err)
183 return ret
184 }
185
186 func (mc *memCollectionImpl) VisitItemsAscend(target []byte, withValue bool, vis itor gkvlite.ItemVisitor) {
187 if !mc.ro {
188 panic("attempting to VisitItemsAscend from r/w memCollection")
189 }
190 err := mc.c.VisitItemsAscend(target, withValue, visitor)
191 memoryCorruption(err)
192 }
193
194 func (mc *memCollectionImpl) GetTotals() (numItems, numBytes uint64) {
195 numItems, numBytes, err := mc.c.GetTotals()
196 memoryCorruption(err)
197 return
198 }
OLDNEW
« no previous file with comments | « impl/memory/gkvlite_tracing_utils.go ('k') | impl/memory/gkvlite_utils_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698