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 "bytes" | 8 "bytes" |
9 "fmt" | 9 "fmt" |
10 "sort" | 10 "sort" |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 func generate(q *reducedQuery, idx *indexDefinitionSortable, c *constraints) *it
erDefinition { | 310 func generate(q *reducedQuery, idx *indexDefinitionSortable, c *constraints) *it
erDefinition { |
311 def := &iterDefinition{ | 311 def := &iterDefinition{ |
312 c: idx.coll, | 312 c: idx.coll, |
313 start: q.start, | 313 start: q.start, |
314 end: q.end, | 314 end: q.end, |
315 } | 315 } |
316 toJoin := make([][]byte, len(idx.eqFilts)) | 316 toJoin := make([][]byte, len(idx.eqFilts)) |
317 for _, sb := range idx.eqFilts { | 317 for _, sb := range idx.eqFilts { |
318 val := c.peel(sb.Property) | 318 val := c.peel(sb.Property) |
319 if sb.Descending { | 319 if sb.Descending { |
320 » » » val = invert(val) | 320 » » » val = serialize.Invert(val) |
321 } | 321 } |
322 toJoin = append(toJoin, val) | 322 toJoin = append(toJoin, val) |
323 } | 323 } |
324 » def.prefix = bjoin(toJoin...) | 324 » def.prefix = serialize.Join(toJoin...) |
325 def.prefixLen = len(def.prefix) | 325 def.prefixLen = len(def.prefix) |
326 | 326 |
327 if q.eqFilters["__ancestor__"] != nil && !idx.hasAncestor() { | 327 if q.eqFilters["__ancestor__"] != nil && !idx.hasAncestor() { |
328 // The query requires an ancestor, but the index doesn't explici
tly have it | 328 // The query requires an ancestor, but the index doesn't explici
tly have it |
329 // as part of the prefix (otherwise it would have been the first
eqFilt | 329 // as part of the prefix (otherwise it would have been the first
eqFilt |
330 // above). This happens when it's a builtin index, or if it's th
e primary | 330 // above). This happens when it's a builtin index, or if it's th
e primary |
331 // index (for a kindless query), or if it's the Kind index (for
a filterless | 331 // index (for a kindless query), or if it's the Kind index (for
a filterless |
332 // query). | 332 // query). |
333 // | 333 // |
334 // builtin indexes are: | 334 // builtin indexes are: |
(...skipping 12 matching lines...) Expand all Loading... |
347 // Intentionally do NOT update prefixLen. This allows multiItera
tor to | 347 // Intentionally do NOT update prefixLen. This allows multiItera
tor to |
348 // correctly include the entire key in the shared iterator suffi
x, instead | 348 // correctly include the entire key in the shared iterator suffi
x, instead |
349 // of just the remainder. | 349 // of just the remainder. |
350 | 350 |
351 // chop the terminal null byte off the q.ancestor key... we can
accept | 351 // chop the terminal null byte off the q.ancestor key... we can
accept |
352 // anything which is a descendant or an exact match. Removing t
he last byte | 352 // anything which is a descendant or an exact match. Removing t
he last byte |
353 // from the key (the terminating null) allows this trick to work
. Otherwise | 353 // from the key (the terminating null) allows this trick to work
. Otherwise |
354 // it would be a closed range of EXACTLY this key. | 354 // it would be a closed range of EXACTLY this key. |
355 chopped := []byte(anc[:len(anc)-1]) | 355 chopped := []byte(anc[:len(anc)-1]) |
356 if q.suffixFormat[0].Descending { | 356 if q.suffixFormat[0].Descending { |
357 » » » chopped = invert(chopped) | 357 » » » chopped = serialize.Invert(chopped) |
358 } | 358 } |
359 » » def.prefix = bjoin(def.prefix, chopped) | 359 » » def.prefix = serialize.Join(def.prefix, chopped) |
360 | 360 |
361 // Update start and end, since we know that if they contain anyt
hing, they | 361 // Update start and end, since we know that if they contain anyt
hing, they |
362 // contain values for the __key__ field. | 362 // contain values for the __key__ field. |
363 if def.start != nil { | 363 if def.start != nil { |
364 offset := 0 | 364 offset := 0 |
365 if len(q.suffixFormat) > 1 { | 365 if len(q.suffixFormat) > 1 { |
366 chunks, _ := parseSuffix(q.ns, q.suffixFormat, d
ef.start, 1) | 366 chunks, _ := parseSuffix(q.ns, q.suffixFormat, d
ef.start, 1) |
367 offset = len(chunks[0]) | 367 offset = len(chunks[0]) |
368 } | 368 } |
369 if !bytes.HasPrefix(def.start[offset:], chopped) { | 369 if !bytes.HasPrefix(def.start[offset:], chopped) { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 if bestIdx == nil { | 531 if bestIdx == nil { |
532 // something is really wrong here... if relevantIdxs is
!nil, then we | 532 // something is really wrong here... if relevantIdxs is
!nil, then we |
533 // should always be able to make progress in this loop. | 533 // should always be able to make progress in this loop. |
534 impossible(fmt.Errorf("deadlock: cannot fulfil query?")) | 534 impossible(fmt.Errorf("deadlock: cannot fulfil query?")) |
535 } | 535 } |
536 ret = append(ret, generate(q, bestIdx, constraints)) | 536 ret = append(ret, generate(q, bestIdx, constraints)) |
537 } | 537 } |
538 | 538 |
539 return ret, nil | 539 return ret, nil |
540 } | 540 } |
OLD | NEW |