| 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 |