Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion cmd/seq-db/seq-db.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ func startStore(
DocBlocksZstdLevel: cfg.Compression.DocBlockZstdCompressionLevel,
DocBlockSize: int(cfg.DocsSorting.DocBlockSize),
TokenFreqThresholdPercentage: cfg.Sealing.Tokens.FreqThresholdPercentage,
LIDsBitmapThreshold: cfg.Sealing.Lids.BitmapThreshold,
LIDsBitmapThreshold: cfg.Sealing.Lids.BitmapThreshold,
},
Fraction: frac.Config{
Search: frac.SearchConfig{
Expand All @@ -285,6 +285,12 @@ func startStore(
MaxGroupTokens: cfg.Limits.Aggregation.GroupTokens,
MaxTIDsPerFraction: cfg.Limits.Aggregation.FractionTokens,
},
QueryOptimization: frac.QueryOptimizationConfig{
BatchExecution: frac.BatchExecutionConfig{
Enabled: cfg.QueryOptimization.BatchExecution.Enabled,
CostThreshold: cfg.QueryOptimization.BatchExecution.CostThreshold,
},
},
},
SkipSortDocs: !cfg.DocsSorting.Enabled,
KeepWalFile: false,
Expand Down
9 changes: 9 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,15 @@ type Config struct {
} `config:"aggregation"`
} `config:"limits"`

QueryOptimization struct {
BatchExecution struct {
Enabled bool `config:"enabled"`
// CostThreshold is the minimum estimated non-batched execution cost required to enable batch-at-a-time query
// evaluation. Suggestion is to use value which is greater than 3 x LID block size.
CostThreshold int `config:"cost_threshold" default:"50000"`
} `config:"batch_execution"`
} `config:"query_optimization"`

