From cc3b264adaebed12af8c74d1a25808cafb6bea02 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 24 Feb 2025 13:19:08 +0300 Subject: [PATCH] node/metabase: Interrupt search by primary filter faster Primary filters are applied to sorted meta bucket's elements. This allows us to speed up execution when we reached mismatch at some point: - for EQ/PREFIX/LT/LE/GE matchers, any next item will definitely fail; - for GT matcher, any next item will definitely fail if some previous element matched. Now the meta bucket iterator breaks when the mentioned conditions are reached. This speeds up the processing of most search queries, especially as the number of objects increases. Refs #3058. Signed-off-by: Leonard Lyubich --- pkg/local_object_storage/metabase/metadata.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/local_object_storage/metabase/metadata.go b/pkg/local_object_storage/metabase/metadata.go index b55ace7936..857248302e 100644 --- a/pkg/local_object_storage/metabase/metadata.go +++ b/pkg/local_object_storage/metabase/metadata.go @@ -434,6 +434,7 @@ func (db *DB) searchTx(tx *bbolt.Tx, cnr cid.ID, fs object.SearchFilters, fInt m var more bool var id, dbVal, primDBVal []byte var keyBuf keyBuffer + var wasPrimMatch bool attrSkr := &metaAttributeSeeker{keyBuf: &keyBuf, bkt: metaBkt} curEpoch := db.epochState.CurrentEpoch() dbValInt := new(big.Int) @@ -476,8 +477,12 @@ nextPrimKey: matches = matchValues(checkedDBVal, mch, fltVal) } if !matches { + if mch != object.MatchStringNotEqual && (wasPrimMatch || mch != object.MatchNumGT) { + break nextPrimKey + } continue nextPrimKey } + wasPrimMatch = true // TODO: attribute value can be requested, it can be collected here, or we can // detect earlier when an object goes beyond the already collected result. The // code can become even more complex. Same below