/src/immer/immer/detail/hamts/champ.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // immer: immutable data structures for C++ |
3 | | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente |
4 | | // |
5 | | // This software is distributed under the Boost Software License, Version 1.0. |
6 | | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt |
7 | | // |
8 | | |
9 | | #pragma once |
10 | | |
11 | | #include <immer/config.hpp> |
12 | | #include <immer/detail/hamts/node.hpp> |
13 | | |
14 | | #include <algorithm> |
15 | | |
16 | | namespace immer { |
17 | | namespace detail { |
18 | | namespace hamts { |
19 | | |
20 | | #if IMMER_DEBUG_STATS |
21 | | struct champ_debug_stats |
22 | | { |
23 | | std::size_t bits = {}; |
24 | | std::size_t value_size = {}; |
25 | | std::size_t child_size = sizeof(void*); |
26 | | |
27 | | std::size_t inner_node_count = {}; |
28 | | std::size_t inner_node_w_value_count = {}; |
29 | | std::size_t inner_node_w_child_count = {}; |
30 | | std::size_t collision_node_count = {}; |
31 | | |
32 | | std::size_t child_count = {}; |
33 | | std::size_t value_count = {}; |
34 | | std::size_t collision_count = {}; |
35 | | |
36 | | friend champ_debug_stats operator+(champ_debug_stats a, champ_debug_stats b) |
37 | | { |
38 | | if (a.bits != b.bits || a.value_size != b.value_size || |
39 | | a.child_size != b.child_size) |
40 | | throw std::runtime_error{"accumulating incompatible stats"}; |
41 | | return { |
42 | | a.bits, |
43 | | a.value_size, |
44 | | a.child_size, |
45 | | a.inner_node_count + b.inner_node_count, |
46 | | a.inner_node_w_value_count + b.inner_node_w_value_count, |
47 | | a.inner_node_w_child_count + b.inner_node_w_child_count, |
48 | | a.collision_node_count + b.collision_node_count, |
49 | | a.child_count + b.child_count, |
50 | | a.value_count + b.value_count, |
51 | | a.collision_count + b.collision_count, |
52 | | }; |
53 | | } |
54 | | |
55 | | struct summary |
56 | | { |
57 | | double collision_ratio; |
58 | | |
59 | | double utilization; |
60 | | double child_utilization; |
61 | | double value_utilization; |
62 | | |
63 | | double dense_utilization; |
64 | | double dense_value_utilization; |
65 | | double dense_child_utilization; |
66 | | |
67 | | friend std::ostream& operator<<(std::ostream& os, const summary& s) |
68 | | { |
69 | | os << "---\n"; |
70 | | os << "collisions\n" |
71 | | << " ratio = " << s.collision_ratio << " %\n"; |
72 | | os << "utilization\n" |
73 | | << " total = " << s.utilization << " %\n" |
74 | | << " children = " << s.child_utilization << " %\n" |
75 | | << " values = " << s.value_utilization << " %\n"; |
76 | | os << "utilization (dense)\n" |
77 | | << " total = " << s.dense_utilization << " %\n" |
78 | | << " children = " << s.dense_child_utilization << " %\n" |
79 | | << " values = " << s.dense_value_utilization << " %\n"; |
80 | | return os; |
81 | | } |
82 | | }; |
83 | | |
84 | | summary get_summary() const |
85 | | { |
86 | | auto m = std::size_t{1} << bits; |
87 | | |
88 | | auto collision_ratio = 100. * collision_count / value_count; |
89 | | |
90 | | auto capacity = m * inner_node_count; |
91 | | auto child_utilization = 100. * child_count / capacity; |
92 | | auto value_utilization = 100. * value_count / capacity; |
93 | | auto utilization = |
94 | | 100. * (value_count * value_size + child_count * child_size) / |
95 | | (capacity * value_size + capacity * child_size); |
96 | | |
97 | | auto value_capacity = m * inner_node_w_value_count; |
98 | | auto child_capacity = m * inner_node_w_child_count; |
99 | | auto dense_child_utilization = |
100 | | child_capacity == 0 ? 100. : 100. * child_count / child_capacity; |
101 | | auto dense_value_utilization = |
102 | | value_capacity == 0 ? 100. : 100. * value_count / value_capacity; |
103 | | auto dense_utilization = |
104 | | value_capacity + child_capacity == 0 |
105 | | ? 100. |
106 | | : 100. * (value_count * value_size + child_count * child_size) / |
107 | | (value_capacity * value_size + |
108 | | child_capacity * child_size); |
109 | | |
110 | | return {collision_ratio, |
111 | | utilization, |
112 | | child_utilization, |
113 | | value_utilization, |
114 | | dense_utilization, |
115 | | dense_value_utilization, |
116 | | dense_child_utilization}; |
117 | | } |
118 | | }; |
119 | | #endif |
120 | | |
121 | | template <typename T, |
122 | | typename Hash, |
123 | | typename Equal, |
124 | | typename MemoryPolicy, |
125 | | bits_t B> |
126 | | struct champ |
127 | | { |
128 | | static constexpr auto bits = B; |
129 | | |
130 | | using node_t = node<T, Hash, Equal, MemoryPolicy, B>; |
131 | | using edit_t = typename MemoryPolicy::transience_t::edit; |
132 | | using owner_t = typename MemoryPolicy::transience_t::owner; |
133 | | using bitmap_t = typename get_bitmap_type<B>::type; |
134 | | |
135 | | static_assert(branches<B> <= sizeof(bitmap_t) * 8, ""); |
136 | | |
137 | | node_t* root; |
138 | | size_t size; |
139 | | |
140 | | static node_t* empty() |
141 | 940k | { |
142 | 940k | static const auto node = node_t::make_inner_n(0); |
143 | 940k | return node->inc(); |
144 | 940k | } |
145 | | |
146 | | champ(node_t* r, size_t sz = 0) |
147 | | : root{r} |
148 | | , size{sz} |
149 | 1.87M | {} |
150 | | |
151 | | champ(const champ& other) |
152 | | : champ{other.root, other.size} |
153 | 27.7k | { |
154 | 27.7k | inc(); |
155 | 27.7k | } |
156 | | |
157 | | champ(champ&& other) |
158 | | : champ{empty()} |
159 | 924k | { |
160 | 924k | swap(*this, other); |
161 | 924k | } |
162 | | |
163 | | champ& operator=(const champ& other) |
164 | | { |
165 | | auto next = other; |
166 | | swap(*this, next); |
167 | | return *this; |
168 | | } |
169 | | |
170 | | champ& operator=(champ&& other) |
171 | 1.03M | { |
172 | 1.03M | swap(*this, other); |
173 | 1.03M | return *this; |
174 | 1.03M | } |
175 | | |
176 | | friend void swap(champ& x, champ& y) |
177 | 1.96M | { |
178 | 1.96M | using std::swap; |
179 | 1.96M | swap(x.root, y.root); |
180 | 1.96M | swap(x.size, y.size); |
181 | 1.96M | } |
182 | | |
183 | 1.87M | ~champ() { dec(); } |
184 | | |
185 | 27.7k | void inc() const { root->inc(); } |
186 | | |
187 | | void dec() const |
188 | 1.87M | { |
189 | 1.87M | if (root->dec()) |
190 | 918k | node_t::delete_deep(root, 0); |
191 | 1.87M | } |
192 | | |
193 | | std::size_t do_check_champ(node_t* node, |
194 | | count_t depth, |
195 | | size_t path_hash, |
196 | | size_t hash_mask) const |
197 | 17.2M | { |
198 | 17.2M | auto result = std::size_t{}; |
199 | 17.2M | if (depth < max_depth<B>) { |
200 | 17.1M | auto nodemap = node->nodemap(); |
201 | 17.1M | if (nodemap) { |
202 | 11.4M | auto fst = node->children(); |
203 | 102M | for (auto idx = std::size_t{}; idx < branches<B>; ++idx) { |
204 | 91.4M | if (nodemap & (1 << idx)) { |
205 | 16.8M | auto child = *fst++; |
206 | 16.8M | result += |
207 | 16.8M | do_check_champ(child, |
208 | 16.8M | depth + 1, |
209 | 16.8M | path_hash | (idx << (B * depth)), |
210 | 16.8M | (hash_mask << B) | mask<B>); |
211 | 16.8M | } |
212 | 91.4M | } |
213 | 11.4M | } |
214 | 17.1M | auto datamap = node->datamap(); |
215 | 17.1M | if (datamap) { |
216 | 8.73M | auto fst = node->values(); |
217 | 78.5M | for (auto idx = std::size_t{}; idx < branches<B>; ++idx) { |
218 | 69.8M | if (datamap & (1 << idx)) { |
219 | 20.6M | auto hash = Hash{}(*fst++); |
220 | 20.6M | auto check = (hash & hash_mask) == |
221 | 20.6M | (path_hash | (idx << (B * depth))); |
222 | | // assert(check); |
223 | 20.6M | result += !!check; |
224 | 20.6M | } |
225 | 69.8M | } |
226 | 8.73M | } |
227 | 17.1M | } else { |
228 | 158k | auto fst = node->collisions(); |
229 | 158k | auto lst = fst + node->collision_count(); |
230 | 516k | for (; fst != lst; ++fst) { |
231 | 357k | auto hash = Hash{}(*fst); |
232 | 357k | auto check = hash == path_hash; |
233 | | // assert(check); |
234 | 357k | result += !!check; |
235 | 357k | } |
236 | 158k | } |
237 | 17.2M | return result; |
238 | 17.2M | } |
239 | | |
240 | | // Checks that the hashes of the values correspond with what has actually |
241 | | // been inserted. If it doesn't it can mean that corruption has happened |
242 | | // due some value being moved out of the champ when it should have not. |
243 | | bool check_champ() const |
244 | 467k | { |
245 | 467k | auto r = do_check_champ(root, 0, 0, mask<B>); |
246 | | // assert(r == size); |
247 | 467k | return r == size; |
248 | 467k | } |
249 | | |
250 | | #if IMMER_DEBUG_STATS |
251 | | void do_get_debug_stats(champ_debug_stats& stats, |
252 | | node_t* node, |
253 | | count_t depth) const |
254 | | { |
255 | | if (depth < max_depth<B>) { |
256 | | ++stats.inner_node_count; |
257 | | stats.inner_node_w_value_count += node->data_count() > 0; |
258 | | stats.inner_node_w_child_count += node->children_count() > 0; |
259 | | stats.value_count += node->data_count(); |
260 | | stats.child_count += node->children_count(); |
261 | | auto nodemap = node->nodemap(); |
262 | | if (nodemap) { |
263 | | auto fst = node->children(); |
264 | | auto lst = fst + node->children_count(); |
265 | | for (; fst != lst; ++fst) |
266 | | do_get_debug_stats(stats, *fst, depth + 1); |
267 | | } |
268 | | } else { |
269 | | ++stats.collision_node_count; |
270 | | stats.collision_count += node->collision_count(); |
271 | | } |
272 | | } |
273 | | |
274 | | champ_debug_stats get_debug_stats() const |
275 | | { |
276 | | auto stats = champ_debug_stats{B, sizeof(T)}; |
277 | | do_get_debug_stats(stats, root, 0); |
278 | | return stats; |
279 | | } |
280 | | #endif |
281 | | |
282 | | template <typename U> |
283 | | static auto from_initializer_list(std::initializer_list<U> values) |
284 | | { |
285 | | auto e = owner_t{}; |
286 | | auto result = champ{empty()}; |
287 | | for (auto&& v : values) |
288 | | result.add_mut(e, v); |
289 | | return result; |
290 | | } |
291 | | |
292 | | template <typename Iter, |
293 | | typename Sent, |
294 | | std::enable_if_t<compatible_sentinel_v<Iter, Sent>, bool> = true> |
295 | | static auto from_range(Iter first, Sent last) |
296 | | { |
297 | | auto e = owner_t{}; |
298 | | auto result = champ{empty()}; |
299 | | for (; first != last; ++first) |
300 | | result.add_mut(e, *first); |
301 | | return result; |
302 | | } |
303 | | |
304 | | template <typename Fn> |
305 | | void for_each_chunk(Fn&& fn) const |
306 | | { |
307 | | for_each_chunk_traversal(root, 0, fn); |
308 | | } |
309 | | |
310 | | template <typename Fn> |
311 | | void |
312 | | for_each_chunk_traversal(const node_t* node, count_t depth, Fn&& fn) const |
313 | 285k | { |
314 | 285k | if (depth < max_depth<B>) { |
315 | 278k | auto datamap = node->datamap(); |
316 | 278k | if (datamap) |
317 | 143k | fn(node->values(), node->values() + node->data_count()); |
318 | 278k | auto nodemap = node->nodemap(); |
319 | 278k | if (nodemap) { |
320 | 153k | auto fst = node->children(); |
321 | 153k | auto lst = fst + node->children_count(); |
322 | 317k | for (; fst != lst; ++fst) |
323 | 163k | for_each_chunk_traversal(*fst, depth + 1, fn); |
324 | 153k | } |
325 | 278k | } else { |
326 | 7.14k | fn(node->collisions(), |
327 | 7.14k | node->collisions() + node->collision_count()); |
328 | 7.14k | } |
329 | 285k | } map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 1.00k | { | 314 | 1.00k | if (depth < max_depth<B>) { | 315 | 1.00k | auto datamap = node->datamap(); | 316 | 1.00k | if (datamap) | 317 | 0 | fn(node->values(), node->values() + node->data_count()); | 318 | 1.00k | auto nodemap = node->nodemap(); | 319 | 1.00k | if (nodemap) { | 320 | 1.00k | auto fst = node->children(); | 321 | 1.00k | auto lst = fst + node->children_count(); | 322 | 2.01k | for (; fst != lst; ++fst) | 323 | 1.00k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 1.00k | } | 325 | 1.00k | } else { | 326 | 0 | fn(node->collisions(), | 327 | 0 | node->collisions() + node->collision_count()); | 328 | 0 | } | 329 | 1.00k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 18.6k | { | 314 | 18.6k | if (depth < max_depth<B>) { | 315 | 18.2k | auto datamap = node->datamap(); | 316 | 18.2k | if (datamap) | 317 | 1.37k | fn(node->values(), node->values() + node->data_count()); | 318 | 18.2k | auto nodemap = node->nodemap(); | 319 | 18.2k | if (nodemap) { | 320 | 17.1k | auto fst = node->children(); | 321 | 17.1k | auto lst = fst + node->children_count(); | 322 | 34.8k | for (; fst != lst; ++fst) | 323 | 17.6k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 17.1k | } | 325 | 18.2k | } else { | 326 | 415 | fn(node->collisions(), | 327 | 415 | node->collisions() + node->collision_count()); | 328 | 415 | } | 329 | 18.6k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 1.85k | { | 314 | 1.85k | if (depth < max_depth<B>) { | 315 | 1.85k | auto datamap = node->datamap(); | 316 | 1.85k | if (datamap) | 317 | 0 | fn(node->values(), node->values() + node->data_count()); | 318 | 1.85k | auto nodemap = node->nodemap(); | 319 | 1.85k | if (nodemap) { | 320 | 1.85k | auto fst = node->children(); | 321 | 1.85k | auto lst = fst + node->children_count(); | 322 | 3.71k | for (; fst != lst; ++fst) | 323 | 1.85k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 1.85k | } | 325 | 1.85k | } else { | 326 | 0 | fn(node->collisions(), | 327 | 0 | node->collisions() + node->collision_count()); | 328 | 0 | } | 329 | 1.85k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 36.9k | { | 314 | 36.9k | if (depth < max_depth<B>) { | 315 | 36.0k | auto datamap = node->datamap(); | 316 | 36.0k | if (datamap) | 317 | 4.75k | fn(node->values(), node->values() + node->data_count()); | 318 | 36.0k | auto nodemap = node->nodemap(); | 319 | 36.0k | if (nodemap) { | 320 | 32.8k | auto fst = node->children(); | 321 | 32.8k | auto lst = fst + node->children_count(); | 322 | 67.9k | for (; fst != lst; ++fst) | 323 | 35.0k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 32.8k | } | 325 | 36.0k | } else { | 326 | 834 | fn(node->collisions(), | 327 | 834 | node->collisions() + node->collision_count()); | 328 | 834 | } | 329 | 36.9k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 18.2k | { | 314 | 18.2k | if (depth < max_depth<B>) { | 315 | 18.0k | auto datamap = node->datamap(); | 316 | 18.0k | if (datamap) | 317 | 15.0k | fn(node->values(), node->values() + node->data_count()); | 318 | 18.0k | auto nodemap = node->nodemap(); | 319 | 18.0k | if (nodemap) { | 320 | 5.37k | auto fst = node->children(); | 321 | 5.37k | auto lst = fst + node->children_count(); | 322 | 11.3k | for (; fst != lst; ++fst) | 323 | 6.02k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 5.37k | } | 325 | 18.0k | } else { | 326 | 205 | fn(node->collisions(), | 327 | 205 | node->collisions() + node->collision_count()); | 328 | 205 | } | 329 | 18.2k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 10.1k | { | 314 | 10.1k | if (depth < max_depth<B>) { | 315 | 9.36k | auto datamap = node->datamap(); | 316 | 9.36k | if (datamap) | 317 | 5.52k | fn(node->values(), node->values() + node->data_count()); | 318 | 9.36k | auto nodemap = node->nodemap(); | 319 | 9.36k | if (nodemap) { | 320 | 3.94k | auto fst = node->children(); | 321 | 3.94k | auto lst = fst + node->children_count(); | 322 | 8.07k | for (; fst != lst; ++fst) | 323 | 4.13k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 3.94k | } | 325 | 9.36k | } else { | 326 | 791 | fn(node->collisions(), | 327 | 791 | node->collisions() + node->collision_count()); | 328 | 791 | } | 329 | 10.1k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 18.3k | { | 314 | 18.3k | if (depth < max_depth<B>) { | 315 | 18.1k | auto datamap = node->datamap(); | 316 | 18.1k | if (datamap) | 317 | 15.3k | fn(node->values(), node->values() + node->data_count()); | 318 | 18.1k | auto nodemap = node->nodemap(); | 319 | 18.1k | if (nodemap) { | 320 | 5.17k | auto fst = node->children(); | 321 | 5.17k | auto lst = fst + node->children_count(); | 322 | 11.2k | for (; fst != lst; ++fst) | 323 | 6.07k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 5.17k | } | 325 | 18.1k | } else { | 326 | 204 | fn(node->collisions(), | 327 | 204 | node->collisions() + node->collision_count()); | 328 | 204 | } | 329 | 18.3k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 10.3k | { | 314 | 10.3k | if (depth < max_depth<B>) { | 315 | 9.50k | auto datamap = node->datamap(); | 316 | 9.50k | if (datamap) | 317 | 5.72k | fn(node->values(), node->values() + node->data_count()); | 318 | 9.50k | auto nodemap = node->nodemap(); | 319 | 9.50k | if (nodemap) { | 320 | 4.12k | auto fst = node->children(); | 321 | 4.12k | auto lst = fst + node->children_count(); | 322 | 8.43k | for (; fst != lst; ++fst) | 323 | 4.31k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 4.12k | } | 325 | 9.50k | } else { | 326 | 880 | fn(node->collisions(), | 327 | 880 | node->collisions() + node->collision_count()); | 328 | 880 | } | 329 | 10.3k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff_data_node<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned char, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 41.2k | { | 314 | 41.2k | if (depth < max_depth<B>) { | 315 | 40.9k | auto datamap = node->datamap(); | 316 | 40.9k | if (datamap) | 317 | 33.8k | fn(node->values(), node->values() + node->data_count()); | 318 | 40.9k | auto nodemap = node->nodemap(); | 319 | 40.9k | if (nodemap) { | 320 | 11.6k | auto fst = node->children(); | 321 | 11.6k | auto lst = fst + node->children_count(); | 322 | 24.0k | for (; fst != lst; ++fst) | 323 | 12.4k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 11.6k | } | 325 | 40.9k | } else { | 326 | 282 | fn(node->collisions(), | 327 | 282 | node->collisions() + node->collision_count()); | 328 | 282 | } | 329 | 41.2k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff_data_node<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned char, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 44.8k | { | 314 | 44.8k | if (depth < max_depth<B>) { | 315 | 43.5k | auto datamap = node->datamap(); | 316 | 43.5k | if (datamap) | 317 | 14.6k | fn(node->values(), node->values() + node->data_count()); | 318 | 43.5k | auto nodemap = node->nodemap(); | 319 | 43.5k | if (nodemap) { | 320 | 30.4k | auto fst = node->children(); | 321 | 30.4k | auto lst = fst + node->children_count(); | 322 | 62.7k | for (; fst != lst; ++fst) | 323 | 32.3k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 30.4k | } | 325 | 43.5k | } else { | 326 | 1.30k | fn(node->collisions(), | 327 | 1.30k | node->collisions() + node->collision_count()); | 328 | 1.30k | } | 329 | 44.8k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff_node_data<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned char, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 41.0k | { | 314 | 41.0k | if (depth < max_depth<B>) { | 315 | 40.7k | auto datamap = node->datamap(); | 316 | 40.7k | if (datamap) | 317 | 33.0k | fn(node->values(), node->values() + node->data_count()); | 318 | 40.7k | auto nodemap = node->nodemap(); | 319 | 40.7k | if (nodemap) { | 320 | 11.8k | auto fst = node->children(); | 321 | 11.8k | auto lst = fst + node->children_count(); | 322 | 24.9k | for (; fst != lst; ++fst) | 323 | 13.1k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 11.8k | } | 325 | 40.7k | } else { | 326 | 306 | fn(node->collisions(), | 327 | 306 | node->collisions() + node->collision_count()); | 328 | 306 | } | 329 | 41.0k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff_node_data<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned char, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const Line | Count | Source | 313 | 42.6k | { | 314 | 42.6k | if (depth < max_depth<B>) { | 315 | 40.7k | auto datamap = node->datamap(); | 316 | 40.7k | if (datamap) | 317 | 13.8k | fn(node->values(), node->values() + node->data_count()); | 318 | 40.7k | auto nodemap = node->nodemap(); | 319 | 40.7k | if (nodemap) { | 320 | 27.9k | auto fst = node->children(); | 321 | 27.9k | auto lst = fst + node->children_count(); | 322 | 57.5k | for (; fst != lst; ++fst) | 323 | 29.5k | for_each_chunk_traversal(*fst, depth + 1, fn); | 324 | 27.9k | } | 325 | 40.7k | } else { | 326 | 1.92k | fn(node->collisions(), | 327 | 1.92k | node->collisions() + node->collision_count()); | 328 | 1.92k | } | 329 | 42.6k | } |
|
330 | | |
331 | | template <typename EqualValue, typename Differ> |
332 | | void diff(const champ& new_champ, Differ&& differ) const |
333 | 28.7k | { |
334 | 28.7k | diff<EqualValue>(root, new_champ.root, 0, std::forward<Differ>(differ)); |
335 | 28.7k | } |
336 | | |
337 | | template <typename EqualValue, typename Differ> |
338 | | void diff(const node_t* old_node, |
339 | | const node_t* new_node, |
340 | | count_t depth, |
341 | | Differ&& differ) const |
342 | 684k | { |
343 | 684k | if (old_node == new_node) |
344 | 61.6k | return; |
345 | 622k | if (depth < max_depth<B>) { |
346 | 617k | auto old_nodemap = old_node->nodemap(); |
347 | 617k | auto new_nodemap = new_node->nodemap(); |
348 | 617k | auto old_datamap = old_node->datamap(); |
349 | 617k | auto new_datamap = new_node->datamap(); |
350 | 617k | auto old_bits = old_nodemap | old_datamap; |
351 | 617k | auto new_bits = new_nodemap | new_datamap; |
352 | 617k | auto changes = old_bits ^ new_bits; |
353 | | |
354 | | // added bits |
355 | 617k | for (auto bit : set_bits_range<bitmap_t>(new_bits & changes)) { |
356 | 111k | if (new_nodemap & bit) { |
357 | 19.2k | auto offset = new_node->children_count(bit); |
358 | 19.2k | auto child = new_node->children()[offset]; |
359 | 19.2k | for_each_chunk_traversal( |
360 | 19.2k | child, |
361 | 19.2k | depth + 1, |
362 | 23.3k | [&](auto const& begin, auto const& end) { |
363 | 72.4k | for (auto it = begin; it != end; it++) |
364 | 49.0k | differ.added(*it); |
365 | 23.3k | }); map-st-str-conflict.cpp:auto immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}::operator()<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const*, {lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const* const) const Line | Count | Source | 362 | 1.79k | [&](auto const& begin, auto const& end) { | 363 | 5.59k | for (auto it = begin; it != end; it++) | 364 | 3.80k | differ.added(*it); | 365 | 1.79k | }); |
map-st-str-conflict.cpp:auto immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}::operator()<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const*, {lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const* const) const Line | Count | Source | 362 | 21.6k | [&](auto const& begin, auto const& end) { | 363 | 66.8k | for (auto it = begin; it != end; it++) | 364 | 45.2k | differ.added(*it); | 365 | 21.6k | }); |
|
366 | 92.4k | } else if (new_datamap & bit) { |
367 | 92.4k | auto offset = new_node->data_count(bit); |
368 | 92.4k | auto const& value = new_node->values()[offset]; |
369 | 92.4k | differ.added(value); |
370 | 92.4k | } |
371 | 111k | } |
372 | | |
373 | | // removed bits |
374 | 617k | for (auto bit : set_bits_range<bitmap_t>(old_bits & changes)) { |
375 | 110k | if (old_nodemap & bit) { |
376 | 20.2k | auto offset = old_node->children_count(bit); |
377 | 20.2k | auto child = old_node->children()[offset]; |
378 | 20.2k | for_each_chunk_traversal( |
379 | 20.2k | child, |
380 | 20.2k | depth + 1, |
381 | 27.7k | [&](auto const& begin, auto const& end) { |
382 | 86.9k | for (auto it = begin; it != end; it++) |
383 | 59.1k | differ.removed(*it); |
384 | 27.7k | }); map-st-str-conflict.cpp:auto immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}::operator()<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const*, {lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const* const) const Line | Count | Source | 381 | 5.59k | [&](auto const& begin, auto const& end) { | 382 | 17.2k | for (auto it = begin; it != end; it++) | 383 | 11.6k | differ.removed(*it); | 384 | 5.59k | }); |
map-st-str-conflict.cpp:auto immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}::operator()<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const*, {lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const* const) const Line | Count | Source | 381 | 22.1k | [&](auto const& begin, auto const& end) { | 382 | 69.6k | for (auto it = begin; it != end; it++) | 383 | 47.5k | differ.removed(*it); | 384 | 22.1k | }); |
|
385 | 90.5k | } else if (old_datamap & bit) { |
386 | 90.5k | auto offset = old_node->data_count(bit); |
387 | 90.5k | auto const& value = old_node->values()[offset]; |
388 | 90.5k | differ.removed(value); |
389 | 90.5k | } |
390 | 110k | } |
391 | | |
392 | | // bits in both nodes |
393 | 1.20M | for (auto bit : set_bits_range<bitmap_t>(old_bits & new_bits)) { |
394 | 1.20M | if ((old_nodemap & bit) && (new_nodemap & bit)) { |
395 | 655k | auto old_offset = old_node->children_count(bit); |
396 | 655k | auto new_offset = new_node->children_count(bit); |
397 | 655k | auto old_child = old_node->children()[old_offset]; |
398 | 655k | auto new_child = new_node->children()[new_offset]; |
399 | 655k | diff<EqualValue>(old_child, new_child, depth + 1, differ); |
400 | 655k | } else if ((old_datamap & bit) && (new_nodemap & bit)) { |
401 | 41.2k | diff_data_node<EqualValue>( |
402 | 41.2k | old_node, new_node, bit, depth, differ); |
403 | 511k | } else if ((old_nodemap & bit) && (new_datamap & bit)) { |
404 | 41.0k | diff_node_data<EqualValue>( |
405 | 41.0k | old_node, new_node, bit, depth, differ); |
406 | 470k | } else if ((old_datamap & bit) && (new_datamap & bit)) { |
407 | 470k | diff_data_data<EqualValue>(old_node, new_node, bit, differ); |
408 | 470k | } |
409 | 1.20M | } |
410 | 617k | } else { |
411 | 5.10k | diff_collisions<EqualValue>(old_node, new_node, differ); |
412 | 5.10k | } |
413 | 622k | } map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const Line | Count | Source | 342 | 28.7k | { | 343 | 28.7k | if (old_node == new_node) | 344 | 1.93k | return; | 345 | 26.7k | if (depth < max_depth<B>) { | 346 | 26.7k | auto old_nodemap = old_node->nodemap(); | 347 | 26.7k | auto new_nodemap = new_node->nodemap(); | 348 | 26.7k | auto old_datamap = old_node->datamap(); | 349 | 26.7k | auto new_datamap = new_node->datamap(); | 350 | 26.7k | auto old_bits = old_nodemap | old_datamap; | 351 | 26.7k | auto new_bits = new_nodemap | new_datamap; | 352 | 26.7k | auto changes = old_bits ^ new_bits; | 353 | | | 354 | | // added bits | 355 | 26.7k | for (auto bit : set_bits_range<bitmap_t>(new_bits & changes)) { | 356 | 1.29k | if (new_nodemap & bit) { | 357 | 1.00k | auto offset = new_node->children_count(bit); | 358 | 1.00k | auto child = new_node->children()[offset]; | 359 | 1.00k | for_each_chunk_traversal( | 360 | 1.00k | child, | 361 | 1.00k | depth + 1, | 362 | 1.00k | [&](auto const& begin, auto const& end) { | 363 | 1.00k | for (auto it = begin; it != end; it++) | 364 | 1.00k | differ.added(*it); | 365 | 1.00k | }); | 366 | 1.00k | } else if (new_datamap & bit) { | 367 | 286 | auto offset = new_node->data_count(bit); | 368 | 286 | auto const& value = new_node->values()[offset]; | 369 | 286 | differ.added(value); | 370 | 286 | } | 371 | 1.29k | } | 372 | | | 373 | | // removed bits | 374 | 26.7k | for (auto bit : set_bits_range<bitmap_t>(old_bits & changes)) { | 375 | 2.16k | if (old_nodemap & bit) { | 376 | 1.85k | auto offset = old_node->children_count(bit); | 377 | 1.85k | auto child = old_node->children()[offset]; | 378 | 1.85k | for_each_chunk_traversal( | 379 | 1.85k | child, | 380 | 1.85k | depth + 1, | 381 | 1.85k | [&](auto const& begin, auto const& end) { | 382 | 1.85k | for (auto it = begin; it != end; it++) | 383 | 1.85k | differ.removed(*it); | 384 | 1.85k | }); | 385 | 1.85k | } else if (old_datamap & bit) { | 386 | 306 | auto offset = old_node->data_count(bit); | 387 | 306 | auto const& value = old_node->values()[offset]; | 388 | 306 | differ.removed(value); | 389 | 306 | } | 390 | 2.16k | } | 391 | | | 392 | | // bits in both nodes | 393 | 26.7k | for (auto bit : set_bits_range<bitmap_t>(old_bits & new_bits)) { | 394 | 23.3k | if ((old_nodemap & bit) && (new_nodemap & bit)) { | 395 | 19.4k | auto old_offset = old_node->children_count(bit); | 396 | 19.4k | auto new_offset = new_node->children_count(bit); | 397 | 19.4k | auto old_child = old_node->children()[old_offset]; | 398 | 19.4k | auto new_child = new_node->children()[new_offset]; | 399 | 19.4k | diff<EqualValue>(old_child, new_child, depth + 1, differ); | 400 | 19.4k | } else if ((old_datamap & bit) && (new_nodemap & bit)) { | 401 | 1.62k | diff_data_node<EqualValue>( | 402 | 1.62k | old_node, new_node, bit, depth, differ); | 403 | 2.23k | } else if ((old_nodemap & bit) && (new_datamap & bit)) { | 404 | 1.45k | diff_node_data<EqualValue>( | 405 | 1.45k | old_node, new_node, bit, depth, differ); | 406 | 1.45k | } else if ((old_datamap & bit) && (new_datamap & bit)) { | 407 | 777 | diff_data_data<EqualValue>(old_node, new_node, bit, differ); | 408 | 777 | } | 409 | 23.3k | } | 410 | 26.7k | } else { | 411 | 0 | diff_collisions<EqualValue>(old_node, new_node, differ); | 412 | 0 | } | 413 | 26.7k | } |
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const Line | Count | Source | 342 | 655k | { | 343 | 655k | if (old_node == new_node) | 344 | 59.7k | return; | 345 | 595k | if (depth < max_depth<B>) { | 346 | 590k | auto old_nodemap = old_node->nodemap(); | 347 | 590k | auto new_nodemap = new_node->nodemap(); | 348 | 590k | auto old_datamap = old_node->datamap(); | 349 | 590k | auto new_datamap = new_node->datamap(); | 350 | 590k | auto old_bits = old_nodemap | old_datamap; | 351 | 590k | auto new_bits = new_nodemap | new_datamap; | 352 | 590k | auto changes = old_bits ^ new_bits; | 353 | | | 354 | | // added bits | 355 | 590k | for (auto bit : set_bits_range<bitmap_t>(new_bits & changes)) { | 356 | 110k | if (new_nodemap & bit) { | 357 | 18.2k | auto offset = new_node->children_count(bit); | 358 | 18.2k | auto child = new_node->children()[offset]; | 359 | 18.2k | for_each_chunk_traversal( | 360 | 18.2k | child, | 361 | 18.2k | depth + 1, | 362 | 18.2k | [&](auto const& begin, auto const& end) { | 363 | 18.2k | for (auto it = begin; it != end; it++) | 364 | 18.2k | differ.added(*it); | 365 | 18.2k | }); | 366 | 92.1k | } else if (new_datamap & bit) { | 367 | 92.1k | auto offset = new_node->data_count(bit); | 368 | 92.1k | auto const& value = new_node->values()[offset]; | 369 | 92.1k | differ.added(value); | 370 | 92.1k | } | 371 | 110k | } | 372 | | | 373 | | // removed bits | 374 | 590k | for (auto bit : set_bits_range<bitmap_t>(old_bits & changes)) { | 375 | 108k | if (old_nodemap & bit) { | 376 | 18.3k | auto offset = old_node->children_count(bit); | 377 | 18.3k | auto child = old_node->children()[offset]; | 378 | 18.3k | for_each_chunk_traversal( | 379 | 18.3k | child, | 380 | 18.3k | depth + 1, | 381 | 18.3k | [&](auto const& begin, auto const& end) { | 382 | 18.3k | for (auto it = begin; it != end; it++) | 383 | 18.3k | differ.removed(*it); | 384 | 18.3k | }); | 385 | 90.2k | } else if (old_datamap & bit) { | 386 | 90.2k | auto offset = old_node->data_count(bit); | 387 | 90.2k | auto const& value = old_node->values()[offset]; | 388 | 90.2k | differ.removed(value); | 389 | 90.2k | } | 390 | 108k | } | 391 | | | 392 | | // bits in both nodes | 393 | 1.18M | for (auto bit : set_bits_range<bitmap_t>(old_bits & new_bits)) { | 394 | 1.18M | if ((old_nodemap & bit) && (new_nodemap & bit)) { | 395 | 635k | auto old_offset = old_node->children_count(bit); | 396 | 635k | auto new_offset = new_node->children_count(bit); | 397 | 635k | auto old_child = old_node->children()[old_offset]; | 398 | 635k | auto new_child = new_node->children()[new_offset]; | 399 | 635k | diff<EqualValue>(old_child, new_child, depth + 1, differ); | 400 | 635k | } else if ((old_datamap & bit) && (new_nodemap & bit)) { | 401 | 39.6k | diff_data_node<EqualValue>( | 402 | 39.6k | old_node, new_node, bit, depth, differ); | 403 | 508k | } else if ((old_nodemap & bit) && (new_datamap & bit)) { | 404 | 39.5k | diff_node_data<EqualValue>( | 405 | 39.5k | old_node, new_node, bit, depth, differ); | 406 | 469k | } else if ((old_datamap & bit) && (new_datamap & bit)) { | 407 | 469k | diff_data_data<EqualValue>(old_node, new_node, bit, differ); | 408 | 469k | } | 409 | 1.18M | } | 410 | 590k | } else { | 411 | 5.10k | diff_collisions<EqualValue>(old_node, new_node, differ); | 412 | 5.10k | } | 413 | 595k | } |
|
414 | | |
415 | | template <typename EqualValue, typename Differ> |
416 | | void diff_data_node(const node_t* old_node, |
417 | | const node_t* new_node, |
418 | | bitmap_t bit, |
419 | | count_t depth, |
420 | | Differ&& differ) const |
421 | 41.2k | { |
422 | 41.2k | auto old_offset = old_node->data_count(bit); |
423 | 41.2k | auto const& old_value = old_node->values()[old_offset]; |
424 | 41.2k | auto new_offset = new_node->children_count(bit); |
425 | 41.2k | auto new_child = new_node->children()[new_offset]; |
426 | | |
427 | 41.2k | bool found = false; |
428 | 41.2k | for_each_chunk_traversal( |
429 | 50.0k | new_child, depth + 1, [&](auto const& begin, auto const& end) { |
430 | 154k | for (auto it = begin; it != end; it++) { |
431 | 104k | if (Equal{}(old_value, *it)) { |
432 | 28.8k | if (!EqualValue{}(old_value, *it)) |
433 | 2.72k | differ.changed(old_value, *it); |
434 | 28.8k | found = true; |
435 | 75.1k | } else { |
436 | 75.1k | differ.added(*it); |
437 | 75.1k | } |
438 | 104k | } |
439 | 50.0k | }); |
440 | 41.2k | if (!found) |
441 | 12.4k | differ.removed(old_value); |
442 | 41.2k | } |
443 | | |
444 | | template <typename EqualValue, typename Differ> |
445 | | void diff_node_data(const node_t* old_node, |
446 | | const node_t* const new_node, |
447 | | bitmap_t bit, |
448 | | count_t depth, |
449 | | Differ&& differ) const |
450 | 41.0k | { |
451 | 41.0k | auto old_offset = old_node->children_count(bit); |
452 | 41.0k | auto old_child = old_node->children()[old_offset]; |
453 | 41.0k | auto new_offset = new_node->data_count(bit); |
454 | 41.0k | auto const& new_value = new_node->values()[new_offset]; |
455 | | |
456 | 41.0k | bool found = false; |
457 | 41.0k | for_each_chunk_traversal( |
458 | 49.1k | old_child, depth + 1, [&](auto const& begin, auto const& end) { |
459 | 152k | for (auto it = begin; it != end; it++) { |
460 | 103k | if (Equal{}(*it, new_value)) { |
461 | 28.5k | if (!EqualValue{}(*it, new_value)) |
462 | 2.46k | differ.changed(*it, new_value); |
463 | 28.5k | found = true; |
464 | 74.4k | } else { |
465 | 74.4k | differ.removed(*it); |
466 | 74.4k | } |
467 | 103k | } |
468 | 49.1k | }); |
469 | 41.0k | if (!found) |
470 | 12.4k | differ.added(new_value); |
471 | 41.0k | } |
472 | | |
473 | | template <typename EqualValue, typename Differ> |
474 | | void diff_data_data(const node_t* old_node, |
475 | | const node_t* new_node, |
476 | | bitmap_t bit, |
477 | | Differ&& differ) const |
478 | 470k | { |
479 | 470k | auto old_offset = old_node->data_count(bit); |
480 | 470k | auto new_offset = new_node->data_count(bit); |
481 | 470k | auto const& old_value = old_node->values()[old_offset]; |
482 | 470k | auto const& new_value = new_node->values()[new_offset]; |
483 | 470k | if (!Equal{}(old_value, new_value)) { |
484 | 26.0k | differ.removed(old_value); |
485 | 26.0k | differ.added(new_value); |
486 | 443k | } else { |
487 | 443k | if (!EqualValue{}(old_value, new_value)) |
488 | 18.8k | differ.changed(old_value, new_value); |
489 | 443k | } |
490 | 470k | } |
491 | | |
492 | | template <typename EqualValue, typename Differ> |
493 | | void diff_collisions(const node_t* old_node, |
494 | | const node_t* new_node, |
495 | | Differ&& differ) const |
496 | 5.10k | { |
497 | 5.10k | auto old_begin = old_node->collisions(); |
498 | 5.10k | auto old_end = old_node->collisions() + old_node->collision_count(); |
499 | 5.10k | auto new_begin = new_node->collisions(); |
500 | 5.10k | auto new_end = new_node->collisions() + new_node->collision_count(); |
501 | | // search changes and removals |
502 | 16.7k | for (auto old_it = old_begin; old_it != old_end; old_it++) { |
503 | 11.6k | bool found = false; |
504 | 20.9k | for (auto new_it = new_begin; new_it != new_end; new_it++) { |
505 | 20.1k | if (Equal{}(*old_it, *new_it)) { |
506 | 10.8k | if (!EqualValue{}(*old_it, *new_it)) |
507 | 452 | differ.changed(*old_it, *new_it); |
508 | 10.8k | found = true; |
509 | 10.8k | break; |
510 | 10.8k | } |
511 | 20.1k | } |
512 | 11.6k | if (!found) |
513 | 758 | differ.removed(*old_it); |
514 | 11.6k | } |
515 | | // search new entries |
516 | 16.5k | for (auto new_it = new_begin; new_it != new_end; new_it++) { |
517 | 11.4k | bool found = false; |
518 | 20.5k | for (auto old_it = old_begin; old_it != old_end; old_it++) { |
519 | 19.9k | if (Equal{}(*old_it, *new_it)) { |
520 | 10.8k | found = true; |
521 | 10.8k | break; |
522 | 10.8k | } |
523 | 19.9k | } |
524 | 11.4k | if (!found) |
525 | 578 | differ.added(*new_it); |
526 | 11.4k | } |
527 | 5.10k | } |
528 | | |
529 | | template <typename Project, typename Default, typename K> |
530 | | decltype(auto) get(const K& k) const |
531 | 1.04M | { |
532 | 1.04M | auto node = root; |
533 | 1.04M | auto hash = Hash{}(k); |
534 | 18.6M | for (auto i = count_t{}; i < max_depth<B>; ++i) { |
535 | 18.6M | auto bit = bitmap_t{1u} << (hash & mask<B>); |
536 | 18.6M | if (node->nodemap() & bit) { |
537 | 17.6M | auto offset = node->children_count(bit); |
538 | 17.6M | node = node->children()[offset]; |
539 | 17.6M | hash = hash >> B; |
540 | 17.6M | } else if (node->datamap() & bit) { |
541 | 719k | auto offset = node->data_count(bit); |
542 | 719k | auto val = node->values() + offset; |
543 | 719k | if (Equal{}(*val, k)) |
544 | 511k | return Project{}(*val); |
545 | 208k | else |
546 | 208k | return Default{}(); |
547 | 719k | } else { |
548 | 311k | return Default{}(); |
549 | 311k | } |
550 | 18.6M | } |
551 | 16.5k | auto fst = node->collisions(); |
552 | 16.5k | auto lst = fst + node->collision_count(); |
553 | 29.9k | for (; fst != lst; ++fst) |
554 | 28.1k | if (Equal{}(*fst, k)) |
555 | 14.6k | return Project{}(*fst); |
556 | 1.84k | return Default{}(); |
557 | 16.5k | } decltype(auto) immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::get<immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::project_value_ptr, immer::detail::constantly<immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > const*, (immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > const*)0>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const Line | Count | Source | 531 | 9.51k | { | 532 | 9.51k | auto node = root; | 533 | 9.51k | auto hash = Hash{}(k); | 534 | 154k | for (auto i = count_t{}; i < max_depth<B>; ++i) { | 535 | 153k | auto bit = bitmap_t{1u} << (hash & mask<B>); | 536 | 153k | if (node->nodemap() & bit) { | 537 | 144k | auto offset = node->children_count(bit); | 538 | 144k | node = node->children()[offset]; | 539 | 144k | hash = hash >> B; | 540 | 144k | } else if (node->datamap() & bit) { | 541 | 7.23k | auto offset = node->data_count(bit); | 542 | 7.23k | auto val = node->values() + offset; | 543 | 7.23k | if (Equal{}(*val, k)) | 544 | 6.15k | return Project{}(*val); | 545 | 1.08k | else | 546 | 1.08k | return Default{}(); | 547 | 7.23k | } else { | 548 | 1.07k | return Default{}(); | 549 | 1.07k | } | 550 | 153k | } | 551 | 1.20k | auto fst = node->collisions(); | 552 | 1.20k | auto lst = fst + node->collision_count(); | 553 | 3.08k | for (; fst != lst; ++fst) | 554 | 2.60k | if (Equal{}(*fst, k)) | 555 | 721 | return Project{}(*fst); | 556 | 481 | return Default{}(); | 557 | 1.20k | } |
decltype(auto) immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::get<immer::detail::constantly<unsigned long, 1ul>, immer::detail::constantly<unsigned long, 0ul>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const Line | Count | Source | 531 | 1.03M | { | 532 | 1.03M | auto node = root; | 533 | 1.03M | auto hash = Hash{}(k); | 534 | 18.5M | for (auto i = count_t{}; i < max_depth<B>; ++i) { | 535 | 18.4M | auto bit = bitmap_t{1u} << (hash & mask<B>); | 536 | 18.4M | if (node->nodemap() & bit) { | 537 | 17.4M | auto offset = node->children_count(bit); | 538 | 17.4M | node = node->children()[offset]; | 539 | 17.4M | hash = hash >> B; | 540 | 17.4M | } else if (node->datamap() & bit) { | 541 | 712k | auto offset = node->data_count(bit); | 542 | 712k | auto val = node->values() + offset; | 543 | 712k | if (Equal{}(*val, k)) | 544 | 505k | return Project{}(*val); | 545 | 206k | else | 546 | 206k | return Default{}(); | 547 | 712k | } else { | 548 | 310k | return Default{}(); | 549 | 310k | } | 550 | 18.4M | } | 551 | 15.3k | auto fst = node->collisions(); | 552 | 15.3k | auto lst = fst + node->collision_count(); | 553 | 26.8k | for (; fst != lst; ++fst) | 554 | 25.5k | if (Equal{}(*fst, k)) | 555 | 13.9k | return Project{}(*fst); | 556 | 1.36k | return Default{}(); | 557 | 15.3k | } |
|
558 | | |
559 | | struct add_result |
560 | | { |
561 | | node_t* node; |
562 | | bool added; |
563 | | }; |
564 | | |
565 | | add_result do_add(node_t* node, T v, hash_t hash, shift_t shift) const |
566 | 12.8M | { |
567 | 12.8M | assert(node); |
568 | 12.8M | if (shift == max_shift<B>) { |
569 | 24.1k | auto fst = node->collisions(); |
570 | 24.1k | auto lst = fst + node->collision_count(); |
571 | 58.3k | for (; fst != lst; ++fst) |
572 | 56.8k | if (Equal{}(*fst, v)) |
573 | 22.6k | return { |
574 | 22.6k | node_t::copy_collision_replace(node, fst, std::move(v)), |
575 | 22.6k | false}; |
576 | 1.46k | return {node_t::copy_collision_insert(node, std::move(v)), true}; |
577 | 12.8M | } else { |
578 | 12.8M | auto idx = (hash & (mask<B> << shift)) >> shift; |
579 | 12.8M | auto bit = bitmap_t{1u} << idx; |
580 | 12.8M | if (node->nodemap() & bit) { |
581 | 12.1M | auto offset = node->children_count(bit); |
582 | 12.1M | assert(node->children()[offset]); |
583 | 0 | auto result = do_add( |
584 | 12.1M | node->children()[offset], std::move(v), hash, shift + B); |
585 | 12.1M | IMMER_TRY { |
586 | 12.1M | result.node = |
587 | 12.1M | node_t::copy_inner_replace(node, offset, result.node); |
588 | 12.1M | return result; |
589 | 12.1M | } |
590 | 12.1M | IMMER_CATCH (...) { |
591 | 0 | node_t::delete_deep_shift(result.node, shift + B); |
592 | 0 | IMMER_RETHROW; |
593 | 0 | } |
594 | 12.1M | } else if (node->datamap() & bit) { |
595 | 625k | auto offset = node->data_count(bit); |
596 | 625k | auto val = node->values() + offset; |
597 | 625k | if (Equal{}(*val, v)) |
598 | 603k | return {node_t::copy_inner_replace_value( |
599 | 603k | node, offset, std::move(v)), |
600 | 603k | false}; |
601 | 21.2k | else { |
602 | 21.2k | auto child = node_t::make_merged( |
603 | 21.2k | shift + B, std::move(v), hash, *val, Hash{}(*val)); |
604 | 21.2k | IMMER_TRY { |
605 | 21.2k | return {node_t::copy_inner_replace_merged( |
606 | 21.2k | node, bit, offset, child), |
607 | 21.2k | true}; |
608 | 21.2k | } |
609 | 21.2k | IMMER_CATCH (...) { |
610 | 0 | node_t::delete_deep_shift(child, shift + B); |
611 | 0 | IMMER_RETHROW; |
612 | 0 | } |
613 | 21.2k | } |
614 | 625k | } else { |
615 | 27.3k | return { |
616 | 27.3k | node_t::copy_inner_insert_value(node, bit, std::move(v)), |
617 | 27.3k | true}; |
618 | 27.3k | } |
619 | 12.8M | } |
620 | 12.8M | } |
621 | | |
622 | | champ add(T v) const |
623 | 674k | { |
624 | 674k | auto hash = Hash{}(v); |
625 | 674k | auto res = do_add(root, std::move(v), hash, 0); |
626 | 674k | auto new_size = size + (res.added ? 1 : 0); |
627 | 674k | return {res.node, new_size}; |
628 | 674k | } |
629 | | |
630 | | struct add_mut_result |
631 | | { |
632 | | node_t* node; |
633 | | bool added; |
634 | | bool mutated; |
635 | | }; |
636 | | |
637 | | add_mut_result |
638 | | do_add_mut(edit_t e, node_t* node, T v, hash_t hash, shift_t shift) const |
639 | 358k | { |
640 | 358k | assert(node); |
641 | 358k | if (shift == max_shift<B>) { |
642 | 1.90k | auto fst = node->collisions(); |
643 | 1.90k | auto lst = fst + node->collision_count(); |
644 | 4.49k | for (; fst != lst; ++fst) |
645 | 3.89k | if (Equal{}(*fst, v)) { |
646 | 1.31k | if (node->can_mutate(e)) { |
647 | 1.02k | *fst = std::move(v); |
648 | 1.02k | return {node, false, true}; |
649 | 1.02k | } else { |
650 | 288 | auto r = node_t::copy_collision_replace( |
651 | 288 | node, fst, std::move(v)); |
652 | 288 | return {node_t::owned(r, e), false, false}; |
653 | 288 | } |
654 | 1.31k | } |
655 | 592 | auto mutate = node->can_mutate(e); |
656 | 592 | auto r = mutate ? node_t::move_collision_insert(node, std::move(v)) |
657 | 592 | : node_t::copy_collision_insert(node, std::move(v)); |
658 | 592 | return {node_t::owned(r, e), true, mutate}; |
659 | 356k | } else { |
660 | 356k | auto idx = (hash & (mask<B> << shift)) >> shift; |
661 | 356k | auto bit = bitmap_t{1u} << idx; |
662 | 356k | if (node->nodemap() & bit) { |
663 | 338k | auto offset = node->children_count(bit); |
664 | 338k | auto child = node->children()[offset]; |
665 | 338k | if (node->can_mutate(e)) { |
666 | 335k | auto result = |
667 | 335k | do_add_mut(e, child, std::move(v), hash, shift + B); |
668 | 335k | node->children()[offset] = result.node; |
669 | 335k | if (!result.mutated && child->dec()) |
670 | 0 | node_t::delete_deep_shift(child, shift + B); |
671 | 335k | return {node, result.added, true}; |
672 | 335k | } else { |
673 | 2.39k | assert(node->children()[offset]); |
674 | 0 | auto result = do_add(child, std::move(v), hash, shift + B); |
675 | 2.39k | IMMER_TRY { |
676 | 2.39k | result.node = node_t::copy_inner_replace( |
677 | 2.39k | node, offset, result.node); |
678 | 2.39k | node_t::owned(result.node, e); |
679 | 2.39k | return {result.node, result.added, false}; |
680 | 2.39k | } |
681 | 2.39k | IMMER_CATCH (...) { |
682 | 0 | node_t::delete_deep_shift(result.node, shift + B); |
683 | 0 | IMMER_RETHROW; |
684 | 0 | } |
685 | 2.39k | } |
686 | 338k | } else if (node->datamap() & bit) { |
687 | 12.2k | auto offset = node->data_count(bit); |
688 | 12.2k | auto val = node->values() + offset; |
689 | 12.2k | if (Equal{}(*val, v)) { |
690 | 6.56k | if (node->can_mutate(e)) { |
691 | 6.03k | auto vals = node->ensure_mutable_values(e); |
692 | 6.03k | vals[offset] = std::move(v); |
693 | 6.03k | return {node, false, true}; |
694 | 6.03k | } else { |
695 | 535 | auto r = node_t::copy_inner_replace_value( |
696 | 535 | node, offset, std::move(v)); |
697 | 535 | return {node_t::owned_values(r, e), false, false}; |
698 | 535 | } |
699 | 6.56k | } else { |
700 | 5.67k | auto mutate = node->can_mutate(e); |
701 | 5.67k | auto mutate_values = mutate && node->can_mutate_values(e); |
702 | 5.67k | auto hash2 = Hash{}(*val); |
703 | 5.67k | auto child = node_t::make_merged_e( |
704 | 5.67k | e, |
705 | 5.67k | shift + B, |
706 | 5.67k | std::move(v), |
707 | 5.67k | hash, |
708 | 5.67k | mutate_values ? std::move(*val) : *val, |
709 | 5.67k | hash2); |
710 | 5.67k | IMMER_TRY { |
711 | 5.67k | auto r = mutate ? node_t::move_inner_replace_merged( |
712 | 4.68k | e, node, bit, offset, child) |
713 | 5.67k | : node_t::copy_inner_replace_merged( |
714 | 996 | node, bit, offset, child); |
715 | 5.67k | return {node_t::owned_values_safe(r, e), true, mutate}; |
716 | 5.67k | } |
717 | 5.67k | IMMER_CATCH (...) { |
718 | 0 | node_t::delete_deep_shift(child, shift + B); |
719 | 0 | IMMER_RETHROW; |
720 | 0 | } |
721 | 5.67k | } |
722 | 12.2k | } else { |
723 | 5.71k | auto mutate = node->can_mutate(e); |
724 | 5.71k | auto r = mutate ? node_t::move_inner_insert_value( |
725 | 3.90k | e, node, bit, std::move(v)) |
726 | 5.71k | : node_t::copy_inner_insert_value( |
727 | 1.81k | node, bit, std::move(v)); |
728 | 5.71k | return {node_t::owned_values(r, e), true, mutate}; |
729 | 5.71k | } |
730 | 356k | } |
731 | 358k | } |
732 | | |
733 | | void add_mut(edit_t e, T v) |
734 | 22.2k | { |
735 | 22.2k | auto hash = Hash{}(v); |
736 | 22.2k | auto res = do_add_mut(e, root, std::move(v), hash, 0); |
737 | 22.2k | if (!res.mutated && root->dec()) |
738 | 0 | node_t::delete_deep(root, 0); |
739 | 22.2k | root = res.node; |
740 | 22.2k | size += res.added ? 1 : 0; |
741 | 22.2k | } |
742 | | |
743 | | using update_result = add_result; |
744 | | |
745 | | template <typename Project, |
746 | | typename Default, |
747 | | typename Combine, |
748 | | typename K, |
749 | | typename Fn> |
750 | | update_result |
751 | | do_update(node_t* node, K&& k, Fn&& fn, hash_t hash, shift_t shift) const |
752 | 4.27M | { |
753 | 4.27M | if (shift == max_shift<B>) { |
754 | 2.31k | auto fst = node->collisions(); |
755 | 2.31k | auto lst = fst + node->collision_count(); |
756 | 5.32k | for (; fst != lst; ++fst) |
757 | 4.46k | if (Equal{}(*fst, k)) |
758 | 1.45k | return {node_t::copy_collision_replace( |
759 | 1.45k | node, |
760 | 1.45k | fst, |
761 | 1.45k | Combine{}(std::forward<K>(k), |
762 | 1.45k | std::forward<Fn>(fn)(Project{}( |
763 | 1.45k | detail::as_const(*fst))))), |
764 | 1.45k | false}; |
765 | 857 | return {node_t::copy_collision_insert( |
766 | 857 | node, |
767 | 857 | Combine{}(std::forward<K>(k), |
768 | 857 | std::forward<Fn>(fn)(Default{}()))), |
769 | 857 | true}; |
770 | 4.27M | } else { |
771 | 4.27M | auto idx = (hash & (mask<B> << shift)) >> shift; |
772 | 4.27M | auto bit = bitmap_t{1u} << idx; |
773 | 4.27M | if (node->nodemap() & bit) { |
774 | 4.04M | auto offset = node->children_count(bit); |
775 | 4.04M | auto result = do_update<Project, Default, Combine>( |
776 | 4.04M | node->children()[offset], |
777 | 4.04M | k, |
778 | 4.04M | std::forward<Fn>(fn), |
779 | 4.04M | hash, |
780 | 4.04M | shift + B); |
781 | 4.04M | IMMER_TRY { |
782 | 4.04M | result.node = |
783 | 4.04M | node_t::copy_inner_replace(node, offset, result.node); |
784 | 4.04M | return result; |
785 | 4.04M | } |
786 | 4.04M | IMMER_CATCH (...) { |
787 | 0 | node_t::delete_deep_shift(result.node, shift + B); |
788 | 0 | IMMER_RETHROW; |
789 | 0 | } |
790 | 4.04M | } else if (node->datamap() & bit) { |
791 | 229k | auto offset = node->data_count(bit); |
792 | 229k | auto val = node->values() + offset; |
793 | 229k | if (Equal{}(*val, k)) |
794 | 224k | return {node_t::copy_inner_replace_value( |
795 | 224k | node, |
796 | 224k | offset, |
797 | 224k | Combine{}(std::forward<K>(k), |
798 | 224k | std::forward<Fn>(fn)(Project{}( |
799 | 224k | detail::as_const(*val))))), |
800 | 224k | false}; |
801 | 4.92k | else { |
802 | 4.92k | auto child = node_t::make_merged( |
803 | 4.92k | shift + B, |
804 | 4.92k | Combine{}(std::forward<K>(k), |
805 | 4.92k | std::forward<Fn>(fn)(Default{}())), |
806 | 4.92k | hash, |
807 | 4.92k | *val, |
808 | 4.92k | Hash{}(*val)); |
809 | 4.92k | IMMER_TRY { |
810 | 4.92k | return {node_t::copy_inner_replace_merged( |
811 | 4.92k | node, bit, offset, child), |
812 | 4.92k | true}; |
813 | 4.92k | } |
814 | 4.92k | IMMER_CATCH (...) { |
815 | 0 | node_t::delete_deep_shift(child, shift + B); |
816 | 0 | IMMER_RETHROW; |
817 | 0 | } |
818 | 4.92k | } |
819 | 229k | } else { |
820 | 5.40k | return {node_t::copy_inner_insert_value( |
821 | 5.40k | node, |
822 | 5.40k | bit, |
823 | 5.40k | Combine{}(std::forward<K>(k), |
824 | 5.40k | std::forward<Fn>(fn)(Default{}()))), |
825 | 5.40k | true}; |
826 | 5.40k | } |
827 | 4.27M | } |
828 | 4.27M | } map-st-str-conflict.cpp:immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::add_result immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::do_update<immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::project_value, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::default_value, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::combine_value, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)#1}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)#1}&&, unsigned long, unsigned int) const Line | Count | Source | 752 | 4.20M | { | 753 | 4.20M | if (shift == max_shift<B>) { | 754 | 1.06k | auto fst = node->collisions(); | 755 | 1.06k | auto lst = fst + node->collision_count(); | 756 | 2.58k | for (; fst != lst; ++fst) | 757 | 2.19k | if (Equal{}(*fst, k)) | 758 | 670 | return {node_t::copy_collision_replace( | 759 | 670 | node, | 760 | 670 | fst, | 761 | 670 | Combine{}(std::forward<K>(k), | 762 | 670 | std::forward<Fn>(fn)(Project{}( | 763 | 670 | detail::as_const(*fst))))), | 764 | 670 | false}; | 765 | 391 | return {node_t::copy_collision_insert( | 766 | 391 | node, | 767 | 391 | Combine{}(std::forward<K>(k), | 768 | 391 | std::forward<Fn>(fn)(Default{}()))), | 769 | 391 | true}; | 770 | 4.20M | } else { | 771 | 4.20M | auto idx = (hash & (mask<B> << shift)) >> shift; | 772 | 4.20M | auto bit = bitmap_t{1u} << idx; | 773 | 4.20M | if (node->nodemap() & bit) { | 774 | 3.97M | auto offset = node->children_count(bit); | 775 | 3.97M | auto result = do_update<Project, Default, Combine>( | 776 | 3.97M | node->children()[offset], | 777 | 3.97M | k, | 778 | 3.97M | std::forward<Fn>(fn), | 779 | 3.97M | hash, | 780 | 3.97M | shift + B); | 781 | 3.97M | IMMER_TRY { | 782 | 3.97M | result.node = | 783 | 3.97M | node_t::copy_inner_replace(node, offset, result.node); | 784 | 3.97M | return result; | 785 | 3.97M | } | 786 | 3.97M | IMMER_CATCH (...) { | 787 | 0 | node_t::delete_deep_shift(result.node, shift + B); | 788 | 0 | IMMER_RETHROW; | 789 | 0 | } | 790 | 3.97M | } else if (node->datamap() & bit) { | 791 | 226k | auto offset = node->data_count(bit); | 792 | 226k | auto val = node->values() + offset; | 793 | 226k | if (Equal{}(*val, k)) | 794 | 222k | return {node_t::copy_inner_replace_value( | 795 | 222k | node, | 796 | 222k | offset, | 797 | 222k | Combine{}(std::forward<K>(k), | 798 | 222k | std::forward<Fn>(fn)(Project{}( | 799 | 222k | detail::as_const(*val))))), | 800 | 222k | false}; | 801 | 3.70k | else { | 802 | 3.70k | auto child = node_t::make_merged( | 803 | 3.70k | shift + B, | 804 | 3.70k | Combine{}(std::forward<K>(k), | 805 | 3.70k | std::forward<Fn>(fn)(Default{}())), | 806 | 3.70k | hash, | 807 | 3.70k | *val, | 808 | 3.70k | Hash{}(*val)); | 809 | 3.70k | IMMER_TRY { | 810 | 3.70k | return {node_t::copy_inner_replace_merged( | 811 | 3.70k | node, bit, offset, child), | 812 | 3.70k | true}; | 813 | 3.70k | } | 814 | 3.70k | IMMER_CATCH (...) { | 815 | 0 | node_t::delete_deep_shift(child, shift + B); | 816 | 0 | IMMER_RETHROW; | 817 | 0 | } | 818 | 3.70k | } | 819 | 226k | } else { | 820 | 4.14k | return {node_t::copy_inner_insert_value( | 821 | 4.14k | node, | 822 | 4.14k | bit, | 823 | 4.14k | Combine{}(std::forward<K>(k), | 824 | 4.14k | std::forward<Fn>(fn)(Default{}()))), | 825 | 4.14k | true}; | 826 | 4.14k | } | 827 | 4.20M | } | 828 | 4.20M | } |
map-st-str-conflict.cpp:immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::add_result immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::do_update<immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::project_value, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::default_value, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::combine_value, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)#2}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)#2}&&, unsigned long, unsigned int) const Line | Count | Source | 752 | 75.3k | { | 753 | 75.3k | if (shift == max_shift<B>) { | 754 | 1.25k | auto fst = node->collisions(); | 755 | 1.25k | auto lst = fst + node->collision_count(); | 756 | 2.73k | for (; fst != lst; ++fst) | 757 | 2.27k | if (Equal{}(*fst, k)) | 758 | 789 | return {node_t::copy_collision_replace( | 759 | 789 | node, | 760 | 789 | fst, | 761 | 789 | Combine{}(std::forward<K>(k), | 762 | 789 | std::forward<Fn>(fn)(Project{}( | 763 | 789 | detail::as_const(*fst))))), | 764 | 789 | false}; | 765 | 466 | return {node_t::copy_collision_insert( | 766 | 466 | node, | 767 | 466 | Combine{}(std::forward<K>(k), | 768 | 466 | std::forward<Fn>(fn)(Default{}()))), | 769 | 466 | true}; | 770 | 74.0k | } else { | 771 | 74.0k | auto idx = (hash & (mask<B> << shift)) >> shift; | 772 | 74.0k | auto bit = bitmap_t{1u} << idx; | 773 | 74.0k | if (node->nodemap() & bit) { | 774 | 69.4k | auto offset = node->children_count(bit); | 775 | 69.4k | auto result = do_update<Project, Default, Combine>( | 776 | 69.4k | node->children()[offset], | 777 | 69.4k | k, | 778 | 69.4k | std::forward<Fn>(fn), | 779 | 69.4k | hash, | 780 | 69.4k | shift + B); | 781 | 69.4k | IMMER_TRY { | 782 | 69.4k | result.node = | 783 | 69.4k | node_t::copy_inner_replace(node, offset, result.node); | 784 | 69.4k | return result; | 785 | 69.4k | } | 786 | 69.4k | IMMER_CATCH (...) { | 787 | 0 | node_t::delete_deep_shift(result.node, shift + B); | 788 | 0 | IMMER_RETHROW; | 789 | 0 | } | 790 | 69.4k | } else if (node->datamap() & bit) { | 791 | 3.33k | auto offset = node->data_count(bit); | 792 | 3.33k | auto val = node->values() + offset; | 793 | 3.33k | if (Equal{}(*val, k)) | 794 | 2.10k | return {node_t::copy_inner_replace_value( | 795 | 2.10k | node, | 796 | 2.10k | offset, | 797 | 2.10k | Combine{}(std::forward<K>(k), | 798 | 2.10k | std::forward<Fn>(fn)(Project{}( | 799 | 2.10k | detail::as_const(*val))))), | 800 | 2.10k | false}; | 801 | 1.22k | else { | 802 | 1.22k | auto child = node_t::make_merged( | 803 | 1.22k | shift + B, | 804 | 1.22k | Combine{}(std::forward<K>(k), | 805 | 1.22k | std::forward<Fn>(fn)(Default{}())), | 806 | 1.22k | hash, | 807 | 1.22k | *val, | 808 | 1.22k | Hash{}(*val)); | 809 | 1.22k | IMMER_TRY { | 810 | 1.22k | return {node_t::copy_inner_replace_merged( | 811 | 1.22k | node, bit, offset, child), | 812 | 1.22k | true}; | 813 | 1.22k | } | 814 | 1.22k | IMMER_CATCH (...) { | 815 | 0 | node_t::delete_deep_shift(child, shift + B); | 816 | 0 | IMMER_RETHROW; | 817 | 0 | } | 818 | 1.22k | } | 819 | 3.33k | } else { | 820 | 1.26k | return {node_t::copy_inner_insert_value( | 821 | 1.26k | node, | 822 | 1.26k | bit, | 823 | 1.26k | Combine{}(std::forward<K>(k), | 824 | 1.26k | std::forward<Fn>(fn)(Default{}()))), | 825 | 1.26k | true}; | 826 | 1.26k | } | 827 | 74.0k | } | 828 | 75.3k | } |
|
829 | | |
830 | | template <typename Project, |
831 | | typename Default, |
832 | | typename Combine, |
833 | | typename K, |
834 | | typename Fn> |
835 | | champ update(const K& k, Fn&& fn) const |
836 | 231k | { |
837 | 231k | auto hash = Hash{}(k); |
838 | 231k | auto res = do_update<Project, Default, Combine>( |
839 | 231k | root, k, std::forward<Fn>(fn), hash, 0); |
840 | 231k | auto new_size = size + (res.added ? 1 : 0); |
841 | 231k | return {res.node, new_size}; |
842 | 231k | } |
843 | | |
844 | | template <typename Project, typename Combine, typename K, typename Fn> |
845 | | node_t* do_update_if_exists( |
846 | | node_t* node, K&& k, Fn&& fn, hash_t hash, shift_t shift) const |
847 | | { |
848 | | if (shift == max_shift<B>) { |
849 | | auto fst = node->collisions(); |
850 | | auto lst = fst + node->collision_count(); |
851 | | for (; fst != lst; ++fst) |
852 | | if (Equal{}(*fst, k)) |
853 | | return node_t::copy_collision_replace( |
854 | | node, |
855 | | fst, |
856 | | Combine{}(std::forward<K>(k), |
857 | | std::forward<Fn>(fn)( |
858 | | Project{}(detail::as_const(*fst))))); |
859 | | return nullptr; |
860 | | } else { |
861 | | auto idx = (hash & (mask<B> << shift)) >> shift; |
862 | | auto bit = bitmap_t{1u} << idx; |
863 | | if (node->nodemap() & bit) { |
864 | | auto offset = node->children_count(bit); |
865 | | auto result = do_update_if_exists<Project, Combine>( |
866 | | node->children()[offset], |
867 | | k, |
868 | | std::forward<Fn>(fn), |
869 | | hash, |
870 | | shift + B); |
871 | | IMMER_TRY { |
872 | | return result ? node_t::copy_inner_replace( |
873 | | node, offset, result) |
874 | | : nullptr; |
875 | | } |
876 | | IMMER_CATCH (...) { |
877 | | node_t::delete_deep_shift(result, shift + B); |
878 | | IMMER_RETHROW; |
879 | | } |
880 | | } else if (node->datamap() & bit) { |
881 | | auto offset = node->data_count(bit); |
882 | | auto val = node->values() + offset; |
883 | | if (Equal{}(*val, k)) |
884 | | return node_t::copy_inner_replace_value( |
885 | | node, |
886 | | offset, |
887 | | Combine{}(std::forward<K>(k), |
888 | | std::forward<Fn>(fn)( |
889 | | Project{}(detail::as_const(*val))))); |
890 | | else { |
891 | | return nullptr; |
892 | | } |
893 | | } else { |
894 | | return nullptr; |
895 | | } |
896 | | } |
897 | | } |
898 | | |
899 | | template <typename Project, typename Combine, typename K, typename Fn> |
900 | | champ update_if_exists(const K& k, Fn&& fn) const |
901 | | { |
902 | | auto hash = Hash{}(k); |
903 | | auto res = do_update_if_exists<Project, Combine>( |
904 | | root, k, std::forward<Fn>(fn), hash, 0); |
905 | | if (res) { |
906 | | return {res, size}; |
907 | | } else { |
908 | | return {root->inc(), size}; |
909 | | }; |
910 | | } |
911 | | |
912 | | using update_mut_result = add_mut_result; |
913 | | |
914 | | template <typename Project, |
915 | | typename Default, |
916 | | typename Combine, |
917 | | typename K, |
918 | | typename Fn> |
919 | | update_mut_result do_update_mut(edit_t e, |
920 | | node_t* node, |
921 | | K&& k, |
922 | | Fn&& fn, |
923 | | hash_t hash, |
924 | | shift_t shift) const |
925 | 1.22M | { |
926 | 1.22M | if (shift == max_shift<B>) { |
927 | 2.24k | auto fst = node->collisions(); |
928 | 2.24k | auto lst = fst + node->collision_count(); |
929 | 5.02k | for (; fst != lst; ++fst) |
930 | 4.66k | if (Equal{}(*fst, k)) { |
931 | 1.88k | if (node->can_mutate(e)) { |
932 | 1.68k | *fst = Combine{}( |
933 | 1.68k | std::forward<K>(k), |
934 | 1.68k | std::forward<Fn>(fn)(Project{}(std::move(*fst)))); |
935 | 1.68k | return {node, false, true}; |
936 | 1.68k | } else { |
937 | 196 | auto r = node_t::copy_collision_replace( |
938 | 196 | node, |
939 | 196 | fst, |
940 | 196 | Combine{}(std::forward<K>(k), |
941 | 196 | std::forward<Fn>(fn)( |
942 | 196 | Project{}(detail::as_const(*fst))))); |
943 | 196 | return {node_t::owned(r, e), false, false}; |
944 | 196 | } |
945 | 1.88k | } |
946 | 365 | auto v = Combine{}(std::forward<K>(k), |
947 | 365 | std::forward<Fn>(fn)(Default{}())); |
948 | 365 | auto mutate = node->can_mutate(e); |
949 | 365 | auto r = mutate ? node_t::move_collision_insert(node, std::move(v)) |
950 | 365 | : node_t::copy_collision_insert(node, std::move(v)); |
951 | 365 | return {node_t::owned(r, e), true, mutate}; |
952 | 1.22M | } else { |
953 | 1.22M | auto idx = (hash & (mask<B> << shift)) >> shift; |
954 | 1.22M | auto bit = bitmap_t{1u} << idx; |
955 | 1.22M | if (node->nodemap() & bit) { |
956 | 1.15M | auto offset = node->children_count(bit); |
957 | 1.15M | auto child = node->children()[offset]; |
958 | 1.15M | if (node->can_mutate(e)) { |
959 | 1.14M | auto result = do_update_mut<Project, Default, Combine>( |
960 | 1.14M | e, child, k, std::forward<Fn>(fn), hash, shift + B); |
961 | 1.14M | node->children()[offset] = result.node; |
962 | 1.14M | if (!result.mutated && child->dec()) |
963 | 0 | node_t::delete_deep_shift(child, shift + B); |
964 | 1.14M | return {node, result.added, true}; |
965 | 1.14M | } else { |
966 | 5.85k | auto result = do_update<Project, Default, Combine>( |
967 | 5.85k | child, k, std::forward<Fn>(fn), hash, shift + B); |
968 | 5.85k | IMMER_TRY { |
969 | 5.85k | result.node = node_t::copy_inner_replace( |
970 | 5.85k | node, offset, result.node); |
971 | 5.85k | node_t::owned(result.node, e); |
972 | 5.85k | return {result.node, result.added, false}; |
973 | 5.85k | } |
974 | 5.85k | IMMER_CATCH (...) { |
975 | 0 | node_t::delete_deep_shift(result.node, shift + B); |
976 | 0 | IMMER_RETHROW; |
977 | 0 | } |
978 | 5.85k | } |
979 | 1.15M | } else if (node->datamap() & bit) { |
980 | 66.0k | auto offset = node->data_count(bit); |
981 | 66.0k | auto val = node->values() + offset; |
982 | 66.0k | if (Equal{}(*val, k)) { |
983 | 61.2k | if (node->can_mutate(e)) { |
984 | 60.1k | auto vals = node->ensure_mutable_values(e); |
985 | 60.1k | vals[offset] = Combine{}(std::forward<K>(k), |
986 | 60.1k | std::forward<Fn>(fn)(Project{}( |
987 | 60.1k | std::move(vals[offset])))); |
988 | 60.1k | return {node, false, true}; |
989 | 60.1k | } else { |
990 | 1.13k | auto r = node_t::copy_inner_replace_value( |
991 | 1.13k | node, |
992 | 1.13k | offset, |
993 | 1.13k | Combine{}(std::forward<K>(k), |
994 | 1.13k | std::forward<Fn>(fn)( |
995 | 1.13k | Project{}(detail::as_const(*val))))); |
996 | 1.13k | return {node_t::owned_values(r, e), false, false}; |
997 | 1.13k | } |
998 | 61.2k | } else { |
999 | 4.73k | auto mutate = node->can_mutate(e); |
1000 | 4.73k | auto mutate_values = mutate && node->can_mutate_values(e); |
1001 | 4.73k | auto hash2 = Hash{}(*val); |
1002 | 4.73k | auto child = node_t::make_merged_e( |
1003 | 4.73k | e, |
1004 | 4.73k | shift + B, |
1005 | 4.73k | Combine{}(std::forward<K>(k), |
1006 | 4.73k | std::forward<Fn>(fn)(Default{}())), |
1007 | 4.73k | hash, |
1008 | 4.73k | mutate_values ? std::move(*val) : *val, |
1009 | 4.73k | hash2); |
1010 | 4.73k | IMMER_TRY { |
1011 | 4.73k | auto r = mutate ? node_t::move_inner_replace_merged( |
1012 | 3.51k | e, node, bit, offset, child) |
1013 | 4.73k | : node_t::copy_inner_replace_merged( |
1014 | 1.22k | node, bit, offset, child); |
1015 | 4.73k | return {node_t::owned_values_safe(r, e), true, mutate}; |
1016 | 4.73k | } |
1017 | 4.73k | IMMER_CATCH (...) { |
1018 | 0 | node_t::delete_deep_shift(child, shift + B); |
1019 | 0 | IMMER_RETHROW; |
1020 | 0 | } |
1021 | 4.73k | } |
1022 | 66.0k | } else { |
1023 | 5.64k | auto mutate = node->can_mutate(e); |
1024 | 5.64k | auto v = Combine{}(std::forward<K>(k), |
1025 | 5.64k | std::forward<Fn>(fn)(Default{}())); |
1026 | 5.64k | auto r = mutate ? node_t::move_inner_insert_value( |
1027 | 3.64k | e, node, bit, std::move(v)) |
1028 | 5.64k | : node_t::copy_inner_insert_value( |
1029 | 1.99k | node, bit, std::move(v)); |
1030 | 5.64k | return {node_t::owned_values(r, e), true, mutate}; |
1031 | 5.64k | } |
1032 | 1.22M | } |
1033 | 1.22M | } |
1034 | | |
1035 | | template <typename Project, |
1036 | | typename Default, |
1037 | | typename Combine, |
1038 | | typename K, |
1039 | | typename Fn> |
1040 | | void update_mut(edit_t e, const K& k, Fn&& fn) |
1041 | 79.7k | { |
1042 | 79.7k | auto hash = Hash{}(k); |
1043 | 79.7k | auto res = do_update_mut<Project, Default, Combine>( |
1044 | 79.7k | e, root, k, std::forward<Fn>(fn), hash, 0); |
1045 | 79.7k | if (!res.mutated && root->dec()) |
1046 | 0 | node_t::delete_deep(root, 0); |
1047 | 79.7k | root = res.node; |
1048 | 79.7k | size += res.added ? 1 : 0; |
1049 | 79.7k | } |
1050 | | |
1051 | | struct update_if_exists_mut_result |
1052 | | { |
1053 | | node_t* node; |
1054 | | bool mutated; |
1055 | | }; |
1056 | | |
1057 | | template <typename Project, typename Combine, typename K, typename Fn> |
1058 | | update_if_exists_mut_result do_update_if_exists_mut(edit_t e, |
1059 | | node_t* node, |
1060 | | K&& k, |
1061 | | Fn&& fn, |
1062 | | hash_t hash, |
1063 | | shift_t shift) const |
1064 | | { |
1065 | | if (shift == max_shift<B>) { |
1066 | | auto fst = node->collisions(); |
1067 | | auto lst = fst + node->collision_count(); |
1068 | | for (; fst != lst; ++fst) |
1069 | | if (Equal{}(*fst, k)) { |
1070 | | if (node->can_mutate(e)) { |
1071 | | *fst = Combine{}( |
1072 | | std::forward<K>(k), |
1073 | | std::forward<Fn>(fn)(Project{}(std::move(*fst)))); |
1074 | | return {node, true}; |
1075 | | } else { |
1076 | | auto r = node_t::copy_collision_replace( |
1077 | | node, |
1078 | | fst, |
1079 | | Combine{}(std::forward<K>(k), |
1080 | | std::forward<Fn>(fn)( |
1081 | | Project{}(detail::as_const(*fst))))); |
1082 | | return {node_t::owned(r, e), false}; |
1083 | | } |
1084 | | } |
1085 | | return {nullptr, false}; |
1086 | | } else { |
1087 | | auto idx = (hash & (mask<B> << shift)) >> shift; |
1088 | | auto bit = bitmap_t{1u} << idx; |
1089 | | if (node->nodemap() & bit) { |
1090 | | auto offset = node->children_count(bit); |
1091 | | auto child = node->children()[offset]; |
1092 | | if (node->can_mutate(e)) { |
1093 | | auto result = do_update_if_exists_mut<Project, Combine>( |
1094 | | e, child, k, std::forward<Fn>(fn), hash, shift + B); |
1095 | | if (result.node) { |
1096 | | node->children()[offset] = result.node; |
1097 | | if (!result.mutated && child->dec()) |
1098 | | node_t::delete_deep_shift(child, shift + B); |
1099 | | return {node, true}; |
1100 | | } else { |
1101 | | return {nullptr, false}; |
1102 | | } |
1103 | | } else { |
1104 | | auto result = do_update_if_exists<Project, Combine>( |
1105 | | child, k, std::forward<Fn>(fn), hash, shift + B); |
1106 | | IMMER_TRY { |
1107 | | if (result) { |
1108 | | result = node_t::copy_inner_replace( |
1109 | | node, offset, result); |
1110 | | node_t::owned(result, e); |
1111 | | return {result, false}; |
1112 | | } else { |
1113 | | return {nullptr, false}; |
1114 | | } |
1115 | | } |
1116 | | IMMER_CATCH (...) { |
1117 | | node_t::delete_deep_shift(result, shift + B); |
1118 | | IMMER_RETHROW; |
1119 | | } |
1120 | | } |
1121 | | } else if (node->datamap() & bit) { |
1122 | | auto offset = node->data_count(bit); |
1123 | | auto val = node->values() + offset; |
1124 | | if (Equal{}(*val, k)) { |
1125 | | if (node->can_mutate(e)) { |
1126 | | auto vals = node->ensure_mutable_values(e); |
1127 | | vals[offset] = Combine{}(std::forward<K>(k), |
1128 | | std::forward<Fn>(fn)(Project{}( |
1129 | | std::move(vals[offset])))); |
1130 | | return {node, true}; |
1131 | | } else { |
1132 | | auto r = node_t::copy_inner_replace_value( |
1133 | | node, |
1134 | | offset, |
1135 | | Combine{}(std::forward<K>(k), |
1136 | | std::forward<Fn>(fn)( |
1137 | | Project{}(detail::as_const(*val))))); |
1138 | | return {node_t::owned_values(r, e), false}; |
1139 | | } |
1140 | | } else { |
1141 | | return {nullptr, false}; |
1142 | | } |
1143 | | } else { |
1144 | | return {nullptr, false}; |
1145 | | } |
1146 | | } |
1147 | | } |
1148 | | |
1149 | | template <typename Project, typename Combine, typename K, typename Fn> |
1150 | | void update_if_exists_mut(edit_t e, const K& k, Fn&& fn) |
1151 | | { |
1152 | | auto hash = Hash{}(k); |
1153 | | auto res = do_update_if_exists_mut<Project, Combine>( |
1154 | | e, root, k, std::forward<Fn>(fn), hash, 0); |
1155 | | if (res.node) { |
1156 | | if (!res.mutated && root->dec()) |
1157 | | node_t::delete_deep(root, 0); |
1158 | | root = res.node; |
1159 | | } |
1160 | | } |
1161 | | |
1162 | | // basically: |
1163 | | // variant<monostate_t, T*, node_t*> |
1164 | | // boo bad we are not using... C++17 :'( |
1165 | | struct sub_result |
1166 | | { |
1167 | | enum kind_t |
1168 | | { |
1169 | | nothing, |
1170 | | singleton, |
1171 | | tree |
1172 | | }; |
1173 | | |
1174 | | union data_t |
1175 | | { |
1176 | | T* singleton; |
1177 | | node_t* tree; |
1178 | | }; |
1179 | | |
1180 | | kind_t kind; |
1181 | | data_t data; |
1182 | | |
1183 | | sub_result() |
1184 | 192k | : kind{nothing} {}; |
1185 | | sub_result(T* x) |
1186 | | : kind{singleton} |
1187 | 2.72k | { |
1188 | 2.72k | data.singleton = x; |
1189 | 2.72k | }; |
1190 | | sub_result(node_t* x) |
1191 | | : kind{tree} |
1192 | 99.3k | { |
1193 | 99.3k | data.tree = x; |
1194 | 99.3k | }; |
1195 | | }; |
1196 | | |
1197 | | template <typename K> |
1198 | | sub_result |
1199 | | do_sub(node_t* node, const K& k, hash_t hash, shift_t shift) const |
1200 | 305k | { |
1201 | 305k | if (shift == max_shift<B>) { |
1202 | 2.46k | auto fst = node->collisions(); |
1203 | 2.46k | auto lst = fst + node->collision_count(); |
1204 | 5.49k | for (auto cur = fst; cur != lst; ++cur) |
1205 | 4.92k | if (Equal{}(*cur, k)) |
1206 | 1.88k | return node->collision_count() > 2 |
1207 | 1.88k | ? node_t::copy_collision_remove(node, cur) |
1208 | 1.88k | : sub_result{fst + (cur == fst)}; |
1209 | 573 | #if !defined(_MSC_VER) |
1210 | | #if defined(__GNUC__) && !defined(__clang__) |
1211 | | #pragma GCC diagnostic push |
1212 | | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" |
1213 | | #endif |
1214 | 573 | #endif |
1215 | | // Apparently GCC is generating this warning sometimes when |
1216 | | // compiling the benchmarks. It makes however no sense at all. |
1217 | 573 | return {}; |
1218 | 2.46k | #if !defined(_MSC_VER) |
1219 | | #if defined(__GNUC__) && !defined(__clang__) |
1220 | | #pragma GCC diagnostic pop |
1221 | | #endif |
1222 | 2.46k | #endif |
1223 | 302k | } else { |
1224 | 302k | auto idx = (hash & (mask<B> << shift)) >> shift; |
1225 | 302k | auto bit = bitmap_t{1u} << idx; |
1226 | 302k | if (node->nodemap() & bit) { |
1227 | 285k | auto offset = node->children_count(bit); |
1228 | 285k | auto result = |
1229 | 285k | do_sub(node->children()[offset], k, hash, shift + B); |
1230 | 285k | switch (result.kind) { |
1231 | 178k | case sub_result::nothing: |
1232 | 178k | return {}; |
1233 | 13.4k | case sub_result::singleton: |
1234 | 13.4k | return node->datamap() == 0 && |
1235 | 13.4k | node->children_count() == 1 && shift > 0 |
1236 | 13.4k | ? result |
1237 | 13.4k | : node_t::copy_inner_replace_inline( |
1238 | 2.29k | node, bit, offset, *result.data.singleton); |
1239 | 93.1k | case sub_result::tree: |
1240 | 93.1k | IMMER_TRY { |
1241 | 93.1k | return node_t::copy_inner_replace( |
1242 | 93.1k | node, offset, result.data.tree); |
1243 | 93.1k | } |
1244 | 93.1k | IMMER_CATCH (...) { |
1245 | 0 | node_t::delete_deep_shift(result.data.tree, shift + B); |
1246 | 0 | IMMER_RETHROW; |
1247 | 0 | } |
1248 | 285k | } |
1249 | 285k | } else if (node->datamap() & bit) { |
1250 | 11.0k | auto offset = node->data_count(bit); |
1251 | 11.0k | auto val = node->values() + offset; |
1252 | 11.0k | if (Equal{}(*val, k)) { |
1253 | 4.73k | auto nv = node->data_count(); |
1254 | 4.73k | if (node->nodemap() || nv > 2) |
1255 | 2.50k | return node_t::copy_inner_remove_value( |
1256 | 2.50k | node, bit, offset); |
1257 | 2.22k | else if (nv == 2) { |
1258 | 2.00k | return shift > 0 ? sub_result{node->values() + !offset} |
1259 | 2.00k | : node_t::make_inner_n( |
1260 | 0 | 0, |
1261 | 0 | node->datamap() & ~bit, |
1262 | 0 | node->values()[!offset]); |
1263 | 2.00k | } else { |
1264 | 215 | assert(shift == 0); |
1265 | 0 | return empty(); |
1266 | 215 | } |
1267 | 4.73k | } |
1268 | 11.0k | } |
1269 | 12.8k | return {}; |
1270 | 302k | } |
1271 | 305k | } |
1272 | | |
1273 | | template <typename K> |
1274 | | champ sub(const K& k) const |
1275 | 18.5k | { |
1276 | 18.5k | auto hash = Hash{}(k); |
1277 | 18.5k | auto res = do_sub(root, k, hash, 0); |
1278 | 18.5k | switch (res.kind) { |
1279 | 12.8k | case sub_result::nothing: |
1280 | 12.8k | return *this; |
1281 | 5.72k | case sub_result::tree: |
1282 | 5.72k | return {res.data.tree, size - 1}; |
1283 | 0 | default: |
1284 | 0 | IMMER_UNREACHABLE; |
1285 | 18.5k | } |
1286 | 18.5k | } |
1287 | | |
1288 | | struct sub_result_mut |
1289 | | { |
1290 | | using kind_t = typename sub_result::kind_t; |
1291 | | using data_t = typename sub_result::data_t; |
1292 | | |
1293 | | kind_t kind; |
1294 | | data_t data; |
1295 | | bool owned; |
1296 | | bool mutated; |
1297 | | |
1298 | | sub_result_mut(sub_result a) |
1299 | | : kind{a.kind} |
1300 | | , data{a.data} |
1301 | | , owned{false} |
1302 | | , mutated{false} |
1303 | 1.48k | {} |
1304 | | sub_result_mut(sub_result a, bool m) |
1305 | | : kind{a.kind} |
1306 | | , data{a.data} |
1307 | | , owned{false} |
1308 | | , mutated{m} |
1309 | | {} |
1310 | | sub_result_mut() |
1311 | | : kind{kind_t::nothing} |
1312 | 56.9k | , mutated{false} {}; |
1313 | | sub_result_mut(T* x, bool m) |
1314 | | : kind{kind_t::singleton} |
1315 | | , owned{m} |
1316 | | , mutated{m} |
1317 | 2.70k | { |
1318 | 2.70k | data.singleton = x; |
1319 | 2.70k | }; |
1320 | | sub_result_mut(T* x, bool o, bool m) |
1321 | | : kind{kind_t::singleton} |
1322 | | , owned{o} |
1323 | | , mutated{m} |
1324 | 11.2k | { |
1325 | 11.2k | data.singleton = x; |
1326 | 11.2k | }; |
1327 | | sub_result_mut(node_t* x, bool m) |
1328 | | : kind{kind_t::tree} |
1329 | | , owned{false} |
1330 | | , mutated{m} |
1331 | 110k | { |
1332 | 110k | data.tree = x; |
1333 | 110k | }; |
1334 | | }; |
1335 | | |
1336 | | template <typename K> |
1337 | | sub_result_mut do_sub_mut(edit_t e, |
1338 | | node_t* node, |
1339 | | const K& k, |
1340 | | hash_t hash, |
1341 | | shift_t shift, |
1342 | | void* store) const |
1343 | 181k | { |
1344 | 181k | auto mutate = node->can_mutate(e); |
1345 | 181k | if (shift == max_shift<B>) { |
1346 | 2.25k | auto fst = node->collisions(); |
1347 | 2.25k | auto lst = fst + node->collision_count(); |
1348 | 5.23k | for (auto cur = fst; cur != lst; ++cur) { |
1349 | 4.56k | if (Equal{}(*cur, k)) { |
1350 | 1.57k | if (node->collision_count() <= 2) { |
1351 | 596 | if (mutate) { |
1352 | 340 | auto r = new (store) |
1353 | 340 | T{std::move(node->collisions()[cur == fst])}; |
1354 | 340 | node_t::delete_collision(node); |
1355 | 340 | return sub_result_mut{r, true}; |
1356 | 340 | } else { |
1357 | 256 | return sub_result_mut{fst + (cur == fst), false}; |
1358 | 256 | } |
1359 | 981 | } else { |
1360 | 981 | auto r = mutate |
1361 | 981 | ? node_t::move_collision_remove(node, cur) |
1362 | 981 | : node_t::copy_collision_remove(node, cur); |
1363 | 981 | return {node_t::owned(r, e), mutate}; |
1364 | 981 | } |
1365 | 1.57k | } |
1366 | 4.56k | } |
1367 | 676 | return {}; |
1368 | 179k | } else { |
1369 | 179k | auto idx = (hash & (mask<B> << shift)) >> shift; |
1370 | 179k | auto bit = bitmap_t{1u} << idx; |
1371 | 179k | if (node->nodemap() & bit) { |
1372 | 171k | auto offset = node->children_count(bit); |
1373 | 171k | auto children = node->children(); |
1374 | 171k | auto child = children[offset]; |
1375 | 171k | auto result = |
1376 | 171k | mutate ? do_sub_mut(e, child, k, hash, shift + B, store) |
1377 | 171k | : do_sub(child, k, hash, shift + B); |
1378 | 171k | switch (result.kind) { |
1379 | 53.2k | case sub_result::nothing: |
1380 | 53.2k | return {}; |
1381 | 14.3k | case sub_result::singleton: |
1382 | 14.3k | if (node->datamap() == 0 && node->children_count() == 1 && |
1383 | 14.3k | shift > 0) { |
1384 | 11.2k | if (mutate) { |
1385 | 11.0k | node_t::delete_inner(node); |
1386 | 11.0k | if (!result.mutated && child->dec()) |
1387 | 0 | node_t::delete_deep_shift(child, shift + B); |
1388 | 11.0k | } |
1389 | 11.2k | return {result.data.singleton, result.owned, mutate}; |
1390 | 11.2k | } else { |
1391 | 3.13k | auto r = |
1392 | 3.13k | mutate ? node_t::move_inner_replace_inline( |
1393 | 2.91k | e, |
1394 | 2.91k | node, |
1395 | 2.91k | bit, |
1396 | 2.91k | offset, |
1397 | 2.91k | result.owned |
1398 | 2.91k | ? std::move(*result.data.singleton) |
1399 | 2.91k | : *result.data.singleton) |
1400 | 3.13k | : node_t::copy_inner_replace_inline( |
1401 | 222 | node, |
1402 | 222 | bit, |
1403 | 222 | offset, |
1404 | 222 | *result.data.singleton); |
1405 | 3.13k | if (result.owned) |
1406 | 1.63k | detail::destroy_at(result.data.singleton); |
1407 | 3.13k | if (!result.mutated && mutate && child->dec()) |
1408 | 0 | node_t::delete_deep_shift(child, shift + B); |
1409 | 3.13k | return {node_t::owned_values(r, e), mutate}; |
1410 | 3.13k | } |
1411 | 104k | case sub_result::tree: |
1412 | 104k | if (mutate) { |
1413 | 103k | children[offset] = result.data.tree; |
1414 | 103k | if (!result.mutated && child->dec()) |
1415 | 0 | node_t::delete_deep_shift(child, shift + B); |
1416 | 103k | return {node, true}; |
1417 | 103k | } else { |
1418 | 472 | IMMER_TRY { |
1419 | 472 | auto r = node_t::copy_inner_replace( |
1420 | 472 | node, offset, result.data.tree); |
1421 | 472 | return {node_t::owned(r, e), false}; |
1422 | 472 | } |
1423 | 472 | IMMER_CATCH (...) { |
1424 | 0 | node_t::delete_deep_shift(result.data.tree, |
1425 | 0 | shift + B); |
1426 | 0 | IMMER_RETHROW; |
1427 | 0 | } |
1428 | 472 | } |
1429 | 171k | } |
1430 | 171k | } else if (node->datamap() & bit) { |
1431 | 6.23k | auto offset = node->data_count(bit); |
1432 | 6.23k | auto val = node->values() + offset; |
1433 | 6.23k | auto mutate_values = mutate && node->can_mutate_values(e); |
1434 | 6.23k | if (Equal{}(*val, k)) { |
1435 | 4.65k | auto nv = node->data_count(); |
1436 | 4.65k | if (node->nodemap() || nv > 2) { |
1437 | 2.14k | auto r = mutate ? node_t::move_inner_remove_value( |
1438 | 1.90k | e, node, bit, offset) |
1439 | 2.14k | : node_t::copy_inner_remove_value( |
1440 | 235 | node, bit, offset); |
1441 | 2.14k | return {node_t::owned_values_safe(r, e), mutate}; |
1442 | 2.51k | } else if (nv == 2) { |
1443 | 2.11k | if (shift > 0) { |
1444 | 2.11k | if (mutate_values) { |
1445 | 1.29k | auto r = new (store) |
1446 | 1.29k | T{std::move(node->values()[!offset])}; |
1447 | 1.29k | node_t::delete_inner(node); |
1448 | 1.29k | return {r, true}; |
1449 | 1.29k | } else { |
1450 | 818 | return {node->values() + !offset, false}; |
1451 | 818 | } |
1452 | 2.11k | } else { |
1453 | 0 | auto& v = node->values()[!offset]; |
1454 | 0 | auto r = node_t::make_inner_n( |
1455 | 0 | 0, |
1456 | 0 | node->datamap() & ~bit, |
1457 | 0 | mutate_values ? std::move(v) : v); |
1458 | 0 | assert(!node->nodemap()); |
1459 | 0 | if (mutate) |
1460 | 0 | node_t::delete_inner(node); |
1461 | 0 | return {node_t::owned_values(r, e), mutate}; |
1462 | 0 | } |
1463 | 2.11k | } else { |
1464 | 403 | assert(shift == 0); |
1465 | 403 | if (mutate) |
1466 | 208 | node_t::delete_inner(node); |
1467 | 403 | return {empty(), mutate}; |
1468 | 403 | } |
1469 | 4.65k | } |
1470 | 6.23k | } |
1471 | 3.10k | return {}; |
1472 | 179k | } |
1473 | 181k | } |
1474 | | |
1475 | | template <typename K> |
1476 | | void sub_mut(edit_t e, const K& k) |
1477 | 11.4k | { |
1478 | 11.4k | auto store = aligned_storage_for<T>{}; |
1479 | 11.4k | auto hash = Hash{}(k); |
1480 | 11.4k | auto res = do_sub_mut(e, root, k, hash, 0, &store); |
1481 | 11.4k | switch (res.kind) { |
1482 | 4.36k | case sub_result::nothing: |
1483 | 4.36k | break; |
1484 | 7.12k | case sub_result::tree: |
1485 | 7.12k | if (!res.mutated && root->dec()) |
1486 | 0 | node_t::delete_deep(root, 0); |
1487 | 7.12k | root = res.data.tree; |
1488 | 7.12k | --size; |
1489 | 7.12k | break; |
1490 | 0 | default: |
1491 | 0 | IMMER_UNREACHABLE; |
1492 | 11.4k | } |
1493 | 11.4k | } |
1494 | | |
1495 | | template <typename Eq = Equal> |
1496 | | bool equals(const champ& other) const |
1497 | | { |
1498 | | return size == other.size && equals_tree<Eq>(root, other.root, 0); |
1499 | | } |
1500 | | |
1501 | | template <typename Eq> |
1502 | | static bool equals_tree(const node_t* a, const node_t* b, count_t depth) |
1503 | | { |
1504 | | if (a == b) |
1505 | | return true; |
1506 | | else if (depth == max_depth<B>) { |
1507 | | auto nv = a->collision_count(); |
1508 | | return nv == b->collision_count() && |
1509 | | equals_collisions<Eq>(a->collisions(), b->collisions(), nv); |
1510 | | } else { |
1511 | | if (a->nodemap() != b->nodemap() || a->datamap() != b->datamap()) |
1512 | | return false; |
1513 | | auto n = a->children_count(); |
1514 | | for (auto i = count_t{}; i < n; ++i) |
1515 | | if (!equals_tree<Eq>( |
1516 | | a->children()[i], b->children()[i], depth + 1)) |
1517 | | return false; |
1518 | | auto nv = a->data_count(); |
1519 | | return !nv || equals_values<Eq>(a->values(), b->values(), nv); |
1520 | | } |
1521 | | } |
1522 | | |
1523 | | template <typename Eq> |
1524 | | static bool equals_values(const T* a, const T* b, count_t n) |
1525 | | { |
1526 | | return std::equal(a, a + n, b, Eq{}); |
1527 | | } |
1528 | | |
1529 | | template <typename Eq> |
1530 | | static bool equals_collisions(const T* a, const T* b, count_t n) |
1531 | | { |
1532 | | auto ae = a + n; |
1533 | | auto be = b + n; |
1534 | | for (; a != ae; ++a) { |
1535 | | for (auto fst = b; fst != be; ++fst) |
1536 | | if (Eq{}(*a, *fst)) |
1537 | | goto good; |
1538 | | return false; |
1539 | | good: |
1540 | | continue; |
1541 | | } |
1542 | | return true; |
1543 | | } |
1544 | | }; |
1545 | | |
1546 | | } // namespace hamts |
1547 | | } // namespace detail |
1548 | | } // namespace immer |