There was an error while loading. Please reload this page.
1 parent 4f4e7aa commit eac19c8Copy full SHA for eac19c8
4 files changed
src/core/search/range_tree.cc
@@ -76,7 +76,10 @@ template <typename MapT> auto FindRangeBlockImpl(MapT& entries, double value) {
76
} // namespace
77
78
RangeTree::RangeTree(PMR_NS::memory_resource* mr, size_t max_range_block_size)
79
- : max_range_block_size_(max_range_block_size), entries_(mr) {
+ // A zero block size is used as a divisor in Builder::Populate; fall back to the default.
80
+ : max_range_block_size_(max_range_block_size ? max_range_block_size
81
+ : kDefaultMaxRangeBlockSize),
82
+ entries_(mr) {
83
// The tree has at least always a block with a negative infinity bound, so that any new insertion
84
// goes at least somewhere
85
CreateEmptyBlock(-std::numeric_limits<double>::infinity());
src/core/search/range_tree_test.cc
@@ -628,6 +628,24 @@ TEST_F(RangeTreeTest, DiscreteIntialization) {
628
EXPECT_EQ(result.size(), 4u);
629
}
630
631
+TEST_F(BuilderTest, ZeroBlockSizeDoesNotDivideByZero) {
632
+ RangeTree tree{PMR_NS::get_default_resource(), 0};
633
+ RangeTree::Builder builder;
634
+
635
+ std::vector<RangeTree::Entry> entries;
636
+ entries.reserve(20);
637
+ for (size_t i = 0; i < 20; i++)
638
+ entries.emplace_back(i, double(i));
639
+ for (auto [id, v] : entries)
640
+ builder.Add(id, v);
641
642
+ builder.Populate(&tree, RenewableQuota::Unlimited());
643
644
+ rng::sort(entries, {}, &RangeTree::Entry::first);
645
+ auto all_values = tree.Range(-1000, +1000);
646
+ EXPECT_TRUE(rng::equal(all_values.Take(), entries | std::views::keys));
647
+}
648
649
// Benchmark tree insertion performance with set of discrete values
650
static void BM_DiscreteInsertion(benchmark::State& state) {
651
RangeTree tree{PMR_NS::get_default_resource()};
src/server/search/search_family.cc
@@ -204,7 +204,10 @@ constexpr auto kTextParamsGrammar =
204
205
search::SchemaField::NumericParams ParseNumericParams(CmdArgParser* parser) {
206
search::SchemaField::NumericParams params{};
207
- parser->Check("BLOCKSIZE", ¶ms.block_size);
+ // A zero block size divides by zero when the numeric range tree is built.
208
+ if (parser->Check("BLOCKSIZE"))
209
+ params.block_size =
210
+ parser->Next<facade::Positive<size_t>>("BLOCKSIZE must be a positive integer");
211
return params;
212
213
src/server/search/search_family_test.cc
@@ -4074,6 +4074,18 @@ TEST_F(SearchFamilyTest, BlockSizeOptionFtCreate) {
4074
EXPECT_THAT(resp, AreDocIds("doc:1", "doc:2", "doc:3"));
4075
4076
4077
+TEST_F(SearchFamilyTest, BlockSizeZeroRejected) {
4078
+ Run({"HSET", "doc:a", "n", "7"});
4079
4080
+ EXPECT_THAT(Run({"FT.CREATE", "idx0", "ON", "HASH", "PREFIX", "1", "doc:", "SCHEMA", "n",
4081
+ "NUMERIC", "BLOCKSIZE", "0"}),
4082
+ ErrArg("BLOCKSIZE"));
4083
4084
+ EXPECT_THAT(Run({"FT.CREATE", "idx1", "ON", "HASH", "PREFIX", "1", "doc:", "SCHEMA", "n",
4085
+ "NUMERIC", "BLOCKSIZE", "1"}),
4086
+ "OK");
4087
4088
4089
TEST_F(SearchFamilyTest, AggregateWithLoadFromJoinSimple) {
4090
Run({"ft.create", "idx1", "ON", "HASH", "SCHEMA", "num1", "NUMERIC", "num2", "NUMERIC"});
4091
Run({"ft.create", "idx2", "ON", "HASH", "SCHEMA", "num3", "NUMERIC", "num4", "NUMERIC"});
0 commit comments