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) AddIndexes(idxs ...*ds.IndexDefinition) { | 76 func (d *dsImpl) AddIndexes(idxs ...*ds.IndexDefinition) { |
72 if len(idxs) == 0 { | 77 if len(idxs) == 0 { |
73 return | 78 return |
74 } | 79 } |
75 | 80 |
76 for _, i := range idxs { | 81 for _, i := range idxs { |
77 if !i.Compound() { | 82 if !i.Compound() { |
78 panic(fmt.Errorf("Attempted to add non-compound index: %
s", i)) | 83 panic(fmt.Errorf("Attempted to add non-compound index: %
s", i)) |
79 } | 84 } |
80 } | 85 } |
81 | 86 |
82 » d.data.Lock() | 87 » d.data.addIndexes(d.ns, idxs) |
83 » defer d.data.Unlock() | |
84 » addIndex(d.data.head, d.ns, idxs) | |
85 } | 88 } |
86 | 89 |
87 func (d *dsImpl) TakeIndexSnapshot() ds.TestingSnapshot { | 90 func (d *dsImpl) TakeIndexSnapshot() ds.TestingSnapshot { |
88 return d.data.takeSnapshot() | 91 return d.data.takeSnapshot() |
89 } | 92 } |
90 | 93 |
91 func (d *dsImpl) SetIndexSnapshot(snap ds.TestingSnapshot) { | 94 func (d *dsImpl) SetIndexSnapshot(snap ds.TestingSnapshot) { |
92 d.data.setSnapshot(snap.(*memStore)) | 95 d.data.setSnapshot(snap.(*memStore)) |
93 } | 96 } |
94 | 97 |
95 func (d *dsImpl) CatchupIndexes() { | 98 func (d *dsImpl) CatchupIndexes() { |
96 d.data.catchupIndexes() | 99 d.data.catchupIndexes() |
97 } | 100 } |
98 | 101 |
99 func (d *dsImpl) SetTransactionRetryCount(count int) { | 102 func (d *dsImpl) SetTransactionRetryCount(count int) { |
100 d.data.setTxnRetry(count) | 103 d.data.setTxnRetry(count) |
101 } | 104 } |
102 | 105 |
103 func (d *dsImpl) Consistent(always bool) { | 106 func (d *dsImpl) Consistent(always bool) { |
104 d.data.setConsistent(always) | 107 d.data.setConsistent(always) |
105 } | 108 } |
106 | 109 |
| 110 func (d *dsImpl) AutoIndex(enable bool) { |
| 111 d.data.setAutoIndex(enable) |
| 112 } |
| 113 |
107 func (d *dsImpl) Testable() ds.Testable { | 114 func (d *dsImpl) Testable() ds.Testable { |
108 return d | 115 return d |
109 } | 116 } |
110 | 117 |
111 ////////////////////////////////// txnDsImpl /////////////////////////////////// | 118 ////////////////////////////////// txnDsImpl /////////////////////////////////// |
112 | 119 |
113 type txnDsImpl struct { | 120 type txnDsImpl struct { |
114 data *txnDataStoreData | 121 data *txnDataStoreData |
115 ns string | 122 ns string |
116 } | 123 } |
(...skipping 22 matching lines...) Expand all Loading... |
139 return d.data.run(func() error { | 146 return d.data.run(func() error { |
140 return d.data.delMulti(keys, cb) | 147 return d.data.delMulti(keys, cb) |
141 }) | 148 }) |
142 } | 149 } |
143 | 150 |
144 func (d *txnDsImpl) DecodeCursor(s string) (ds.Cursor, error) { | 151 func (d *txnDsImpl) DecodeCursor(s string) (ds.Cursor, error) { |
145 return newCursor(s) | 152 return newCursor(s) |
146 } | 153 } |
147 | 154 |
148 func (d *txnDsImpl) Run(q *ds.FinalizedQuery, cb ds.RawRunCB) error { | 155 func (d *txnDsImpl) Run(q *ds.FinalizedQuery, cb ds.RawRunCB) error { |
| 156 // note that autoIndex has no effect inside transactions. This is becaus
e |
| 157 // the transaction guarantees a consistent view of head at the time that
the |
| 158 // transaction opens. At best, we could add the index on head, but then
return |
| 159 // the error anyway, but adding the index then re-snapping at head would |
| 160 // potentially reveal other entities not in the original transaction sna
pshot. |
| 161 // |
| 162 // It's possible that if you have full-consistency and also auto index e
nabled |
| 163 // that this would make sense... but at that point you should probably j
ust |
| 164 // add the index up front. |
149 return executeQuery(q, d.ns, true, d.data.snap, d.data.snap, cb) | 165 return executeQuery(q, d.ns, true, d.data.snap, d.data.snap, cb) |
150 } | 166 } |
151 | 167 |
152 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *ds.Transactio
nOptions) error { | 168 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *ds.Transactio
nOptions) error { |
153 return errors.New("datastore: nested transactions are not supported") | 169 return errors.New("datastore: nested transactions are not supported") |
154 } | 170 } |
155 | 171 |
156 func (*txnDsImpl) Testable() ds.Testable { | 172 func (*txnDsImpl) Testable() ds.Testable { |
157 return nil | 173 return nil |
158 } | 174 } |
OLD | NEW |