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: logdog/common/storage/bigtable/testing.go

Issue 2435113002: LogDog: Add Storage-layer data caching. (Closed)
Patch Set: Fix byteLimit bug. Created 4 years, 1 month 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 | « logdog/common/storage/bigtable/storage_test.go ('k') | logdog/common/storage/caching/cache.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 2016 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 bigtable
6
7 import (
8 "bytes"
9 "fmt"
10 "time"
11
12 "github.com/luci/gkvlite"
13
14 "github.com/luci/luci-go/common/data/recordio"
15 "github.com/luci/luci-go/logdog/common/storage"
16
17 "golang.org/x/net/context"
18 )
19
20 // btTableTest is an in-memory implementation of btTable interface for testing.
21 //
22 // This is a simple implementation; not an efficient one.
23 type btTableTest struct {
24 s *gkvlite.Store
25 c *gkvlite.Collection
26
27 // err, if true, is the error immediately returned by functions.
28 err error
29
30 // maxLogAge is the currently-configured maximum log age.
31 maxLogAge time.Duration
32 }
33
34 // Testing is an extension of storage.Storage with additional testing
35 // capabilities.
36 type Testing interface {
37 storage.Storage
38
39 DataMap() map[string][]byte
40 SetMaxRowSize(int)
41 SetErr(error)
42 MaxLogAge() time.Duration
43 }
44
45 type btTestingStorage struct {
46 *btStorage
47 mem *btTableTest
48 }
49
50 func (st *btTestingStorage) Close() {
51 // Override Close to make sure our gkvlite instance is closed.
52 st.mem.close()
53 st.btStorage.Close()
54 }
55
56 func (st *btTestingStorage) DataMap() map[string][]byte { return st.mem.dataMap( ) }
57 func (st *btTestingStorage) SetMaxRowSize(v int) { st.maxRowSize = v }
58 func (st *btTestingStorage) SetErr(err error) { st.mem.err = err }
59 func (st *btTestingStorage) MaxLogAge() time.Duration { return st.mem.maxLogAg e }
60
61 // NewMemoryInstance returns an in-memory BigTable Storage implementation.
62 // This can be supplied in the Raw field in Options to simulate a BigTable
63 // connection.
64 //
65 // Close should be called on the resulting value after the user is finished in
66 // order to free resources.
67 func NewMemoryInstance(c context.Context, opts Options) Testing {
68 mem := &btTableTest{}
69 base := newBTStorage(c, opts, nil, nil, mem)
70 return &btTestingStorage{
71 btStorage: base,
72 mem: mem,
73 }
74 }
75
76 func (t *btTableTest) close() {
77 if t.s != nil {
78 t.s.Close()
79 t.s = nil
80 }
81 }
82
83 func (t *btTableTest) collection() *gkvlite.Collection {
84 if t.s == nil {
85 var err error
86 t.s, err = gkvlite.NewStore(nil)
87 if err != nil {
88 panic(err)
89 }
90 t.c = t.s.MakePrivateCollection(bytes.Compare)
91 }
92 return t.c
93 }
94
95 func (t *btTableTest) putLogData(c context.Context, rk *rowKey, d []byte) error {
96 if t.err != nil {
97 return t.err
98 }
99
100 // Record/count sanity check.
101 records, err := recordio.Split(d)
102 if err != nil {
103 return err
104 }
105 if int64(len(records)) != rk.count {
106 return fmt.Errorf("count mismatch (%d != %d)", len(records), rk. count)
107 }
108
109 enc := []byte(rk.encode())
110 coll := t.collection()
111 if item, _ := coll.Get(enc); item != nil {
112 return storage.ErrExists
113 }
114
115 clone := make([]byte, len(d))
116 copy(clone, d)
117 if err := coll.Set(enc, clone); err != nil {
118 panic(err)
119 }
120 return nil
121 }
122
123 func (t *btTableTest) getLogData(c context.Context, rk *rowKey, limit int, keysO nly bool, cb btGetCallback) error {
124 if t.err != nil {
125 return t.err
126 }
127
128 enc := []byte(rk.encode())
129 prefix := rk.pathPrefix()
130 var ierr error
131 err := t.collection().VisitItemsAscend(enc, !keysOnly, func(i *gkvlite.I tem) bool {
132 var drk *rowKey
133 drk, ierr = decodeRowKey(string(i.Key))
134 if ierr != nil {
135 return false
136 }
137 if drk.pathPrefix() != prefix {
138 return false
139 }
140
141 rowData := i.Val
142 if keysOnly {
143 rowData = nil
144 }
145
146 if ierr = cb(drk, rowData); ierr != nil {
147 if ierr == errStop {
148 ierr = nil
149 }
150 return false
151 }
152
153 if limit > 0 {
154 limit--
155 if limit == 0 {
156 return false
157 }
158 }
159
160 return true
161 })
162 if err != nil {
163 panic(err)
164 }
165 return ierr
166 }
167
168 func (t *btTableTest) setMaxLogAge(c context.Context, d time.Duration) error {
169 if t.err != nil {
170 return t.err
171 }
172 t.maxLogAge = d
173 return nil
174 }
175
176 func (t *btTableTest) dataMap() map[string][]byte {
177 result := map[string][]byte{}
178
179 err := t.collection().VisitItemsAscend([]byte(nil), true, func(i *gkvlit e.Item) bool {
180 result[string(i.Key)] = i.Val
181 return true
182 })
183 if err != nil {
184 panic(err)
185 }
186 return result
187 }
OLDNEW
« no previous file with comments | « logdog/common/storage/bigtable/storage_test.go ('k') | logdog/common/storage/caching/cache.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698