This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.0 by this push:
new 551762d3a25 branch-4.0: [opt](inverted index) add BitmapQuery for
boolean query composition #56408 (#56668)
551762d3a25 is described below
commit 551762d3a25d81d0a16c0c407c88d1f879a06514
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Sep 30 22:20:56 2025 +0800
branch-4.0: [opt](inverted index) add BitmapQuery for boolean query
composition #56408 (#56668)
Cherry-picked from #56408
Co-authored-by: zzzxl <[email protected]>
---
.../query_v2/bitmap_query/bitmap_query.h | 45 +++++++++++
.../query_v2/bitmap_query/bitmap_scorer.h | 83 ++++++++++++++++++++
.../query_v2/bitmap_query/bitmap_weight.h | 46 +++++++++++
.../inverted_index/query_v2/boolean_query_test.cpp | 88 ++++++++++++++++++++++
4 files changed, 262 insertions(+)
diff --git
a/be/src/olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_query.h
b/be/src/olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_query.h
new file mode 100644
index 00000000000..52503a2b979
--- /dev/null
+++
b/be/src/olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_query.h
@@ -0,0 +1,45 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <memory>
+
+#include
"olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_weight.h"
+#include "olap/rowset/segment_v2/inverted_index/query_v2/query.h"
+#include "roaring/roaring.hh"
+
+namespace doris::segment_v2::inverted_index::query_v2 {
+
+class BitmapQuery : public Query {
+public:
+ explicit BitmapQuery(std::shared_ptr<roaring::Roaring> bitmap) :
_bitmap(std::move(bitmap)) {}
+ BitmapQuery(const roaring::Roaring& bitmap)
+ : _bitmap(std::make_shared<roaring::Roaring>(bitmap)) {}
+ ~BitmapQuery() override = default;
+
+ WeightPtr weight(bool /*enable_scoring*/) override {
+ return std::make_shared<BitmapWeight>(_bitmap);
+ }
+
+private:
+ std::shared_ptr<roaring::Roaring> _bitmap;
+};
+
+using BitmapQueryPtr = std::shared_ptr<BitmapQuery>;
+
+} // namespace doris::segment_v2::inverted_index::query_v2
\ No newline at end of file
diff --git
a/be/src/olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_scorer.h
b/be/src/olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_scorer.h
new file mode 100644
index 00000000000..7d510843799
--- /dev/null
+++
b/be/src/olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_scorer.h
@@ -0,0 +1,83 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <algorithm>
+#include <limits>
+#include <memory>
+#include <optional>
+
+#include "olap/rowset/segment_v2/inverted_index/query_v2/scorer.h"
+#include "roaring/roaring.hh"
+
+namespace doris::segment_v2::inverted_index::query_v2 {
+
+class BitmapScorer final : public Scorer {
+public:
+ explicit BitmapScorer(std::shared_ptr<roaring::Roaring> bitmap)
+ : _bitmap(std::move(bitmap)), _it(_bitmap->begin()) {
+ _doc = *_it;
+ }
+ ~BitmapScorer() override = default;
+
+ uint32_t advance() override {
+ if (_doc == TERMINATED) {
+ return TERMINATED;
+ }
+ ++_it;
+ if (!_it.i.has_value) {
+ _doc = TERMINATED;
+ return TERMINATED;
+ }
+ _doc = *_it;
+ return _doc;
+ }
+
+ uint32_t seek(uint32_t target) override {
+ if (_doc == TERMINATED) {
+ return TERMINATED;
+ }
+ if (target <= _doc) {
+ return _doc;
+ }
+ _it.equalorlarger(target);
+ if (!_it.i.has_value) {
+ _doc = TERMINATED;
+ return TERMINATED;
+ }
+ _doc = *_it;
+ return _doc;
+ }
+
+ uint32_t doc() const override { return _doc; }
+
+ uint32_t size_hint() const override {
+ uint64_t card = _bitmap->cardinality();
+ return static_cast<uint32_t>(
+ std::min<uint64_t>(card,
std::numeric_limits<uint32_t>::max()));
+ }
+
+ float score() override { return 1.0F; }
+
+private:
+ std::shared_ptr<roaring::Roaring> _bitmap;
+ roaring::Roaring::const_iterator _it;
+ uint32_t _doc = TERMINATED;
+};
+
+} // namespace doris::segment_v2::inverted_index::query_v2
\ No newline at end of file
diff --git
a/be/src/olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_weight.h
b/be/src/olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_weight.h
new file mode 100644
index 00000000000..276ad072054
--- /dev/null
+++
b/be/src/olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_weight.h
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <memory>
+
+#include
"olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_scorer.h"
+#include "olap/rowset/segment_v2/inverted_index/query_v2/weight.h"
+#include "roaring/roaring.hh"
+
+namespace doris::segment_v2::inverted_index::query_v2 {
+
+class BitmapWeight final : public Weight {
+public:
+ explicit BitmapWeight(std::shared_ptr<roaring::Roaring> bitmap) :
_bitmap(std::move(bitmap)) {}
+ ~BitmapWeight() override = default;
+
+ ScorerPtr scorer(const CompositeReaderPtr& /*composite_reader*/) override {
+ if (_bitmap == nullptr || _bitmap->isEmpty()) {
+ return std::make_shared<EmptyScorer>();
+ }
+ return std::make_shared<BitmapScorer>(_bitmap);
+ }
+
+private:
+ std::shared_ptr<roaring::Roaring> _bitmap;
+};
+
+using BitmapWeightPtr = std::shared_ptr<BitmapWeight>;
+
+} // namespace doris::segment_v2::inverted_index::query_v2
\ No newline at end of file
diff --git
a/be/test/olap/rowset/segment_v2/inverted_index/query_v2/boolean_query_test.cpp
b/be/test/olap/rowset/segment_v2/inverted_index/query_v2/boolean_query_test.cpp
index 5144f5fc72f..3ce5bd11ce1 100644
---
a/be/test/olap/rowset/segment_v2/inverted_index/query_v2/boolean_query_test.cpp
+++
b/be/test/olap/rowset/segment_v2/inverted_index/query_v2/boolean_query_test.cpp
@@ -26,6 +26,7 @@
#include "common/status.h"
#include "olap/rowset/segment_v2/index_query_context.h"
#include "olap/rowset/segment_v2/inverted_index/analyzer/custom_analyzer.h"
+#include
"olap/rowset/segment_v2/inverted_index/query_v2/bitmap_query/bitmap_query.h"
#include "olap/rowset/segment_v2/inverted_index/query_v2/operator.h"
#include
"olap/rowset/segment_v2/inverted_index/query_v2/term_query/term_query.h"
#include "olap/rowset/segment_v2/inverted_index/util/string_helper.h"
@@ -474,4 +475,91 @@ TEST_F(BooleanQueryTest,
test_boolean_query_cross_fields_with_composite_reader)
_CLDECDELETE(dir2);
}
+TEST_F(BooleanQueryTest, test_boolean_query_bitmap_and_term) {
+ std::wstring field = StringHelper::to_wstring("name1");
+
+ auto context = std::make_shared<IndexQueryContext>();
+ context->collection_statistics = std::make_shared<CollectionStatistics>();
+ context->collection_similarity = std::make_shared<CollectionSimilarity>();
+
+ auto* dir = FSDirectory::getDirectory(kTestDir1.c_str());
+ auto* reader = IndexReader::open(dir, true);
+ ASSERT_TRUE(reader != nullptr);
+
+ auto composite_reader = std::make_unique<query_v2::CompositeReader>();
+ composite_reader->set_reader(field, reader);
+
+ roaring::Roaring bm;
+ for (uint32_t d = 0; d < static_cast<uint32_t>(reader->numDocs()); ++d) {
+ if (d % 8 == 0 || d % 8 == 1) {
+ bm.add(d);
+ }
+ }
+
+ query_v2::BooleanQuery::Builder builder(query_v2::OperatorType::OP_AND);
+ builder.add(std::make_shared<query_v2::TermQuery>(context, field,
+
StringHelper::to_wstring("apple")));
+ builder.add(std::make_shared<query_v2::BitmapQuery>(bm));
+ auto q = builder.build();
+
+ auto w = q->weight(false);
+ auto s = w->scorer(composite_reader);
+
+ uint32_t doc = s->doc();
+ uint32_t count = 0;
+ while (doc != query_v2::TERMINATED) {
+ EXPECT_TRUE(doc % 8 == 0 || doc % 8 == 1);
+ ++count;
+ doc = s->advance();
+ }
+ EXPECT_EQ(count, 20);
+
+ reader->close();
+ _CLLDELETE(reader);
+ _CLDECDELETE(dir);
+}
+
+TEST_F(BooleanQueryTest, test_boolean_query_bitmap_or_term) {
+ std::wstring field = StringHelper::to_wstring("name1");
+
+ auto context = std::make_shared<IndexQueryContext>();
+ context->collection_statistics = std::make_shared<CollectionStatistics>();
+ context->collection_similarity = std::make_shared<CollectionSimilarity>();
+
+ auto* dir = FSDirectory::getDirectory(kTestDir1.c_str());
+ auto* reader = IndexReader::open(dir, true);
+ ASSERT_TRUE(reader != nullptr);
+
+ auto composite_reader = std::make_unique<query_v2::CompositeReader>();
+ composite_reader->set_reader(field, reader);
+
+ roaring::Roaring bm;
+ for (uint32_t d = 0; d < static_cast<uint32_t>(reader->numDocs()); ++d) {
+ if (d % 8 == 2 || d % 8 == 3) {
+ bm.add(d);
+ }
+ }
+
+ query_v2::BooleanQuery::Builder builder(query_v2::OperatorType::OP_OR);
+ builder.add(std::make_shared<query_v2::TermQuery>(context, field,
+
StringHelper::to_wstring("apple")));
+ builder.add(std::make_shared<query_v2::BitmapQuery>(bm));
+ auto q = builder.build();
+
+ auto w = q->weight(false);
+ auto s = w->scorer(composite_reader);
+
+ uint32_t doc = s->doc();
+ uint32_t count = 0;
+ while (doc != query_v2::TERMINATED) {
+ ++count;
+ doc = s->advance();
+ }
+ EXPECT_EQ(count, 60);
+
+ reader->close();
+ _CLLDELETE(reader);
+ _CLDECDELETE(dir);
+}
+
} // namespace doris::segment_v2
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]