Skip to content

Commit 61591dd

Browse files
committed
Corrected level merging issue within radix_tree
1 parent 43be98c commit 61591dd

File tree

5 files changed

+937
-12
lines changed

5 files changed

+937
-12
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 3.16)
22

33
project(seq
4-
VERSION 2.0
4+
VERSION 2.1
55
DESCRIPTION "Collection of C++17 original containers"
66
HOMEPAGE_URL "https://github.com/Thermadiag/seq"
77
LANGUAGES CXX

docs/algorithm.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
- `seq::unique`: removed duplicates from a range in a stable way. This is very similar to `std::unique` except that the range does not need to be sorted. It uses a hash table under the hood to find duplicate values. A custom hash function and comparison function can be passed for custom types.
1717

1818
- `seq::net_sort` and `seq::net_sort_size`: "new" generic stable sorting algorithm that is used everywhere within the seq library. `seq::net_sort` is a merge sort algorithm with the following specificities:
19-
- Bottom-up merging instead of the more traditional top-down approach,
20-
- Small blocks of 8 elements are sorted using a sorting network,
21-
- Bidirectional merging is used for relocatable types,
22-
- Ping-pong merge is used to merge 4 sorted ranges,
23-
- Can work without allocating memory through a (potentially null) user provided buffer,
24-
- Also works on bidirectional iterators.
19+
- Bottom-up merging instead of the more traditional top-down approach,
20+
- Small blocks of 8 elements are sorted using a sorting network,
21+
- Bidirectional merging is used for relocatable types,
22+
- Ping-pong merge is used to merge 4 sorted ranges,
23+
- Can work without allocating memory through a (potentially null) user provided buffer,
24+
- Also works on bidirectional iterators.
2525

2626
If provided buffer is one of `seq::default_buffer`, `seq::medium_buffer`, `seq::small_buffer` or `seq::tiny_buffer`, this function will try to allocate memory.
2727

seq/internal/radix_tree.hpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,15 +2128,19 @@ namespace seq
21282128
directory* new_dir = directory::make(d_data->base, new_hash_len);
21292129
// copy prefix length
21302130
new_dir->prefix_len = dir->prefix_len;
2131+
// set parent, used by iterator::get_bit_pos
2132+
new_dir->parent = parent_dir;
21312133

21322134
try {
21332135
for (unsigned i = 0; i < size; ++i) {
21342136
directory* child = static_cast<directory*>(dir->children()[i].ptr());
21352137
unsigned child_count = child->size();
21362138

21372139
if (prefix_search && child->prefix_len >= start_arity) {
2138-
// keep this directory and remove max_hash_len to the prefix.
2139-
unsigned loc = (i << start_arity) | (get_prefix_first_bits(child, start_arity, bit_pos));
2140+
// keep this directory and remove start_arity to the prefix.
2141+
size_t dir_pos = iterator::get_bit_pos(new_dir);
2142+
unsigned loc = hash_key(child->any_child()).n_bits(dir_pos, new_hash_len);
2143+
21402144
child->prefix_len -= start_arity;
21412145
new_dir->child(loc) = dir->const_child(i);
21422146
new_dir->child_count++;
@@ -2148,7 +2152,7 @@ namespace seq
21482152
}
21492153

21502154
if (child->hash_len != start_arity) {
2151-
// if child has more than min_hash_len bits
2155+
// if child has more than start_arity bits
21522156
unsigned rem_bits = child->hash_len - start_arity;
21532157
unsigned mask = ((1U << rem_bits) - 1U);
21542158

@@ -2211,6 +2215,9 @@ namespace seq
22112215
throw;
22122216
}
22132217

2218+
// reset parent
2219+
new_dir->parent = nullptr;
2220+
22142221
// destroy old directory
22152222
directory::destroy(d_data->base, dir, false);
22162223

@@ -2973,7 +2980,7 @@ namespace seq
29732980
}
29742981

29752982
/// @brief Check if given hash value share the same prefix as d
2976-
//SEQ_ALWAYS_INLINE bool check_prefix(const hash_type& hash, const directory* d) const noexcept { return check_prefix(hash, hash_key(d->any_child()), d->prefix_len); }
2983+
// SEQ_ALWAYS_INLINE bool check_prefix(const hash_type& hash, const directory* d) const noexcept { return check_prefix(hash, hash_key(d->any_child()), d->prefix_len); }
29772984

29782985
/// @brief Find key in vector node
29792986
template<class U>
@@ -3062,7 +3069,7 @@ namespace seq
30623069

30633070
// check directory prefix
30643071
if (prefix_search && d->prefix_len) {
3065-
if (!check_prefix(hash, bit_pos, d))
3072+
if (!check_prefix(hash, bit_pos, d))
30663073
return nullptr;
30673074
else
30683075
bit_pos += d->prefix_len;

0 commit comments

Comments
 (0)