46 unsigned blockSize,
typename SearchStrategy,
bool isSet,
typename Functor,
47 typename WeakComparator =
Comparator,
typename Updater = detail::updater<Key>>
48 class LambdaBTree :
public btree<Key, Comparator, Allocator, blockSize, SearchStrategy, isSet, WeakComparator,
52 btree<Key, Comparator, Allocator, blockSize, SearchStrategy, isSet, WeakComparator, Updater>;
60 typename Functor::result_type
insert(Key&
k,
const Functor& f) {
66 typename Functor::result_type
insert(
71 while (this->
root ==
nullptr) {
79 if (this->
root !=
nullptr) {
86 this->
leftmost =
new typename parenttype::leaf_node();
89 typename Functor::result_type res = f(
k);
104 typename parenttype::node* cur =
nullptr;
107 typename parenttype::lock_type::Lease cur_lease;
109 auto checkHint = [&](
typename parenttype::node* last_insert) {
111 if (!last_insert)
return false;
113 auto hint_lease = last_insert->lock.start_read();
117 if (!last_insert->lock.validate(hint_lease))
return false;
121 cur_lease = hint_lease;
144 cur_lease = cur->lock.start_read();
157 auto a = &(cur->keys[0]);
158 auto b = &(cur->keys[cur->numElements]);
166 if (!cur->lock.validate(cur_lease)) {
172 if (
typeid(
Comparator) !=
typeid(WeakComparator) && this->
less(k, *pos)) {
173 if (!cur->lock.try_upgrade_to_write(cur_lease)) {
180 auto res = (*pos).second;
182 cur->lock.end_write();
187 auto res = (*pos).second;
190 if (!cur->lock.validate(cur_lease)) {
200 auto next = cur->getChild(idx);
203 auto next_lease = next->lock.start_read();
206 if (!cur->lock.end_read(cur_lease)) {
215 cur_lease = next_lease;
225 auto a = &(cur->keys[0]);
226 auto b = &(cur->keys[cur->numElements]);
232 if (isSet && pos != a && this->
weak_equal(*(pos - 1),
k)) {
234 if (!cur->lock.validate(cur_lease)) {
241 if (
typeid(
Comparator) !=
typeid(WeakComparator) && this->
less(k, *(pos - 1))) {
242 if (!cur->lock.try_upgrade_to_write(cur_lease)) {
249 auto res = (*(pos - 1)).second;
251 cur->lock.end_write();
256 std::atomic<typename Functor::result_type>& loc =
257 *
reinterpret_cast<std::atomic<typename Functor::result_type>*
>(&(*(pos - 1)).second);
258 auto res = loc.load(std::memory_order_relaxed);
261 if (!cur->lock.validate(cur_lease)) {
271 if (!cur->lock.try_upgrade_to_write(cur_lease)) {
280 auto parent = priv->parent;
281 std::vector<typename parenttype::node*> parents;
284 parent->lock.start_write();
287 if (parent == priv->parent) {
291 parent->lock.abort_write();
292 parent = priv->parent;
293 parent->lock.start_write();
301 parents.push_back(parent);
304 if (!parent || !parent->isFull()) {
310 parent = parent->parent;
315 auto old_root = this->
root;
316 idx -= cur->rebalance_or_split(
317 const_cast<typename parenttype::node**
>(&this->
root), this->
root_lock, idx, parents);
320 for (
auto it = parents.rbegin(); it != parents.rend(); ++it) {
325 parent->lock.end_write();
327 if (old_root != this->
root) {
338 cur->lock.end_write();
349 for (
int j = cur->numElements;
j > idx; --
j) {
350 cur->keys[
j] = cur->keys[
j - 1];
354 typename Functor::result_type res = f(
k);
359 cur->lock.end_write();
370 this->
leftmost =
new typename parenttype::leaf_node();
373 typename Functor::result_type res = f(
k);
383 typename parenttype::node* cur = this->
root;
385 auto checkHints = [&](
typename parenttype::node* last_insert) {
386 if (!last_insert)
return false;
402 auto a = &(cur->keys[0]);
403 auto b = &(cur->keys[cur->numElements]);
411 if (
typeid(
Comparator) !=
typeid(WeakComparator) && this->
less(k, *pos)) {
413 return (*pos).second;
416 return (*pos).second;
419 cur = cur->getChild(idx);
428 auto a = &(cur->keys[0]);
429 auto b = &(cur->keys[cur->numElements]);
435 if (isSet && pos != a && this->
weak_equal(*(pos - 1),
k)) {
437 if (
typeid(
Comparator) !=
typeid(WeakComparator) && this->
less(k, *(pos - 1))) {
439 return (*(pos - 1)).second;
442 return (*(pos - 1)).second;
447 idx -= cur->rebalance_or_split(
448 const_cast<typename parenttype::node**
>(&this->
root), this->
root_lock, idx);
452 idx -= cur->numElements + 1;
453 cur = cur->parent->getChild(cur->position + 1);
461 for (
int j = cur->numElements;
j > idx; --
j) {
462 cur->keys[
j] = cur->keys[
j - 1];
466 typename Functor::result_type res = f(
k);
481 template <
typename Iter>
482 void insert(
const Iter& a,
const Iter&
b) {
486 for (
auto it = a; it !=
b; ++it) {
499 std::swap(this->
root, other.root);
500 std::swap(this->
leftmost, other.leftmost);
506 if (
this == &other) {
517 this->
root = other.root->clone();
520 auto tmp = this->
root;
521 while (!tmp->isLeaf()) {
522 tmp = tmp->getChild(0);
524 this->
leftmost =
static_cast<typename parenttype::leaf_node*
>(tmp);
533 if (
this == &other) {
538 if (this->
size() != other.size()) {
541 if (this->
size() < other.size()) {
542 return other == *
this;
546 for (
const auto& key : other) {
556 return !(*
this == other);
572 template <
typename Key,
typename Functor,
typename Comparator = detail::comparator<Key>,
573 typename Allocator = std::allocator<Key>,
574 unsigned blockSize = 256,
typename SearchStrategy =
typename detail::default_strategy<Key>::type>
576 :
public detail::LambdaBTree<Key, Comparator, Allocator, blockSize, SearchStrategy, true, Functor> {
590 template <
typename Iter>
603 template <
typename s,
typename n,
typename l>
614 template <
typename Iter>
616 return super::template load<LambdaBTreeSet>(a,
b);