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