diff --git a/frac/active_index.go b/frac/active_index.go index 9a07fc55..5bf7852b 100644 --- a/frac/active_index.go +++ b/frac/active_index.go @@ -244,6 +244,10 @@ func (si *activeTokenIndex) GetValByTID(tid uint32, field string) []byte { return si.tokenList.GetValByTID(tid, field) } +func (si *activeTokenIndex) GetTIDsByField(field string) ([]uint32, error) { + return si.tokenList.GetTIDsByField(field), nil +} + func (si *activeTokenIndex) GetTIDsByTokenExpr(t parser.Token) ([]uint32, error) { return si.tokenList.FindPattern(si.ctx, t) } diff --git a/frac/processor/eval_tree.go b/frac/processor/eval_tree.go index f9b0e090..2db0ef8c 100644 --- a/frac/processor/eval_tree.go +++ b/frac/processor/eval_tree.go @@ -200,11 +200,13 @@ func iteratorFromLiteral( iteratorLimit iteratorLimit, order seq.DocsOrder, ) (*SourcedNodeIterator, error) { - m := sw.Start("get_tids_by_token_expr") - tids, err := ti.GetTIDsByTokenExpr(literal) + m := sw.Start("get_tids_by_field") + // For aggregations we can receive the first and the last TID for field, + // because we build tree over *all* token values. + tids, err := ti.GetTIDsByField(literal.Field) m.Stop() if err != nil { - return nil, fmt.Errorf("getting TIDs by token expression: %s", err) + return nil, fmt.Errorf("getting TIDs for field %q: %s", literal.Field, err) } if len(tids) > maxTIDs && maxTIDs > 0 { diff --git a/frac/processor/search.go b/frac/processor/search.go index 13e86f9b..866dae3f 100644 --- a/frac/processor/search.go +++ b/frac/processor/search.go @@ -33,6 +33,7 @@ type idsIndex interface { type tokenIndex interface { GetValByTID(tid uint32, field string) []byte + GetTIDsByField(field string) ([]uint32, error) GetTIDsByTokenExpr(token parser.Token) ([]uint32, error) GetLIDsFromTIDs(tids []uint32, stats lids.Counter, minLID, maxLID uint32, order seq.DocsOrder) []node.Node } diff --git a/frac/sealed_index.go b/frac/sealed_index.go index a1e5aca5..cab0efea 100644 --- a/frac/sealed_index.go +++ b/frac/sealed_index.go @@ -237,6 +237,25 @@ func (ti *sealedTokenIndex) GetValByTID(tid uint32, field string) []byte { return nil } +func (ti *sealedTokenIndex) GetTIDsByField(field string) ([]uint32, error) { + table := ti.tokenTableLoader.Load() + + entries := table.SelectEntries(field, "") + if len(entries) == 0 { + return nil, nil + } + + first := entries[0].StartTID + last := entries[len(entries)-1].GetLastTID() + + tids := make([]uint32, (last-first)+1) + for i := range tids { + tids[i] = first + uint32(i) + } + + return tids, nil +} + func (ti *sealedTokenIndex) GetTIDsByTokenExpr(t parser.Token) ([]uint32, error) { field := parser.GetField(t) searchStr := parser.GetHint(t)