OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "errors" | 8 "errors" |
9 "fmt" | 9 "fmt" |
10 | 10 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 d.data.delMulti(keys, cb) | 58 d.data.delMulti(keys, cb) |
59 return nil | 59 return nil |
60 } | 60 } |
61 | 61 |
62 func (d *dsImpl) DecodeCursor(s string) (ds.Cursor, error) { | 62 func (d *dsImpl) DecodeCursor(s string) (ds.Cursor, error) { |
63 return newCursor(s) | 63 return newCursor(s) |
64 } | 64 } |
65 | 65 |
66 func (d *dsImpl) Run(fq *ds.FinalizedQuery, cb ds.RawRunCB) error { | 66 func (d *dsImpl) Run(fq *ds.FinalizedQuery, cb ds.RawRunCB) error { |
67 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) | 67 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) |
68 » return executeQuery(fq, d.ns, false, idx, head, cb) | 68 » err := executeQuery(fq, d.ns, false, idx, head, cb) |
| 69 » if d.data.maybeAutoIndex(err) { |
| 70 » » idx, head = d.data.getQuerySnaps(!fq.EventuallyConsistent()) |
| 71 » » err = executeQuery(fq, d.ns, false, idx, head, cb) |
| 72 » } |
| 73 » return err |
69 } | 74 } |
70 | 75 |
71 func (d *dsImpl) Count(fq *ds.FinalizedQuery) (ret int64, err error) { | 76 func (d *dsImpl) Count(fq *ds.FinalizedQuery) (ret int64, err error) { |
72 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) | 77 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) |
73 » return countQuery(fq, d.ns, false, idx, head) | 78 » ret, err = countQuery(fq, d.ns, false, idx, head) |
| 79 » if d.data.maybeAutoIndex(err) { |
| 80 » » idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) |
| 81 » » ret, err = countQuery(fq, d.ns, false, idx, head) |
| 82 » } |
| 83 » return |
74 } | 84 } |
75 | 85 |
76 func (d *dsImpl) AddIndexes(idxs ...*ds.IndexDefinition) { | 86 func (d *dsImpl) AddIndexes(idxs ...*ds.IndexDefinition) { |
77 if len(idxs) == 0 { | 87 if len(idxs) == 0 { |
78 return | 88 return |
79 } | 89 } |
80 | 90 |
81 for _, i := range idxs { | 91 for _, i := range idxs { |
82 if !i.Compound() { | 92 if !i.Compound() { |
83 panic(fmt.Errorf("Attempted to add non-compound index: %
s", i)) | 93 panic(fmt.Errorf("Attempted to add non-compound index: %
s", i)) |
84 } | 94 } |
85 } | 95 } |
86 | 96 |
87 » d.data.Lock() | 97 » d.data.addIndexes(d.ns, idxs) |
88 » defer d.data.Unlock() | |
89 » addIndex(d.data.head, d.ns, idxs) | |
90 } | 98 } |
91 | 99 |
92 func (d *dsImpl) TakeIndexSnapshot() ds.TestingSnapshot { | 100 func (d *dsImpl) TakeIndexSnapshot() ds.TestingSnapshot { |
93 return d.data.takeSnapshot() | 101 return d.data.takeSnapshot() |
94 } | 102 } |
95 | 103 |
96 func (d *dsImpl) SetIndexSnapshot(snap ds.TestingSnapshot) { | 104 func (d *dsImpl) SetIndexSnapshot(snap ds.TestingSnapshot) { |
97 d.data.setSnapshot(snap.(*memStore)) | 105 d.data.setSnapshot(snap.(*memStore)) |
98 } | 106 } |
99 | 107 |
100 func (d *dsImpl) CatchupIndexes() { | 108 func (d *dsImpl) CatchupIndexes() { |
101 d.data.catchupIndexes() | 109 d.data.catchupIndexes() |
102 } | 110 } |
103 | 111 |
104 func (d *dsImpl) SetTransactionRetryCount(count int) { | 112 func (d *dsImpl) SetTransactionRetryCount(count int) { |
105 d.data.setTxnRetry(count) | 113 d.data.setTxnRetry(count) |
106 } | 114 } |
107 | 115 |
108 func (d *dsImpl) Consistent(always bool) { | 116 func (d *dsImpl) Consistent(always bool) { |
109 d.data.setConsistent(always) | 117 d.data.setConsistent(always) |
110 } | 118 } |
111 | 119 |
| 120 func (d *dsImpl) AutoIndex(enable bool) { |
| 121 d.data.setAutoIndex(enable) |
| 122 } |
| 123 |
112 func (d *dsImpl) Testable() ds.Testable { | 124 func (d *dsImpl) Testable() ds.Testable { |
113 return d | 125 return d |
114 } | 126 } |
115 | 127 |
116 ////////////////////////////////// txnDsImpl /////////////////////////////////// | 128 ////////////////////////////////// txnDsImpl /////////////////////////////////// |
117 | 129 |
118 type txnDsImpl struct { | 130 type txnDsImpl struct { |
119 data *txnDataStoreData | 131 data *txnDataStoreData |
120 ns string | 132 ns string |
121 } | 133 } |
(...skipping 22 matching lines...) Expand all Loading... |
144 return d.data.run(func() error { | 156 return d.data.run(func() error { |
145 return d.data.delMulti(keys, cb) | 157 return d.data.delMulti(keys, cb) |
146 }) | 158 }) |
147 } | 159 } |
148 | 160 |
149 func (d *txnDsImpl) DecodeCursor(s string) (ds.Cursor, error) { | 161 func (d *txnDsImpl) DecodeCursor(s string) (ds.Cursor, error) { |
150 return newCursor(s) | 162 return newCursor(s) |
151 } | 163 } |
152 | 164 |
153 func (d *txnDsImpl) Run(q *ds.FinalizedQuery, cb ds.RawRunCB) error { | 165 func (d *txnDsImpl) Run(q *ds.FinalizedQuery, cb ds.RawRunCB) error { |
| 166 // note that autoIndex has no effect inside transactions. This is becaus
e |
| 167 // the transaction guarantees a consistent view of head at the time that
the |
| 168 // transaction opens. At best, we could add the index on head, but then
return |
| 169 // the error anyway, but adding the index then re-snapping at head would |
| 170 // potentially reveal other entities not in the original transaction sna
pshot. |
| 171 // |
| 172 // It's possible that if you have full-consistency and also auto index e
nabled |
| 173 // that this would make sense... but at that point you should probably j
ust |
| 174 // add the index up front. |
154 return executeQuery(q, d.ns, true, d.data.snap, d.data.snap, cb) | 175 return executeQuery(q, d.ns, true, d.data.snap, d.data.snap, cb) |
155 } | 176 } |
156 | 177 |
157 func (d *txnDsImpl) Count(fq *ds.FinalizedQuery) (ret int64, err error) { | 178 func (d *txnDsImpl) Count(fq *ds.FinalizedQuery) (ret int64, err error) { |
158 return countQuery(fq, d.ns, true, d.data.snap, d.data.snap) | 179 return countQuery(fq, d.ns, true, d.data.snap, d.data.snap) |
159 } | 180 } |
160 | 181 |
161 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *ds.Transactio
nOptions) error { | 182 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *ds.Transactio
nOptions) error { |
162 return errors.New("datastore: nested transactions are not supported") | 183 return errors.New("datastore: nested transactions are not supported") |
163 } | 184 } |
164 | 185 |
165 func (*txnDsImpl) Testable() ds.Testable { | 186 func (*txnDsImpl) Testable() ds.Testable { |
166 return nil | 187 return nil |
167 } | 188 } |
OLD | NEW |