intersectBucket intersects every UID list in the UID matrix with the indexed bucket.
(ctx context.Context, ts *pb.SortMessage, token string, out []intersectedList)
| 605 | // intersectBucket intersects every UID list in the UID matrix with the |
| 606 | // indexed bucket. |
| 607 | func intersectBucket(ctx context.Context, ts *pb.SortMessage, token string, |
| 608 | out []intersectedList) error { |
| 609 | count := int(ts.Count) |
| 610 | order := ts.Order[0] |
| 611 | sType, err := schema.State().TypeOf(order.Attr) |
| 612 | if err != nil || !sType.IsScalar() { |
| 613 | return errors.Errorf("Cannot sort attribute %s of type object.", order.Attr) |
| 614 | } |
| 615 | scalar := sType |
| 616 | |
| 617 | key := x.IndexKey(order.Attr, token) |
| 618 | // Don't put the Index keys in memory. |
| 619 | pl, err := posting.GetNoStore(key, ts.GetReadTs()) |
| 620 | if err != nil { |
| 621 | return err |
| 622 | } |
| 623 | var vals []types.Val |
| 624 | |
| 625 | // For each UID list, we need to intersect with the index bucket. |
| 626 | for i, ul := range ts.UidMatrix { |
| 627 | il := &out[i] |
| 628 | // We need to reduce multiSortOffset while checking the count as we might have included |
| 629 | // some extra uids from the bucket that the offset falls into. We are going to discard |
| 630 | // the first multiSortOffset number of uids later after all sorts are applied. |
| 631 | if count > 0 && len(il.ulist.Uids)-int(il.multiSortOffset) >= count { |
| 632 | continue |
| 633 | } |
| 634 | |
| 635 | // Intersect index with i-th input UID list. |
| 636 | listOpt := posting.ListOptions{ |
| 637 | Intersect: ul, |
| 638 | ReadTs: ts.ReadTs, |
| 639 | First: 0, // TODO: Should we set the first N here? |
| 640 | } |
| 641 | result, err := pl.Uids(listOpt) // The actual intersection work is done here. |
| 642 | if err != nil { |
| 643 | return err |
| 644 | } |
| 645 | |
| 646 | // Duplicates will exist between buckets if there are multiple language |
| 647 | // variants of a predicate. |
| 648 | result.Uids = removeDuplicates(result.Uids, il.uset) |
| 649 | |
| 650 | // Check offsets[i]. |
| 651 | n := len(result.Uids) |
| 652 | if il.offset >= n { |
| 653 | // We are going to skip the whole intersection. No need to do actual |
| 654 | // sorting. Just update offsets[i]. We now offset less. Also, keep track of the UIDs |
| 655 | // that have been skipped for the offset. |
| 656 | il.offset -= n |
| 657 | il.skippedUids.Uids = append(il.skippedUids.Uids, result.Uids...) |
| 658 | continue |
| 659 | } |
| 660 | |
| 661 | // We are within the page. We need to apply sorting. |
| 662 | // Sort results by value before applying offset. |
| 663 | // TODO (pawan) - Why do we do this? Looks like it is only useful for language. |
| 664 | if vals, err = sortByValue(ctx, ts, result, scalar); err != nil { |
no test coverage detected