CircuitBreaker struct {
Bulk struct {
// Checkout [CircuitBreaker] for more information.
Expand Down
20 changes: 19 additions & 1 deletion frac/active_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ func (dp *activeDataProvider) Search(params processor.SearchParams) (*seq.QPR, e
params.To = min(params.To, dp.info.To)

aggLimits := processor.AggLimits(dp.config.Search.AggLimits)
queryOpt := processor.QueryOptimizationConfig{
BatchExecution: processor.BatchExecutionConfig(dp.config.Search.QueryOptimization.BatchExecution),
}

sw := stopwatch.New()

Expand All @@ -132,7 +135,7 @@ func (dp *activeDataProvider) Search(params processor.SearchParams) (*seq.QPR, e
qprs := make([]*seq.QPR, 0, len(indexes))

for _, si := range indexes {
qpr, err := processor.IndexSearch(dp.ctx, params, &si, aggLimits, sw)
qpr, err := processor.IndexSearch(dp.ctx, params, &si, aggLimits, queryOpt, sw)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -248,6 +251,10 @@ func (si *activeTokenIndex) GetTIDsByTokenExpr(t parser.Token) ([]uint32, error)
return si.tokenList.FindPattern(si.ctx, t)
}

func (si *activeTokenIndex) GetFreqsByTIDs(tids []uint32, field string) []uint32 {
return make([]uint32, len(tids))
}

func (si *activeTokenIndex) GetLIDsFromTIDs(tids []uint32, _ lids.Counter, minLID, maxLID uint32, order seq.DocsOrder) []node.Node {
nodes := make([]node.Node, 0, len(tids))
for _, tid := range tids {
Expand All @@ -259,6 +266,17 @@ func (si *activeTokenIndex) GetLIDsFromTIDs(tids []uint32, _ lids.Counter, minLI
return nodes
}

func (si *activeTokenIndex) GetBatchedLIDsFromTIDs(tids []uint32, _ lids.Counter, minLID, maxLID uint32, order seq.DocsOrder) []node.BatchedNode {
nodes := make([]node.BatchedNode, 0, len(tids))
for _, tid := range tids {
tlids := si.tokenList.Provide(tid)
unmapped := tlids.GetLIDs(si.mids, si.rids)
inverse := inverseLIDs(unmapped, si.inverser, minLID, maxLID)
nodes = append(nodes, node.NewStaticBatched(inverse, order.IsReverse()))
}
return nodes
}

func inverseLIDs(unmapped []uint32, inv *inverser, minLID, maxLID uint32) []uint32 {
result := make([]uint32, 0, len(unmapped))
for _, v := range unmapped {
Expand Down
2 changes: 1 addition & 1 deletion frac/common/seal_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type SealParams struct {
DocBlocksZstdLevel int // DocBlocksZstdLevel is the zstd compress level of each document block.

LIDBlockSize int
LIDsBitmapThreshold int // LIDsBitmapThreshold is the minimum number of LIDs in the lid list to serialize as bitmap.
LIDsBitmapThreshold int // LIDsBitmapThreshold is the minimum number of LIDs in the lid list to serialize as bitmap.
TokenBlockSize int
TokenFreqThresholdPercentage float64
DocBlockSize int // DocBlockSize is decompressed payload size of document block.
Expand Down
14 changes: 13 additions & 1 deletion frac/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ type Config struct {
}

type SearchConfig struct {
AggLimits AggLimits
AggLimits AggLimits
QueryOptimization QueryOptimizationConfig
}

type AggLimits struct {
Expand All @@ -17,3 +18,14 @@ type AggLimits struct {
MaxGroupTokens int // MaxGroupTokens max AggQuery.GroupBy unique values.
MaxTIDsPerFraction int // MaxTIDsPerFraction max number of tokens per fraction.
}

type QueryOptimizationConfig struct {
BatchExecution BatchExecutionConfig
}

type BatchExecutionConfig struct {
Enabled bool
// CostThreshold is the minimum estimated non-batched iteration
// cost required to enable batch-at-a-time query evaluation.
CostThreshold int
}
47 changes: 45 additions & 2 deletions frac/fraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ func (s *FractionTestSuite) TearDownSuiteCommon() {

func (s *FractionTestSuite) SetupTestCommon() {
s.config = &frac.Config{}
s.config.Search.QueryOptimization = frac.QueryOptimizationConfig{
BatchExecution: frac.BatchExecutionConfig{
Enabled: true,
CostThreshold: 1000,
},
}
s.tokenizers = map[seq.TokenizerType]tokenizer.Tokenizer{
seq.TokenizerTypeKeyword: tokenizer.NewKeywordTokenizer(20, false, true),
seq.TokenizerTypeText: tokenizer.NewTextTokenizer(20, false, true, 100),
Expand Down Expand Up @@ -1358,7 +1364,7 @@ func (s *FractionTestSuite) TestSearchLargeFrac() {
fromTime: fromTime,
toTime: midTime,
},
// AND operator queries
// AND operator queries (intersection)
{
name: "message:request AND message:failed",
query: "message:request AND message:failed",
Expand All @@ -1368,6 +1374,24 @@ func (s *FractionTestSuite) TestSearchLargeFrac() {
fromTime: fromTime,
toTime: toTime,
},
{
name: "service:gateway AND level:5",
query: "service:gateway AND level:5",
filter: func(doc *testDoc) bool {
return doc.service == gateway && doc.level == 5
},
fromTime: fromTime,
toTime: toTime,
},
{
name: "service:gateway AND level:5 AND message:processing (time range)",
query: "service:gateway AND level:5 AND message:processing",
filter: func(doc *testDoc) bool {
return doc.service == gateway && doc.level == 5 && strings.Contains(doc.message, "processing")
},
fromTime: fromTime,
toTime: midTime,
},
{
name: "service:gateway AND message:processing AND message:retry AND level:5",
query: "service:gateway AND message:processing AND message:retry AND level:5",
Expand Down Expand Up @@ -1417,7 +1441,7 @@ func (s *FractionTestSuite) TestSearchLargeFrac() {
toTime: toTime,
},
{
name: "complex AND+OR",
name: "complex AND+OR 2",
query: "(service:gateway OR service:proxy OR service:scheduler) AND " +
"(message:request OR message:failed) AND (level:1 OR level:2 OR level:3)",
filter: func(doc *testDoc) bool {
Expand All @@ -1428,6 +1452,25 @@ func (s *FractionTestSuite) TestSearchLargeFrac() {
fromTime: fromTime,
toTime: toTime,
},
// AND NOT
{
name: "service:gateway AND NOT message:request",
query: "service:gateway AND NOT message:request",
filter: func(doc *testDoc) bool {
return doc.service == gateway && !strings.Contains(doc.message, "request")
},
fromTime: fromTime,
toTime: midTime,
},
{
name: "service:gateway AND NOT message:request AND NOT level:3",
query: "service:gateway AND NOT message:request AND NOT level:3",
filter: func(doc *testDoc) bool {
return doc.service == gateway && !strings.Contains(doc.message, "request") && doc.level != 3
},
fromTime: fromTime,
toTime: midTime,
},
{
name: "service:gateway AND NOT (message:request OR message:timed OR level:[0 to 3])",
query: "service:gateway AND NOT (message:request OR message:timed OR level:[0 to 3])",
Expand Down
4 changes: 4 additions & 0 deletions frac/processor/aggregator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ func (m *MockTokenIndex) GetValByTID(tid uint32, _ string) []byte {
return []byte(strconv.Itoa(int(tid)))
}

func (m *MockTokenIndex) GetFreqsByTIDs(tids []uint32, _ string) []uint32 {
return make([]uint32, len(tids))
}

type IDSourcePair struct {
LID node.LID
Source uint32
Expand Down
Loading