mirror of
https://github.com/typesense/typesense.git
synced 2025-05-23 15:23:40 +08:00
Add NumericTrie::remove
.
This commit is contained in:
parent
a901240979
commit
7efa690810
@ -41,9 +41,11 @@ class NumericTrie {
|
||||
|
||||
void insert(const int64_t& cell_id, const uint32_t& seq_id, const char& max_level);
|
||||
|
||||
void remove(const int64_t& cell_id, const uint32_t& seq_id, const char& max_level);
|
||||
|
||||
void insert_geopoint(const uint64_t& cell_id, const uint32_t& seq_id, const char& max_level);
|
||||
|
||||
void search_geopoints(const std::vector<uint64_t>& cell_ids, const char& max_index_level,
|
||||
void search_geopoints(const std::vector<uint64_t>& cell_ids, const char& max_level,
|
||||
std::vector<uint32_t>& geo_result_ids);
|
||||
|
||||
void delete_geopoint(const uint64_t& cell_id, uint32_t id, const char& max_level);
|
||||
@ -121,6 +123,8 @@ public:
|
||||
|
||||
void insert(const int64_t& value, const uint32_t& seq_id);
|
||||
|
||||
void remove(const int64_t& value, const uint32_t& seq_id);
|
||||
|
||||
void insert_geopoint(const uint64_t& cell_id, const uint32_t& seq_id);
|
||||
|
||||
void search_geopoints(const std::vector<uint64_t>& cell_ids, std::vector<uint32_t>& geo_result_ids);
|
||||
|
@ -5423,6 +5423,11 @@ void Index::remove_field(uint32_t seq_id, const nlohmann::json& document, const
|
||||
std::vector<int32_t>{document[field_name].get<int32_t>()} :
|
||||
document[field_name].get<std::vector<int32_t>>();
|
||||
for(int32_t value: values) {
|
||||
if (search_field.range_index) {
|
||||
auto const& trie = range_index.at(search_field.name);
|
||||
trie->remove(value, seq_id);
|
||||
}
|
||||
|
||||
num_tree_t* num_tree = numerical_index.at(field_name);
|
||||
num_tree->remove(value, seq_id);
|
||||
if(search_field.facet) {
|
||||
@ -5434,6 +5439,11 @@ void Index::remove_field(uint32_t seq_id, const nlohmann::json& document, const
|
||||
std::vector<int64_t>{document[field_name].get<int64_t>()} :
|
||||
document[field_name].get<std::vector<int64_t>>();
|
||||
for(int64_t value: values) {
|
||||
if (search_field.range_index) {
|
||||
auto const& trie = range_index.at(search_field.name);
|
||||
trie->remove(value, seq_id);
|
||||
}
|
||||
|
||||
num_tree_t* num_tree = numerical_index.at(field_name);
|
||||
num_tree->remove(value, seq_id);
|
||||
if(search_field.facet) {
|
||||
@ -5448,8 +5458,14 @@ void Index::remove_field(uint32_t seq_id, const nlohmann::json& document, const
|
||||
document[field_name].get<std::vector<float>>();
|
||||
|
||||
for(float value: values) {
|
||||
num_tree_t* num_tree = numerical_index.at(field_name);
|
||||
int64_t fintval = float_to_int64_t(value);
|
||||
|
||||
if (search_field.range_index) {
|
||||
auto const& trie = range_index.at(search_field.name);
|
||||
trie->remove(fintval, seq_id);
|
||||
}
|
||||
|
||||
num_tree_t* num_tree = numerical_index.at(field_name);
|
||||
num_tree->remove(fintval, seq_id);
|
||||
if(search_field.facet) {
|
||||
remove_facet_token(search_field, search_index, StringUtils::float_to_str(value), seq_id);
|
||||
@ -5641,6 +5657,10 @@ void Index::refresh_schemas(const std::vector<field>& new_fields, const std::vec
|
||||
} else {
|
||||
num_tree_t* num_tree = new num_tree_t;
|
||||
numerical_index.emplace(new_field.name, num_tree);
|
||||
|
||||
if (new_field.range_index) {
|
||||
range_index.emplace(new_field.name, new NumericTrie(new_field.is_int32() ? 32 : 64));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5697,6 +5717,11 @@ void Index::refresh_schemas(const std::vector<field>& new_fields, const std::vec
|
||||
} else {
|
||||
delete numerical_index[del_field.name];
|
||||
numerical_index.erase(del_field.name);
|
||||
|
||||
if (del_field.range_index) {
|
||||
delete range_index[del_field.name];
|
||||
range_index.erase(del_field.name);
|
||||
}
|
||||
}
|
||||
|
||||
if(del_field.is_sortable()) {
|
||||
|
@ -19,6 +19,18 @@ void NumericTrie::insert(const int64_t& value, const uint32_t& seq_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void NumericTrie::remove(const int64_t& value, const uint32_t& seq_id) {
|
||||
if ((value < 0 && negative_trie == nullptr) || (value >= 0 && positive_trie == nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
negative_trie->remove(std::abs(value), seq_id, max_level);
|
||||
} else {
|
||||
positive_trie->remove(value, seq_id, max_level);
|
||||
}
|
||||
}
|
||||
|
||||
void NumericTrie::insert_geopoint(const uint64_t& cell_id, const uint32_t& seq_id) {
|
||||
if (positive_trie == nullptr) {
|
||||
positive_trie = new NumericTrie::Node();
|
||||
@ -420,6 +432,34 @@ inline int get_geopoint_index(const uint64_t& cell_id, const char& level) {
|
||||
return (cell_id >> (8 * (8 - level))) & 0xFF;
|
||||
}
|
||||
|
||||
void NumericTrie::Node::remove(const int64_t& value, const uint32_t& id, const char& max_level) {
|
||||
char level = 1;
|
||||
Node* root = this;
|
||||
auto index = get_index(value, level, max_level);
|
||||
|
||||
while (level < max_level) {
|
||||
root->seq_ids.remove_value(id);
|
||||
|
||||
if (root->children == nullptr || root->children[index] == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
root = root->children[index];
|
||||
index = get_index(value, ++level, max_level);
|
||||
}
|
||||
|
||||
root->seq_ids.remove_value(id);
|
||||
if (root->children != nullptr && root->children[index] != nullptr) {
|
||||
auto& child = root->children[index];
|
||||
|
||||
child->seq_ids.remove_value(id);
|
||||
if (child->seq_ids.getLength() == 0) {
|
||||
delete child;
|
||||
child = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NumericTrie::Node::insert_helper(const int64_t& value, const uint32_t& seq_id, char& level, const char& max_level) {
|
||||
if (level > max_level) {
|
||||
return;
|
||||
@ -501,11 +541,11 @@ void NumericTrie::Node::search_geopoints_helper(const uint64_t& cell_id, const c
|
||||
matches.insert(root);
|
||||
}
|
||||
|
||||
void NumericTrie::Node::search_geopoints(const std::vector<uint64_t>& cell_ids, const char& max_index_level,
|
||||
void NumericTrie::Node::search_geopoints(const std::vector<uint64_t>& cell_ids, const char& max_level,
|
||||
std::vector<uint32_t>& geo_result_ids) {
|
||||
std::set<Node*> matches;
|
||||
for (const auto &cell_id: cell_ids) {
|
||||
search_geopoints_helper(cell_id, max_index_level, matches);
|
||||
search_geopoints_helper(cell_id, max_level, matches);
|
||||
}
|
||||
|
||||
for (auto const& match: matches) {
|
||||
@ -538,9 +578,14 @@ void NumericTrie::Node::delete_geopoint(const uint64_t& cell_id, uint32_t id, co
|
||||
}
|
||||
|
||||
root->seq_ids.remove_value(id);
|
||||
if (root->children != nullptr || root->children[index] != nullptr) {
|
||||
delete root->children[index];
|
||||
root->children[index] = nullptr;
|
||||
if (root->children != nullptr && root->children[index] != nullptr) {
|
||||
auto& child = root->children[index];
|
||||
|
||||
child->seq_ids.remove_value(id);
|
||||
if (child->seq_ids.getLength() == 0) {
|
||||
delete child;
|
||||
child = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -601,6 +601,75 @@ TEST_F(NumericRangeTrieTest, MultivalueData) {
|
||||
reset(ids, ids_length);
|
||||
}
|
||||
|
||||
TEST_F(NumericRangeTrieTest, Remove) {
|
||||
auto trie = new NumericTrie();
|
||||
std::unique_ptr<NumericTrie> trie_guard(trie);
|
||||
std::vector<std::pair<int32_t, uint32_t>> pairs = {
|
||||
{-0x202020, 32},
|
||||
{-32768, 5},
|
||||
{-32768, 8},
|
||||
{-24576, 32},
|
||||
{-16384, 35},
|
||||
{-8192, 43},
|
||||
{0, 2},
|
||||
{0, 49},
|
||||
{1, 8},
|
||||
{256, 91},
|
||||
{8192, 49},
|
||||
{16384, 56},
|
||||
{24576, 58},
|
||||
{32768, 91},
|
||||
{0x202020, 35},
|
||||
};
|
||||
|
||||
for (auto const& pair: pairs) {
|
||||
trie->insert(pair.first, pair.second);
|
||||
}
|
||||
|
||||
uint32_t* ids = nullptr;
|
||||
uint32_t ids_length = 0;
|
||||
|
||||
trie->search_less_than(0, false, ids, ids_length);
|
||||
|
||||
std::vector<uint32_t> expected = {5, 8, 32, 35, 43};
|
||||
|
||||
ASSERT_EQ(5, ids_length);
|
||||
for (uint32_t i = 0; i < ids_length; i++) {
|
||||
ASSERT_EQ(expected[i], ids[i]);
|
||||
}
|
||||
|
||||
trie->remove(-24576, 32);
|
||||
trie->remove(-0x202020, 32);
|
||||
|
||||
reset(ids, ids_length);
|
||||
trie->search_less_than(0, false, ids, ids_length);
|
||||
|
||||
expected = {5, 8, 35, 43};
|
||||
ASSERT_EQ(4, ids_length);
|
||||
for (uint32_t i = 0; i < ids_length; i++) {
|
||||
ASSERT_EQ(expected[i], ids[i]);
|
||||
}
|
||||
|
||||
reset(ids, ids_length);
|
||||
trie->search_equal_to(0, ids, ids_length);
|
||||
|
||||
expected = {2, 49};
|
||||
ASSERT_EQ(2, ids_length);
|
||||
for (uint32_t i = 0; i < ids_length; i++) {
|
||||
ASSERT_EQ(expected[i], ids[i]);
|
||||
}
|
||||
|
||||
trie->remove(0, 2);
|
||||
|
||||
reset(ids, ids_length);
|
||||
trie->search_equal_to(0, ids, ids_length);
|
||||
|
||||
ASSERT_EQ(1, ids_length);
|
||||
ASSERT_EQ(49, ids[0]);
|
||||
|
||||
reset(ids, ids_length);
|
||||
}
|
||||
|
||||
TEST_F(NumericRangeTrieTest, EmptyTrieOperations) {
|
||||
auto trie = new NumericTrie();
|
||||
std::unique_ptr<NumericTrie> trie_guard(trie);
|
||||
@ -657,6 +726,9 @@ TEST_F(NumericRangeTrieTest, EmptyTrieOperations) {
|
||||
ids_guard.reset(ids);
|
||||
|
||||
ASSERT_EQ(0, ids_length);
|
||||
|
||||
trie->remove(15, 0);
|
||||
trie->remove(-15, 0);
|
||||
}
|
||||
|
||||
TEST_F(NumericRangeTrieTest, Integration) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user