Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(577)

Side by Side Diff: impl/memory/datastore_index.go

Issue 1292913002: Split off serialization and key functions to their own packages. (Closed) Base URL: https://github.com/luci/gae.git@make_queries_better
Patch Set: rebase Created 5 years, 4 months 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 | « impl/memory/datastore_data.go ('k') | impl/memory/datastore_query.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "bytes" 8 "bytes"
9 "fmt" 9 "fmt"
10 "sort" 10 "sort"
11 11
12 ds "github.com/luci/gae/service/datastore" 12 ds "github.com/luci/gae/service/datastore"
13 "github.com/luci/gae/service/datastore/serialize"
13 "github.com/luci/gkvlite" 14 "github.com/luci/gkvlite"
14 ) 15 )
15 16
16 var indexCreationDeterministic = false 17 var indexCreationDeterministic = false
17 18
18 type qIndexSlice []*ds.IndexDefinition 19 type qIndexSlice []*ds.IndexDefinition
19 20
20 func (s qIndexSlice) Len() int { return len(s) } 21 func (s qIndexSlice) Len() int { return len(s) }
21 func (s qIndexSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 22 func (s qIndexSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
22 func (s qIndexSlice) Less(i, j int) bool { return s[i].Less(s[j]) } 23 func (s qIndexSlice) Less(i, j int) bool { return s[i].Less(s[j]) }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 67
67 buf := &bytes.Buffer{} 68 buf := &bytes.Buffer{}
68 ret = make(serializedIndexablePmap, len(pm)) 69 ret = make(serializedIndexablePmap, len(pm))
69 for k, vals := range pm { 70 for k, vals := range pm {
70 newVals := make(serializedPvals, 0, len(vals)) 71 newVals := make(serializedPvals, 0, len(vals))
71 for _, v := range vals { 72 for _, v := range vals {
72 if v.IndexSetting() == ds.NoIndex { 73 if v.IndexSetting() == ds.NoIndex {
73 continue 74 continue
74 } 75 }
75 buf.Reset() 76 buf.Reset()
76 » » » v.Write(buf, ds.WithoutContext) 77 » » » serialize.WriteProperty(buf, serialize.WithoutContext, v )
77 newVal := make([]byte, buf.Len()) 78 newVal := make([]byte, buf.Len())
78 copy(newVal, buf.Bytes()) 79 copy(newVal, buf.Bytes())
79 newVals = append(newVals, newVal) 80 newVals = append(newVals, newVal)
80 } 81 }
81 if len(newVals) > 0 { 82 if len(newVals) > 0 {
82 sort.Sort(newVals) 83 sort.Sort(newVals)
83 ret[k] = newVals 84 ret[k] = newVals
84 } 85 }
85 } 86 }
86 return 87 return
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 } 177 }
177 } 178 }
178 return m.buf, true 179 return m.buf, true
179 } 180 }
180 181
181 func (sip serializedIndexablePmap) indexEntries(k ds.Key, idxs []*ds.IndexDefini tion) *memStore { 182 func (sip serializedIndexablePmap) indexEntries(k ds.Key, idxs []*ds.IndexDefini tion) *memStore {
182 ret := newMemStore() 183 ret := newMemStore()
183 idxColl := ret.SetCollection("idx", nil) 184 idxColl := ret.SetCollection("idx", nil)
184 // getIdxEnts retrieves an index collection or adds it if it's not there . 185 // getIdxEnts retrieves an index collection or adds it if it's not there .
185 getIdxEnts := func(qi *ds.IndexDefinition) *memCollection { 186 getIdxEnts := func(qi *ds.IndexDefinition) *memCollection {
186 » » buf := &bytes.Buffer{} 187 » » b := serialize.ToBytes(*qi)
187 » » qi.Write(buf)
188 » » b := buf.Bytes()
189 idxColl.Set(b, []byte{}) 188 idxColl.Set(b, []byte{})
190 return ret.SetCollection(fmt.Sprintf("idx:%s:%s", k.Namespace(), b), nil) 189 return ret.SetCollection(fmt.Sprintf("idx:%s:%s", k.Namespace(), b), nil)
191 } 190 }
192 191
193 » buf := &bytes.Buffer{} 192 » keyData := serialize.ToBytes(k)
194 » ds.WriteKey(buf, ds.WithoutContext, k)
195 » keyData := buf.Bytes()
196 193
197 walkPermutations := func(prefix []byte, irg indexRowGen, ents *memCollec tion) { 194 walkPermutations := func(prefix []byte, irg indexRowGen, ents *memCollec tion) {
198 prev := []byte{} // intentionally make a non-nil slice, gkvlite hates nil. 195 prev := []byte{} // intentionally make a non-nil slice, gkvlite hates nil.
199 irg.permute(func(data []byte) { 196 irg.permute(func(data []byte) {
200 buf := bytes.NewBuffer(make([]byte, 0, len(prefix)+len(d ata)+len(keyData))) 197 buf := bytes.NewBuffer(make([]byte, 0, len(prefix)+len(d ata)+len(keyData)))
201 buf.Write(prefix) 198 buf.Write(prefix)
202 buf.Write(data) 199 buf.Write(data)
203 buf.Write(keyData) 200 buf.Write(keyData)
204 ents.Set(buf.Bytes(), prev) 201 ents.Set(buf.Bytes(), prev)
205 prev = data 202 prev = data
206 }) 203 })
207 } 204 }
208 205
209 mtch := matcher{} 206 mtch := matcher{}
210 for _, idx := range idxs { 207 for _, idx := range idxs {
211 if irg, ok := mtch.match(idx, sip); ok { 208 if irg, ok := mtch.match(idx, sip); ok {
212 idxEnts := getIdxEnts(idx) 209 idxEnts := getIdxEnts(idx)
213 if len(irg.propVec) == 0 { 210 if len(irg.propVec) == 0 {
214 idxEnts.Set(keyData, []byte{}) // propless index , e.g. kind -> key = nil 211 idxEnts.Set(keyData, []byte{}) // propless index , e.g. kind -> key = nil
215 } else if idx.Ancestor { 212 } else if idx.Ancestor {
216 for ancKey := k; ancKey != nil; ancKey = ancKey. Parent() { 213 for ancKey := k; ancKey != nil; ancKey = ancKey. Parent() {
217 » » » » » buf := &bytes.Buffer{} 214 » » » » » walkPermutations(serialize.ToBytes(ancKe y), irg, idxEnts)
218 » » » » » ds.WriteKey(buf, ds.WithoutContext, ancK ey)
219 » » » » » walkPermutations(buf.Bytes(), irg, idxEn ts)
220 } 215 }
221 } else { 216 } else {
222 walkPermutations(nil, irg, idxEnts) 217 walkPermutations(nil, irg, idxEnts)
223 } 218 }
224 } 219 }
225 } 220 }
226 221
227 return ret 222 return ret
228 } 223 }
229 224
230 func getCompIdxs(idxColl *memCollection) []*ds.IndexDefinition { 225 func getCompIdxs(idxColl *memCollection) []*ds.IndexDefinition {
231 // load all current complex query index definitions. 226 // load all current complex query index definitions.
232 compIdx := []*ds.IndexDefinition{} 227 compIdx := []*ds.IndexDefinition{}
233 complexQueryPrefix := ds.IndexComplexQueryPrefix() 228 complexQueryPrefix := ds.IndexComplexQueryPrefix()
234 idxColl.VisitItemsAscend(complexQueryPrefix, false, func(i *gkvlite.Item ) bool { 229 idxColl.VisitItemsAscend(complexQueryPrefix, false, func(i *gkvlite.Item ) bool {
235 if !bytes.HasPrefix(i.Key, complexQueryPrefix) { 230 if !bytes.HasPrefix(i.Key, complexQueryPrefix) {
236 return false 231 return false
237 } 232 }
238 » » qi := &ds.IndexDefinition{} 233 » » qi, err := serialize.ReadIndexDefinition(bytes.NewBuffer(i.Key))
239 » » if err := qi.Read(bytes.NewBuffer(i.Key)); err != nil { 234 » » if err != nil {
240 panic(err) // memory corruption 235 panic(err) // memory corruption
241 } 236 }
242 » » compIdx = append(compIdx, qi) 237 » » compIdx = append(compIdx, &qi)
243 return true 238 return true
244 }) 239 })
245 return compIdx 240 return compIdx
246 } 241 }
247 242
248 func getIdxColl(store *memStore) *memCollection { 243 func getIdxColl(store *memStore) *memCollection {
249 idxColl := store.GetCollection("idx") 244 idxColl := store.GetCollection("idx")
250 if idxColl == nil { 245 if idxColl == nil {
251 idxColl = store.SetCollection("idx", nil) 246 idxColl = store.SetCollection("idx", nil)
252 } 247 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 // when there are no index entries for that index any more. 292 // when there are no index entries for that index any more.
298 }) 293 })
299 } 294 }
300 295
301 func addIndex(store *memStore, ns string, compIdx []*ds.IndexDefinition) { 296 func addIndex(store *memStore, ns string, compIdx []*ds.IndexDefinition) {
302 store.GetCollection("ents:"+ns).VisitItemsAscend(nil, true, func(i *gkvl ite.Item) bool { 297 store.GetCollection("ents:"+ns).VisitItemsAscend(nil, true, func(i *gkvl ite.Item) bool {
303 pm, err := rpmWoCtx(i.Val, ns) 298 pm, err := rpmWoCtx(i.Val, ns)
304 if err != nil { 299 if err != nil {
305 panic(err) // memory corruption 300 panic(err) // memory corruption
306 } 301 }
307 » » k, err := ds.ReadKey(bytes.NewBuffer(i.Key), ds.WithoutContext, globalAppID, ns) 302 » » k, err := serialize.ReadKey(bytes.NewBuffer(i.Key), serialize.Wi thoutContext, globalAppID, ns)
308 if err != nil { 303 if err != nil {
309 panic(err) 304 panic(err)
310 } 305 }
311 sip := partiallySerialize(pm) 306 sip := partiallySerialize(pm)
312 mergeIndexes(ns, store, newMemStore(), sip.indexEntries(k, compI dx)) 307 mergeIndexes(ns, store, newMemStore(), sip.indexEntries(k, compI dx))
313 return true 308 return true
314 }) 309 })
315 } 310 }
316 311
317 func updateIndicies(store *memStore, key ds.Key, oldEnt, newEnt ds.PropertyMap) { 312 func updateIndicies(store *memStore, key ds.Key, oldEnt, newEnt ds.PropertyMap) {
318 // load all current complex query index definitions. 313 // load all current complex query index definitions.
319 compIdx := getCompIdxs(getIdxColl(store)) 314 compIdx := getCompIdxs(getIdxColl(store))
320 315
321 mergeIndexes(key.Namespace(), store, 316 mergeIndexes(key.Namespace(), store,
322 indexEntriesWithBuiltins(key, oldEnt, compIdx), 317 indexEntriesWithBuiltins(key, oldEnt, compIdx),
323 indexEntriesWithBuiltins(key, newEnt, compIdx)) 318 indexEntriesWithBuiltins(key, newEnt, compIdx))
324 } 319 }
OLDNEW
« no previous file with comments | « impl/memory/datastore_data.go ('k') | impl/memory/datastore_query.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698