OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "fmt" | 9 "fmt" |
10 "sort" | 10 "sort" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 // indexes for (k, pm) combined with complexIdxs. | 48 // indexes for (k, pm) combined with complexIdxs. |
49 // | 49 // |
50 // If "pm" is nil, this indicates an absence of a value. This is used | 50 // If "pm" is nil, this indicates an absence of a value. This is used |
51 // specifically for deletion. | 51 // specifically for deletion. |
52 func indexEntriesWithBuiltins(k *ds.Key, pm ds.PropertyMap, complexIdxs []*ds.In
dexDefinition) memStore { | 52 func indexEntriesWithBuiltins(k *ds.Key, pm ds.PropertyMap, complexIdxs []*ds.In
dexDefinition) memStore { |
53 var sip serialize.SerializedPmap | 53 var sip serialize.SerializedPmap |
54 if pm == nil { | 54 if pm == nil { |
55 return newMemStore() | 55 return newMemStore() |
56 } | 56 } |
57 sip = serialize.PropertyMapPartially(k, pm) | 57 sip = serialize.PropertyMapPartially(k, pm) |
58 » return indexEntries(sip, k.Namespace(), append(defaultIndexes(k.Kind(),
pm), complexIdxs...)) | 58 » return indexEntries(k, sip, append(defaultIndexes(k.Kind(), pm), complex
Idxs...)) |
59 } | 59 } |
60 | 60 |
61 // indexRowGen contains enough information to generate all of the index rows whi
ch | 61 // indexRowGen contains enough information to generate all of the index rows whi
ch |
62 // correspond with a propertyList and a ds.IndexDefinition. | 62 // correspond with a propertyList and a ds.IndexDefinition. |
63 type indexRowGen struct { | 63 type indexRowGen struct { |
64 propVec []serialize.SerializedPslice | 64 propVec []serialize.SerializedPslice |
65 decending []bool | 65 decending []bool |
66 } | 66 } |
67 | 67 |
68 // permute calls cb for each index row, in the sorted order of the rows. | 68 // permute calls cb for each index row, in the sorted order of the rows. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 m.buf.decending = append(m.buf.decending, sb.Descending) | 137 m.buf.decending = append(m.buf.decending, sb.Descending) |
138 } else { | 138 } else { |
139 return indexRowGen{}, false | 139 return indexRowGen{}, false |
140 } | 140 } |
141 } | 141 } |
142 return m.buf, true | 142 return m.buf, true |
143 } | 143 } |
144 | 144 |
145 // indexEntries generates a new memStore containing index entries for sip for | 145 // indexEntries generates a new memStore containing index entries for sip for |
146 // the supplied index definitions. | 146 // the supplied index definitions. |
147 func indexEntries(sip serialize.SerializedPmap, ns string, idxs []*ds.IndexDefin
ition) memStore { | 147 func indexEntries(key *ds.Key, sip serialize.SerializedPmap, idxs []*ds.IndexDef
inition) memStore { |
148 ret := newMemStore() | 148 ret := newMemStore() |
149 idxColl := ret.GetOrCreateCollection("idx") | 149 idxColl := ret.GetOrCreateCollection("idx") |
150 | 150 |
151 mtch := matcher{} | 151 mtch := matcher{} |
152 for _, idx := range idxs { | 152 for _, idx := range idxs { |
153 idx = idx.Normalize() | 153 idx = idx.Normalize() |
| 154 if idx.Kind != "" && idx.Kind != key.Kind() { |
| 155 continue |
| 156 } |
154 if irg, ok := mtch.match(idx.GetFullSortOrder(), sip); ok { | 157 if irg, ok := mtch.match(idx.GetFullSortOrder(), sip); ok { |
155 idxBin := serialize.ToBytes(*idx.PrepForIdxTable()) | 158 idxBin := serialize.ToBytes(*idx.PrepForIdxTable()) |
156 idxColl.Set(idxBin, []byte{}) | 159 idxColl.Set(idxBin, []byte{}) |
157 » » » coll := ret.GetOrCreateCollection(fmt.Sprintf("idx:%s:%s
", ns, idxBin)) | 160 » » » coll := ret.GetOrCreateCollection( |
| 161 » » » » fmt.Sprintf("idx:%s:%s", key.Namespace(), idxBin
)) |
158 irg.permute(coll.Set) | 162 irg.permute(coll.Set) |
159 } | 163 } |
160 } | 164 } |
161 | 165 |
162 return ret | 166 return ret |
163 } | 167 } |
164 | 168 |
165 // walkCompIdxs walks the table of compound indexes in the store. If `endsWith` | 169 // walkCompIdxs walks the table of compound indexes in the store. If `endsWith` |
166 // is provided, this will only walk over compound indexes which match | 170 // is provided, this will only walk over compound indexes which match |
167 // Kind, Ancestor, and whose SortBy has `endsWith.SortBy` as a suffix. | 171 // Kind, Ancestor, and whose SortBy has `endsWith.SortBy` as a suffix. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 | 257 |
254 prop, err := serialize.ReadProperty(bytes.NewBuf
fer(i.Key), serialize.WithoutContext, ds.MkKeyContext(aid, ns)) | 258 prop, err := serialize.ReadProperty(bytes.NewBuf
fer(i.Key), serialize.WithoutContext, ds.MkKeyContext(aid, ns)) |
255 memoryCorruption(err) | 259 memoryCorruption(err) |
256 | 260 |
257 k := prop.Value().(*ds.Key) | 261 k := prop.Value().(*ds.Key) |
258 | 262 |
259 sip := serialize.PropertyMapPartially(k, pm) | 263 sip := serialize.PropertyMapPartially(k, pm) |
260 | 264 |
261 mergeIndexes(ns, store, | 265 mergeIndexes(ns, store, |
262 newMemStore(), | 266 newMemStore(), |
263 » » » » » indexEntries(sip, ns, normalized)) | 267 » » » » » indexEntries(k, sip, normalized)) |
264 return true | 268 return true |
265 }) | 269 }) |
266 } | 270 } |
267 } | 271 } |
268 } | 272 } |
269 | 273 |
270 // updateIndexes updates the indexes in store to accommodate a change in entity | 274 // updateIndexes updates the indexes in store to accommodate a change in entity |
271 // value. | 275 // value. |
272 // | 276 // |
273 // oldEnt is the previous entity value, and newEnt is the new entity value. If | 277 // oldEnt is the previous entity value, and newEnt is the new entity value. If |
274 // newEnt is nil, that signifies deletion. | 278 // newEnt is nil, that signifies deletion. |
275 func updateIndexes(store memStore, key *ds.Key, oldEnt, newEnt ds.PropertyMap) { | 279 func updateIndexes(store memStore, key *ds.Key, oldEnt, newEnt ds.PropertyMap) { |
276 // load all current complex query index definitions. | 280 // load all current complex query index definitions. |
277 var compIdx []*ds.IndexDefinition | 281 var compIdx []*ds.IndexDefinition |
278 walkCompIdxs(store.Snapshot(), nil, func(i *ds.IndexDefinition) bool { | 282 walkCompIdxs(store.Snapshot(), nil, func(i *ds.IndexDefinition) bool { |
279 compIdx = append(compIdx, i) | 283 compIdx = append(compIdx, i) |
280 return true | 284 return true |
281 }) | 285 }) |
282 | 286 |
283 mergeIndexes(key.Namespace(), store, | 287 mergeIndexes(key.Namespace(), store, |
284 indexEntriesWithBuiltins(key, oldEnt, compIdx), | 288 indexEntriesWithBuiltins(key, oldEnt, compIdx), |
285 indexEntriesWithBuiltins(key, newEnt, compIdx)) | 289 indexEntriesWithBuiltins(key, newEnt, compIdx)) |
286 } | 290 } |
OLD | NEW |