Confluent Sets and Maps
set.h
1 /*
2  * Copyright (c) 2017 Olle Liljenzin
3  */
4 
5 #ifndef CONFLUENT_SET_H_INCLUDED
6 #define CONFLUENT_SET_H_INCLUDED
7 
8 #include <atomic>
9 #include <cassert>
10 #include <functional>
11 #include <initializer_list>
12 #include <iterator>
13 #include <memory>
14 #include <mutex>
15 #include <utility>
16 #include <vector>
17 
18 namespace confluent {
19 
21 
22 template <class T, class Compare, class Hash, class Equal>
23 class set_provider;
24 
25 template <class T, class Compare, class Hash, class Equal>
26 class set;
27 
28 template <class Key,
29  class T,
30  class Compare,
31  class Hash,
32  class Equal,
33  class MappedHash,
34  class MappedEqual>
35 class map;
36 
37 namespace internal {
38 
39 // Thomas Wang's 32 bit mix function
40 inline std::uint32_t intmix(std::uint32_t key) {
41  key = ~key + (key << 15); // key = (key << 15) - key - 1;
42  key = key ^ (key >> 12);
43  key = key + (key << 2);
44  key = key ^ (key >> 4);
45  key = key * 2057; // key = (key + (key << 3)) + (key << 11);
46  key = key ^ (key >> 16);
47  return key;
48 }
49 
50 // Thomas Wang's 64 bit mix function
51 inline std::uint64_t intmix(std::uint64_t key) {
52  key = (~key) + (key << 21); // key = (key << 21) - key - 1;
53  key = key ^ (key >> 24);
54  key = (key + (key << 3)) + (key << 8); // key * 265
55  key = key ^ (key >> 14);
56  key = (key + (key << 2)) + (key << 4); // key * 21
57  key = key ^ (key >> 28);
58  key = key + (key << 31);
59  return key;
60 }
61 
62 inline size_t hash_combine(size_t h1, size_t h2) {
63  return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
64 }
65 
66 inline size_t hash_combine(size_t h1, size_t h2, size_t h3) {
67  return hash_combine(hash_combine(h1, h2), h3);
68 }
69 
70 template <class Traits, class Category = typename Traits::category>
71 struct env;
72 
73 template <class Traits, class Category = typename Traits::category>
74 struct node;
75 
76 template <class Traits>
77 struct node_ptr;
78 
79 template <class Traits>
80 struct node_ptr {
81  node_ptr() : node_(nullptr) {}
82  node_ptr(std::nullptr_t) : node_(nullptr) {}
83 
84  explicit node_ptr(node<Traits>* p, bool add_ref = true) : node_(p) {
85  if (add_ref && p)
86  incref(p);
87  }
88 
89  node_ptr(const node_ptr& other) : node_(other.node_) {
90  if (node_)
91  incref(node_);
92  }
93 
94  node_ptr(node_ptr&& other) : node_(other.node_) { other.node_ = nullptr; }
95 
96  ~node_ptr() {
97  if (node_ && !decref(node_))
98  delete node_;
99  }
100 
101  node_ptr& operator=(const node_ptr& other) {
102  reset(other.node_);
103  return *this;
104  }
105 
106  node_ptr& operator=(node_ptr&& other) {
107  if (node_ && !decref(node_))
108  delete node_;
109  node_ = other.node_;
110  other.node_ = nullptr;
111  return *this;
112  }
113 
114  void reset(node<Traits>* p = nullptr, bool add_ref = true) {
115  if (node_ != p) {
116  if (add_ref && p)
117  incref(p);
118  if (node_ && !decref(node_))
119  delete node_;
120  node_ = p;
121  }
122  }
123 
124  void swap(node_ptr& other) { std::swap(node_, other.node_); }
125 
126  node<Traits>& operator*() const { return *node_; }
127  node<Traits>* operator->() const { return node_; }
128 
129  bool operator==(const node_ptr& other) const { return node_ == other.node_; }
130 
131  bool operator!=(const node_ptr& other) const { return node_ != other.node_; }
132 
133  node<Traits>* get() const { return node_; }
134 
135  explicit operator bool() const { return node_; }
136 
137  void incref(node<Traits>* p) const {
138  p->reference_count_.fetch_add(1, std::memory_order_relaxed);
139  }
140 
141  size_t decref(node<Traits>* p) const {
142  size_t count = p->reference_count_.load(std::memory_order_relaxed);
143  while (1) {
144  if (count == 1) {
145  std::lock_guard<std::mutex> lock(env<Traits>::get_hash_table().mutex_);
146  if (p->reference_count_.compare_exchange_strong(
147  count, 0, std::memory_order_relaxed)) {
148  env<Traits>::get_hash_table().erase(p);
149  return 0;
150  }
151  } else {
152  if (p->reference_count_.compare_exchange_weak(
153  count, count - 1, std::memory_order_relaxed))
154  return 1;
155  }
156  }
157  }
158 
159  static const node_ptr null_;
160 
161  node<Traits>* node_;
162 };
163 
164 template <class Traits>
165 const node_ptr<Traits> node_ptr<Traits>::null_;
166 
167 template <class Traits>
168 struct hash_table {
169  hash_table()
170  : buckets_(alloc(min_bucket_count_)),
171  bucket_count_(min_bucket_count_),
172  size_(0) {}
173 
174  node<Traits>* insert(node<Traits>* key) {
175  rehash();
176  node<Traits>** p = &buckets_[pos(key)];
177  while (*p) {
178  if ((*p)->hash_ == key->hash_ && (*p)->left_ == key->left_ &&
179  (*p)->right_ == key->right_ &&
180  env<Traits>::equal((*p)->value(), key->value()))
181  return *p;
182  p = &(*p)->next_;
183  }
184  *p = key;
185  key->next_ = nullptr;
186  ++size_;
187  return key;
188  }
189 
190  void erase(node<Traits>* key) {
191  node<Traits>** p = &buckets_[pos(key)];
192  while (*p != key)
193  p = &(*p)->next_;
194  *p = key->next_;
195  --size_;
196  }
197 
198  void rehash() {
199  if (size_ >= bucket_count_)
200  extend();
201  else if (size_ > min_bucket_count_ && (size_ << 1) < bucket_count_)
202  reduce();
203  }
204 
205  static std::unique_ptr<node<Traits>* []> alloc(size_t bucket_count) {
206  std::unique_ptr<node<Traits>*[]> buckets(new node<Traits>*[bucket_count]);
207  std::fill(buckets.get(), buckets.get() + bucket_count, nullptr);
208  return buckets;
209  }
210 
211  size_t pos(node<Traits>* key) const {
212  return key->hash_ & (bucket_count_ - 1);
213  }
214 
215  void extend() {
216  bucket_count_ *= 2;
217  std::unique_ptr<node<Traits>*[]> new_buckets = alloc(bucket_count_);
218  std::fill(new_buckets.get(), new_buckets.get() + bucket_count_, nullptr);
219  for (size_t i = 0; i < bucket_count_ / 2; ++i) {
220  node<Traits>* head = buckets_[i];
221  while (head) {
222  node<Traits>* next = head->next_;
223  size_t j = pos(head);
224  head->next_ = new_buckets[j];
225  new_buckets[j] = head;
226  head = next;
227  }
228  }
229  swap(buckets_, new_buckets);
230  }
231 
232  void reduce() {
233  bucket_count_ /= 2;
234  std::unique_ptr<node<Traits>*[]> new_buckets(
235  new node<Traits>*[bucket_count_]);
236  for (size_t i = 0; i < bucket_count_; ++i) {
237  node<Traits>* low_head = buckets_[i];
238  node<Traits>* high_head = buckets_[i + bucket_count_];
239  if (low_head) {
240  new_buckets[i] = low_head;
241  while (low_head->next_)
242  low_head = low_head->next_;
243  low_head->next_ = high_head;
244  } else {
245  new_buckets[i] = high_head;
246  }
247  }
248  swap(buckets_, new_buckets);
249  }
250 
251  // Initial size. Must be power of two.
252  static constexpr size_t min_bucket_count_ = 1 << 3;
253 
254  mutable std::mutex mutex_;
255  std::unique_ptr<node<Traits>*[]> buckets_;
256  size_t bucket_count_;
257  size_t size_;
258 };
259 
260 template <class Traits>
261 struct env_base {
262  env_base(typename Traits::provider* provider) : saved_provider_(provider_) {
263  provider_ = provider;
264  }
265 
266  env_base(const env_base&) = delete;
267 
268  ~env_base() { provider_ = saved_provider_; }
269 
270  void silence_unused_warning() const {}
271 
272  static hash_table<Traits>& get_hash_table() { return provider_->hash_table_; }
273 
274  typename Traits::provider* const saved_provider_;
275 
276  static thread_local typename Traits::provider* provider_;
277 };
278 
279 template <class Traits>
280 thread_local typename Traits::provider* env_base<Traits>::provider_;
281 
282 enum class ranking { LEFT = -1, SAME = 0, RIGHT = 1, NOT_SAME };
283 
284 template <class Traits>
285 size_t hash(const node<Traits>* p) {
286  return p ? p->hash_ : 0;
287 }
288 
289 template <class Traits>
290 size_t hash(const node_ptr<Traits>& p) {
291  return p ? p->hash_ : 0;
292 }
293 
294 template <class Traits>
295 size_t size(const node<Traits>* p) {
296  return p ? p->size() : 0;
297 }
298 
299 template <class Traits>
300 size_t size(const node_ptr<Traits>& p) {
301  return p ? p->size() : 0;
302 }
303 
304 template <class Traits>
305 const node<Traits>* at_index(const node<Traits>* p, size_t k) {
306  assert(k < size(p));
307 
308  while (true) {
309  while (k > size(p->left_)) {
310  k -= size(p->left_) + 1;
311  p = p->right_.get();
312  }
313  while (k < size(p->left_))
314  p = p->left_.get();
315  if (k == size(p->left_))
316  return p;
317  };
318 }
319 
320 template <class Traits, class Comparer>
321 std::pair<const node<Traits>*, size_t> lower_bound(const node<Traits>* p,
322  Comparer comparer) {
323  std::pair<const node<Traits>*, size_t> best = {nullptr, size(p)};
324  size_t pos = 0;
325 
326  while (p) {
327  if (comparer(*p)) {
328  pos += size(p->left_) + 1;
329  p = p->right_.get();
330  } else {
331  best = {p, pos + size(p->left_)};
332  p = p->left_.get();
333  }
334  };
335  return best;
336 }
337 
338 struct set_tag {};
339 
340 template <class Traits>
341 void reset(const env<Traits>& env, node_ptr<Traits>* p) {
342  env.silence_unused_warning();
343  p->reset();
344 }
345 
346 template <class Traits>
347 node_ptr<Traits> get_unique_node(const env<Traits>& env,
348  std::unique_ptr<node<Traits>> p) {
349  std::lock_guard<std::mutex> lock(env.get_hash_table().mutex_);
350  node<Traits>* q = env.get_hash_table().insert(p.get());
351  return q == p.get() ? node_ptr<Traits>(p.release(), false)
352  : node_ptr<Traits>(q);
353 }
354 
355 template <class Traits>
356 node_ptr<Traits> make_node(const env<Traits, set_tag>& env,
357  const typename Traits::value_type& value,
358  node_ptr<Traits> left = nullptr,
359  node_ptr<Traits> right = nullptr) {
360  return node<Traits>::create(env, value, std::move(left), std::move(right),
361  intmix(env.hash(value)));
362 }
363 
364 template <class Traits>
365 node_ptr<Traits> make_node(const env<Traits, set_tag>& env,
366  const node<Traits>& parent,
367  node_ptr<Traits> left,
368  node_ptr<Traits> right) {
369  return node<Traits>::create(env, parent.value(), std::move(left),
370  std::move(right), parent.priority());
371 }
372 
373 template <class Traits>
374 ranking rank(const env<Traits>& env,
375  const node<Traits>& left,
376  const node<Traits>& right) {
377  if (left.priority() < right.priority())
378  return ranking::LEFT;
379  if (right.priority() < left.priority())
380  return ranking::RIGHT;
381  if (env.compare(left.key(), right.key()))
382  return ranking::LEFT;
383  if (env.compare(right.key(), left.key()))
384  return ranking::RIGHT;
385  return ranking::SAME;
386 }
387 
388 template <class Traits, class Parent, class Child>
389 node_ptr<Traits> replace_left(const env<Traits>& env,
390  Parent&& parent,
391  Child&& child) {
392  if (parent->left_ == child)
393  return std::forward<Parent>(parent);
394  return make_node(env, *parent, std::forward<Child>(child), parent->right_);
395 }
396 
397 template <class Traits, class Parent, class Child>
398 node_ptr<Traits> replace_right(const env<Traits>& env,
399  Parent&& parent,
400  Child&& child) {
401  if (parent->right_ == child)
402  return std::forward<Parent>(parent);
403  return make_node(env, *parent, parent->left_, std::forward<Child>(child));
404 }
405 
406 template <class Traits, class Left, class Right>
407 node_ptr<Traits> join(const env<Traits>& env, Left&& left, Right&& right) {
408  if (!left)
409  return std::forward<Right>(right);
410  if (!right)
411  return std::forward<Left>(left);
412  switch (rank(env, *left, *right)) {
413  case ranking::LEFT:
414  return replace_right(env, left,
415  join(env, left->right_, std::forward<Right>(right)));
416  case ranking::RIGHT:
417  return replace_left(env, right,
418  join(env, std::forward<Left>(left), right->left_));
419 
420  default:
421  /* keys should never compare equal in join() */
422  assert(false);
423  return nullptr;
424  }
425 }
426 
427 template <class Traits, class NodePtr>
428 std::pair<node_ptr<Traits>, node_ptr<Traits>> split(
429  const env<Traits>& env,
430  NodePtr&& p,
431  const typename Traits::key_type& key) {
432  if (!p)
433  return {};
434  if (env.compare(p->key(), key)) {
435  auto s = split(env, p->right_, key);
436  return {replace_right(env, std::forward<NodePtr>(p), std::move(s.first)),
437  std::move(s.second)};
438  } else {
439  auto s = split(env, p->left_, key);
440  return {std::move(s.first),
441  replace_left(env, std::forward<NodePtr>(p), std::move(s.second))};
442  }
443 }
444 
445 template <class Traits, class Left, class Right>
446 node_ptr<Traits> set_union(const env<Traits>& env, Left&& left, Right&& right) {
447  if (left == right || !right)
448  return std::forward<Left>(left);
449  if (!left)
450  return std::forward<Right>(right);
451  switch (rank(env, *left, *right)) {
452  case ranking::LEFT: {
453  auto s = split(env, std::forward<Right>(right), left->key());
454  return make_node(env, *left,
455  set_union(env, left->left_, std::move(s.first)),
456  set_union(env, left->right_, std::move(s.second)));
457  }
458  case ranking::RIGHT: {
459  auto s = split(env, std::forward<Left>(left), right->key());
460  return make_node(env, *right,
461  set_union(env, std::move(s.first), right->left_),
462  set_union(env, std::move(s.second), right->right_));
463  }
464  default: {
465  return make_node(env, *left, set_union(env, left->left_, right->left_),
466  set_union(env, left->right_, right->right_));
467  }
468  }
469 }
470 
471 template <class Traits, class Rank, class Left, class Right>
472 node_ptr<Traits> set_intersection(const env<Traits>& env,
473  Rank ranker,
474  Left&& left,
475  Right&& right) {
476  if (!left || !right)
477  return nullptr;
478  if (left == right)
479  return std::forward<Left>(left);
480  switch (ranker(env, *left, *right)) {
481  case ranking::LEFT: {
482  auto s = split(env, std::forward<Right>(right), left->key());
483  return join(
484  env, set_intersection(env, ranker, left->left_, std::move(s.first)),
485  set_intersection(env, ranker, left->right_, std::move(s.second)));
486  }
487  case ranking::RIGHT: {
488  auto s = split(env, std::forward<Left>(left), right->key());
489  return join(
490  env, set_intersection(env, ranker, std::move(s.first), right->left_),
491  set_intersection(env, ranker, std::move(s.second), right->right_));
492  }
493  case ranking::NOT_SAME: {
494  return join(env, set_intersection(env, ranker, left->left_, right->left_),
495  set_intersection(env, ranker, left->right_, right->right_));
496  }
497  default: {
498  return make_node(
499  env, *left, set_intersection(env, ranker, left->left_, right->left_),
500  set_intersection(env, ranker, left->right_, right->right_));
501  }
502  }
503 }
504 
505 template <class Traits, class Rank, class Left, class Right>
506 node_ptr<Traits> set_difference(const env<Traits>& env,
507  Rank ranker,
508  Left&& left,
509  Right&& right) {
510  if (left == right || !left)
511  return nullptr;
512  if (!right)
513  return std::forward<Left>(left);
514  switch (ranker(env, *left, *right)) {
515  case ranking::LEFT: {
516  auto s = split(env, std::forward<Right>(right), left->key());
517  return make_node(
518  env, *left,
519  set_difference(env, ranker, left->left_, std::move(s.first)),
520  set_difference(env, ranker, left->right_, std::move(s.second)));
521  }
522  case ranking::RIGHT: {
523  auto s = split(env, std::forward<Left>(left), right->key());
524  return join(
525  env, set_difference(env, ranker, std::move(s.first), right->left_),
526  set_difference(env, ranker, std::move(s.second), right->right_));
527  }
528  case ranking::NOT_SAME: {
529  return make_node(
530  env, *left, set_difference(env, ranker, left->left_, right->left_),
531  set_difference(env, ranker, left->right_, right->right_));
532  }
533  default: {
534  return join(env, set_difference(env, ranker, left->left_, right->left_),
535  set_difference(env, ranker, left->right_, right->right_));
536  }
537  }
538 }
539 
540 template <class Traits, class Left, class Right>
541 node_ptr<Traits> set_symmetric(const env<Traits>& env,
542  Left&& left,
543  Right&& right) {
544  if (!left)
545  return std::forward<Right>(right);
546  if (!right)
547  return std::forward<Left>(left);
548  if (left == right)
549  return nullptr;
550  switch (rank(env, *left, *right)) {
551  case ranking::LEFT: {
552  auto s = split(env, std::forward<Right>(right), left->key());
553  return make_node(env, *left,
554  set_symmetric(env, left->left_, std::move(s.first)),
555  set_symmetric(env, left->right_, std::move(s.second)));
556  }
557  case ranking::RIGHT: {
558  auto s = split(env, std::forward<Left>(left), right->key());
559  return make_node(env, *right,
560  set_symmetric(env, std::move(s.first), right->left_),
561  set_symmetric(env, std::move(s.second), right->right_));
562  }
563  default: {
564  return join(env, set_symmetric(env, left->left_, right->left_),
565  set_symmetric(env, left->right_, right->right_));
566  }
567  }
568 }
569 
570 template <class Traits, class Rank, class Left, class Right>
571 bool includes(const env<Traits>& env, Rank ranker, Left&& left, Right&& right) {
572  if (left == right || !right)
573  return true;
574 
575  if (size(left) < size(right))
576  return false;
577 
578  switch (ranker(env, *left, *right)) {
579  case ranking::LEFT: {
580  auto s = split(env, std::forward<Right>(right), left->key());
581  return includes(env, ranker, left->left_, std::move(s.first)) &&
582  includes(env, ranker, left->right_, std::move(s.second));
583  }
584  case ranking::SAME: {
585  return includes(env, ranker, left->left_, right->left_) &&
586  includes(env, ranker, left->right_, right->right_);
587  }
588  default: {
589  return false;
590  }
591  }
592 }
593 
594 template <class Traits, class InputIterator>
595 node_ptr<Traits> make_node(const env<Traits>& env,
596  InputIterator* first,
597  InputIterator last,
598  size_t max_depth) {
599  if (*first == last)
600  return nullptr;
601  node_ptr<Traits> root = make_node(env, **first);
602  ++*first;
603  for (size_t depth = 0; depth < max_depth; ++depth) {
604  node_ptr<Traits> branch = make_node(env, first, last, depth);
605  if (!branch)
606  break;
607  root = set_union(env, std::move(root), std::move(branch));
608  }
609  return root;
610 }
611 
612 template <class Traits, class InputIterator>
613 node_ptr<Traits> make_node(const env<Traits>& env,
614  InputIterator first,
615  InputIterator last) {
616  InputIterator it = first;
617  return make_node(env, &it, last, std::numeric_limits<size_t>::max());
618 }
619 
620 template <class Traits, class NodePtr>
621 size_t add(const env<Traits>& env, node_ptr<Traits>* p, NodePtr&& q) {
622  size_t n = size(*p);
623  *p = set_union(env, *p, std::forward<NodePtr>(q));
624  return size(*p) - n;
625 }
626 
627 template <class Traits, class Rank, class NodePtr>
628 size_t diff(const env<Traits>& env,
629  Rank ranker,
630  node_ptr<Traits>* p,
631  NodePtr&& q) {
632  size_t n = size(*p);
633  *p = set_difference(env, ranker, *p, std::forward<NodePtr>(q));
634  return n - size(*p);
635 }
636 
637 template <class Traits>
638 size_t erase(const env<Traits>& env,
639  node_ptr<Traits>* p,
640  size_t first,
641  size_t last) {
642  size_t n = size(*p);
643  *p = join(env, head(env, p, first), tail(env, p, last));
644  return n - size(*p);
645 }
646 
647 template <class Traits, class Rank, class NodePtr>
648 size_t intersect(const env<Traits>& env,
649  Rank ranker,
650  node_ptr<Traits>* p,
651  NodePtr&& q) {
652  size_t n = size(*p);
653  *p = set_intersection(env, ranker, *p, std::forward<NodePtr>(q));
654  return n - size(*p);
655 }
656 
657 template <class Traits>
658 size_t insert(const env<Traits>& env,
659  node_ptr<Traits>* p,
660  const typename Traits::value_type& value) {
661  return add(env, p, make_node(env, value));
662 }
663 
664 template <class Traits, class InputIterator>
665 size_t insert(const env<Traits>& env,
666  node_ptr<Traits>* p,
667  InputIterator first,
668  InputIterator last) {
669  return add(env, p, make_node(env, first, last));
670 }
671 
672 template <class Traits, class InputIterator>
673 void assign(const env<Traits>& env,
674  node_ptr<Traits>* p,
675  InputIterator first,
676  InputIterator last) {
677  *p = make_node(env, first, last);
678 }
679 
680 template <class Traits, class Key>
681 std::pair<node_ptr<Traits>, bool> erase(const env<Traits>& env,
682  const node_ptr<Traits>& p,
683  const Key& key) {
684  if (!p)
685  return {nullptr, false};
686  if (env.compare(p->value(), key)) {
687  auto s = erase(env, p->right_, key);
688  if (s.second)
689  return {replace_right(env, p, std::move(s.first)), true};
690  return {p, false};
691  }
692  auto s = erase(env, p->left_, key);
693  if (s.second)
694  return {replace_left(env, p, std::move(s.first)), true};
695  if (!env.equal(p->value(), key))
696  return {p, true};
697  return {join(env, p->left_, p->right_), true};
698 }
699 
700 template <class Traits, class Key>
701 size_t erase(const env<Traits>& env, node_ptr<Traits>* p, const Key& key) {
702  size_t n = size(*p);
703  *p = erase(env, *p, key).first;
704  return n - size(*p);
705 }
706 
707 template <class Traits>
708 size_t retain(const env<Traits>& env,
709  node_ptr<Traits>* p,
710  size_t first,
711  size_t last) {
712  size_t n = size(*p);
713  node_ptr<Traits> h = head(env, p, last);
714  *p = tail(env, &h, first);
715  return n - size(*p);
716 }
717 
718 template <class Traits>
719 void symmetric(const env<Traits>& env,
720  node_ptr<Traits>* p,
721  const node_ptr<Traits>& q) {
722  *p = set_symmetric(env, *p, q);
723 }
724 
725 template <class Traits>
726 node_ptr<Traits> tail(const env<Traits>& env,
727  const node_ptr<Traits>* p,
728  size_t first) {
729  while (*p && first > size((*p)->left_)) {
730  first -= size((*p)->left_) + 1;
731  p = &(*p)->right_;
732  }
733  return first ? replace_left(env, *p, tail(env, &(*p)->left_, first)) : *p;
734 }
735 
736 template <class Traits>
737 node_ptr<Traits> head(const env<Traits>& env,
738  const node_ptr<Traits>* p,
739  size_t last) {
740  while (*p && last <= size((*p)->left_)) {
741  p = &(*p)->left_;
742  }
743  return last == size(*p) ? *p
744  : replace_right(env, *p,
745  head(env, &(*p)->right_,
746  last - size((*p)->left_) - 1));
747 }
748 
749 template <class T, class Compare, class Hash, class Equal>
750 struct set_traits {
751  typedef set_tag category;
752  typedef T key_type;
753  typedef T value_type;
754  typedef set_provider<T, Compare, Hash, Equal> provider;
755  typedef set<T, Compare, Hash, Equal> container;
756 };
757 
758 template <class Traits>
759 struct node<Traits, set_tag> {
760  typedef typename Traits::key_type key_type;
761  typedef typename Traits::value_type value_type;
762  typedef node_ptr<Traits> ptr_type;
763  typedef env<Traits> env_type;
764 
765  node(const value_type& value,
766  size_t priority,
767  size_t sz,
768  ptr_type left,
769  ptr_type right,
770  size_t h)
771  : reference_count_(1),
772  value_(value),
773  priority_(priority),
774  size_(sz),
775  hash_(h),
776  left_(std::move(left)),
777  right_(std::move(right)) {}
778 
779  static ptr_type create(const env_type& env,
780  const value_type& value,
781  ptr_type left,
782  ptr_type right,
783  size_t priority) {
784  size_t sz = 1 + internal::size(left) + internal::size(right);
785  size_t h = hash_combine(hash(left), hash(right), priority);
786  std::unique_ptr<node> p(
787  new node(value, priority, sz, std::move(left), std::move(right), h));
788  return get_unique_node(env, std::move(p));
789  }
790 
791  const key_type& key() const { return value_; }
792  const value_type& value() const { return value_; }
793  size_t priority() const { return priority_; }
794  size_t size() const { return size_; }
795 
796  std::atomic<size_t> reference_count_;
797  node* next_;
798  const value_type value_;
799  const size_t priority_;
800  const size_t size_;
801  const size_t hash_;
802  const ptr_type left_;
803  const ptr_type right_;
804 };
805 
806 template <class Traits>
807 struct env<Traits, set_tag> : env_base<Traits> {
808  typedef typename Traits::provider provider_type;
809  typedef typename Traits::key_type key_type;
810  typedef hash_table<Traits> hash_table_type;
811 
812  using env_base<Traits>::env_base;
813  using env_base<Traits>::provider_;
814 
815  static bool compare(const key_type& lhs, const key_type& rhs) {
816  return provider_->key_comp()(lhs, rhs);
817  }
818 
819  static bool equal(const key_type& lhs, const key_type& rhs) {
820  return provider_->key_eq()(lhs, rhs);
821  }
822 
823  static size_t hash(const key_type& key) { return provider_->key_hash()(key); }
824 };
825 
826 } // namespace internal
827 
828 template <class Traits>
829 struct iterator {
830  typedef internal::node<Traits> node_type;
831  typedef typename Traits::container container_type;
832 
833  typedef std::ptrdiff_t difference_type;
834  typedef const typename Traits::value_type value_type;
835  typedef const value_type* pointer;
836  typedef const value_type& reference;
837  typedef std::bidirectional_iterator_tag iterator_category;
838 
839  iterator() : container_(nullptr), pos_(0), node_(nullptr) {}
840 
841  iterator(const container_type* container,
842  size_t pos,
843  const node_type* node = nullptr)
844  : container_(container), pos_(pos), node_(node), decrementing_(false) {}
845 
846  iterator(const container_type* container,
847  std::pair<const node_type*, size_t> p)
848  : container_(container),
849  pos_(p.second),
850  node_(p.first),
851  decrementing_(false) {}
852 
853  iterator(const iterator& other)
854  : container_(other.container_),
855  pos_(other.pos_),
856  node_(other.node_),
857  decrementing_(false) {}
858 
859  reference operator*() const { return find_node()->value(); }
860  pointer operator->() const { return &find_node()->value(); }
861 
862  iterator& operator++() {
863  *this += 1;
864  return *this;
865  }
866 
867  iterator operator++(int) {
868  iterator it(container_, pos_, node_);
869  *this += 1;
870  return it;
871  }
872 
873  iterator operator+(difference_type k) const {
874  return iterator(container_, pos_ + k);
875  }
876 
877  iterator& operator+=(difference_type k) {
878  reset(pos_ + k);
879  return *this;
880  }
881 
882  iterator& operator--() {
883  *this -= 1;
884  return *this;
885  }
886 
887  iterator operator--(int) {
888  iterator it(container_, pos_, node_);
889  *this -= 1;
890  return it;
891  }
892 
893  iterator operator-(difference_type k) const {
894  return iterator(container_, pos_ - k);
895  }
896 
897  iterator& operator-=(difference_type k) {
898  reset(pos_ - k);
899  return *this;
900  }
901 
902  void swap(iterator& other) {
903  std::swap(container_, other.container_);
904  std::swap(pos_, other.pos_);
905  std::swap(node_, other.node_);
906  std::swap(stack_, other.stack_);
907  std::swap(decrementing_, other.decrementing_);
908  }
909 
910  iterator& operator=(const iterator& other) {
911  container_ = other.container_;
912  pos_ = other.pos_;
913  node_ = other.node_;
914  stack_.clear();
915  return *this;
916  }
917 
918  iterator& operator=(iterator&& other) {
919  swap(other);
920  return *this;
921  }
922 
923  bool operator==(const iterator& other) const { return pos_ == other.pos_; }
924  bool operator!=(const iterator& other) const { return pos_ != other.pos_; }
925  bool operator<(const iterator& other) const { return pos_ < other.pos_; }
926  bool operator<=(const iterator& other) const { return pos_ <= other.pos_; }
927  bool operator>(const iterator& other) const { return pos_ > other.pos_; }
928  bool operator>=(const iterator& other) const { return pos_ >= other.pos_; }
929 
930  void increment() {
931  ++pos_;
932  if (decrementing_) {
933  stack_.clear();
934  decrementing_ = false;
935  }
936  if (stack_.empty()) {
937  size_t k = pos_;
938  node_ = container_->node_.get();
939  do {
940  while (k > size(node_->left_)) {
941  k -= size(node_->left_) + 1;
942  node_ = node_->right_.get();
943  }
944  while (k < size(node_->left_)) {
945  stack_.push_back(node_);
946  node_ = node_->left_.get();
947  }
948  } while (k != size(node_->left_));
949  return;
950  }
951  if (node_->right_) {
952  node_ = node_->right_.get();
953  while (node_->left_) {
954  stack_.push_back(node_);
955  node_ = node_->left_.get();
956  }
957  } else {
958  node_ = stack_.back();
959  stack_.pop_back();
960  }
961  }
962 
963  void decrement() {
964  --pos_;
965  if (!decrementing_) {
966  stack_.clear();
967  decrementing_ = true;
968  }
969  if (stack_.empty()) {
970  size_t k = pos_;
971  node_ = container_->node_.get();
972  do {
973  while (k > size(node_->left_)) {
974  k -= size(node_->left_) + 1;
975  stack_.push_back(node_);
976  node_ = node_->right_.get();
977  }
978  while (k < size(node_->left_)) {
979  node_ = node_->left_.get();
980  }
981  } while (k != size(node_->left_));
982  return;
983  }
984  if (node_->left_) {
985  node_ = node_->left_.get();
986  while (node_->right_) {
987  stack_.push_back(node_);
988  node_ = node_->right_.get();
989  }
990  } else {
991  node_ = stack_.back();
992  stack_.pop_back();
993  }
994  }
995 
996  void reset(size_t pos) {
997  if (pos == pos_ + 1 && pos != size(container_->node_)) {
998  increment();
999  return;
1000  }
1001  if (pos == pos_ - 1) {
1002  decrement();
1003  return;
1004  }
1005  if (pos_ != pos) {
1006  pos_ = pos;
1007  node_ = nullptr;
1008  stack_.clear();
1009  }
1010  }
1011 
1012  const node_type* find_node() const {
1013  assert(pos_ < size(container_->node_));
1014  if (!node_)
1015  node_ = at_index(container_->node_.get(), pos_);
1016  return node_;
1017  }
1018 
1019  const container_type* container_;
1020  size_t pos_;
1021  mutable const node_type* node_;
1022  std::vector<const node_type*> stack_;
1023  bool decrementing_;
1024 };
1025 
1026 template <class Traits>
1027 std::ptrdiff_t distance(const iterator<Traits>& from,
1028  const iterator<Traits>& to) {
1029  return to.pos_ - from.pos_;
1030 }
1031 
1033 
1058 template <class T,
1059  class Compare = std::less<T>,
1060  class Hash = std::hash<T>,
1061  class Equal = std::equal_to<T>>
1063  typedef internal::set_traits<T, Compare, Hash, Equal> traits;
1064 
1065  friend struct internal::env_base<traits>;
1066 
1067  public:
1075  set_provider(const Compare& compare = Compare(),
1076  const Hash& hash = Hash(),
1077  const Equal& equal = Equal())
1078  : compare_(compare), hash_(hash), equal_(equal) {}
1079 
1080  set_provider(const set_provider&) = delete;
1081 
1082  ~set_provider() { assert(size() == 0); }
1083 
1087  const Compare& key_comp() const { return compare_; }
1088 
1092  const Hash& key_hash() const { return hash_; }
1093 
1097  const Equal& key_eq() const { return equal_; }
1098 
1102  size_t size() const {
1103  std::lock_guard<std::mutex> lock(hash_table_.mutex_);
1104  return hash_table_.size_;
1105  }
1106 
1110  static const std::shared_ptr<set_provider>& default_provider() {
1111  static const std::shared_ptr<set_provider> provider =
1112  std::make_shared<set_provider>();
1113  return provider;
1114  }
1115 
1116  private:
1117  const Compare compare_;
1118  const Hash hash_;
1119  const Equal equal_;
1120  internal::hash_table<traits> hash_table_;
1121 };
1122 
1137 template <class T,
1138  class Compare = std::less<T>,
1139  class Hash = std::hash<T>,
1140  class Equal = std::equal_to<T>>
1141 class set {
1142  template <class K, class M, class KC, class KH, class KE, class MH, class ME>
1143  friend class map;
1144 
1145  typedef internal::set_traits<T, Compare, Hash, Equal> traits;
1146  typedef internal::env<traits> env_type;
1147  typedef typename internal::node<traits> node_type;
1148 
1149  friend struct confluent::iterator<traits>;
1150 
1151  public:
1152  typedef T key_type;
1153  typedef T value_type;
1155  typedef std::shared_ptr<provider_type> provider_ptr;
1156  typedef confluent::iterator<traits> iterator;
1157  typedef std::reverse_iterator<iterator> reverse_iterator;
1158 
1167  : provider_(std::move(provider)) {}
1168 
1179  template <class InputIterator>
1180  set(InputIterator first,
1181  InputIterator last,
1182  provider_ptr provider = provider_type::default_provider())
1183  : provider_(std::move(provider)) {
1184  insert(first, last);
1185  }
1186 
1196  set(std::initializer_list<value_type> ilist,
1197  provider_ptr provider = provider_type::default_provider())
1198  : provider_(std::move(provider)) {
1199  insert(ilist);
1200  }
1201 
1212  set(iterator first, iterator last) : set(*first.container_) {
1213  retain(first, last);
1214  }
1215 
1225  set(const set& other) : provider_(other.provider_), node_(other.node_) {}
1226 
1238  set(set&& other)
1239  : provider_(std::move(other.provider_)), node_(std::move(other.node_)) {}
1240 
1241  ~set() { clear(); }
1242 
1253  size_t insert(const value_type& value) {
1254  return internal::insert(env(), &node_, value);
1255  }
1256 
1269  template <class InputIterator>
1270  size_t insert(InputIterator first, InputIterator last) {
1271  return internal::insert(env(), &node_, first, last);
1272  }
1273 
1285  size_t insert(std::initializer_list<value_type> ilist) {
1286  return internal::insert(env(), &node_, ilist.begin(), ilist.end());
1287  }
1288 
1305  size_t insert(const set& other) {
1306  check(other);
1307  return internal::add(env(), &node_, other.node_);
1308  }
1309 
1320  size_t erase(const key_type& key) {
1321  return internal::erase(env(), &node_, key);
1322  }
1323 
1338  size_t erase(iterator first, iterator last) {
1339  check(first, last);
1340  return internal::erase(env(), &node_, first.pos_, last.pos_);
1341  }
1342 
1363  size_t erase(const set& other) {
1364  check(other);
1365  return internal::diff(env(), &internal::rank<traits>, &node_, other.node_);
1366  }
1367 
1384  size_t retain(iterator first, iterator last) {
1385  check(first, last);
1386  return internal::retain(env(), &node_, first.pos_, last.pos_);
1387  }
1388 
1409  size_t retain(const set& other) {
1410  check(other);
1411  return internal::intersect(env(), &internal::rank<traits>, &node_,
1412  other.node_);
1413  }
1414 
1423  void clear() {
1424  if (node_)
1425  reset(env(), &node_);
1426  }
1427 
1433  void swap(set& other) {
1434  provider_.swap(other.provider_);
1435  node_.swap(other.node_);
1436  }
1437 
1438  // TODO: ilist assignment
1439 
1450  set& operator=(const set& other) {
1451  clear();
1452  provider_ = other.provider_;
1453  node_ = other.node_;
1454  return *this;
1455  }
1456 
1470  set& operator=(set&& other) {
1471  swap(other);
1472  return *this;
1473  }
1474 
1486  set& operator=(std::initializer_list<value_type> ilist) {
1487  internal::assign(env(), &node_, ilist.begin(), ilist.end());
1488  return *this;
1489  }
1490 
1505  set operator|(const set& rhs) const {
1506  check(rhs);
1507  return set(provider_, set_union(env(), node_, rhs.node_));
1508  }
1509 
1525  set& operator|=(const set& rhs) {
1526  check(rhs);
1527  insert(rhs);
1528  return *this;
1529  }
1530 
1548  set operator&(const set& rhs) const {
1549  check(rhs);
1550  return set(provider_, set_intersection(env(), &internal::rank<traits>,
1551  node_, rhs.node_));
1552  }
1553 
1572  set& operator&=(const set& rhs) {
1573  check(rhs);
1574  retain(rhs);
1575  return *this;
1576  }
1577 
1595  set operator-(const set& rhs) const {
1596  check(rhs);
1597  return set(provider_, set_difference(env(), &internal::rank<traits>, node_,
1598  rhs.node_));
1599  }
1600 
1619  set& operator-=(const set& rhs) {
1620  check(rhs);
1621  erase(rhs);
1622  return *this;
1623  }
1624 
1642  set operator^(const set& rhs) const {
1643  check(rhs);
1644  return set(provider_, set_symmetric(env(), node_, rhs.node_));
1645  }
1646 
1665  set& operator^=(const set& rhs) {
1666  check(rhs);
1667  symmetric(env(), &node_, rhs.node_);
1668  return *this;
1669  }
1670 
1674  iterator begin() const { return iterator(this, 0); }
1675 
1679  iterator end() const { return iterator(this, size()); }
1680 
1684  iterator cbegin() const { return begin(); }
1685 
1689  iterator cend() const { return end(); }
1690 
1694  reverse_iterator rbegin() const { return reverse_iterator(end()); }
1695 
1699  reverse_iterator rend() const { return reverse_iterator(begin()); }
1700 
1709  iterator find(const key_type& key) const {
1710  std::pair<const node_type*, size_t> bound = internal::lower_bound(
1711  node_.get(),
1712  [&](const node_type& p) { return key_comp(p.key(), key); });
1713  if (bound.first && key_eq(bound.first->key(), key))
1714  return iterator(this, bound);
1715  else
1716  return end();
1717  }
1718 
1727  iterator lower_bound(const key_type& key) const {
1728  return iterator(this,
1729  internal::lower_bound(node_.get(), [&](const node_type& p) {
1730  return key_comp(p.key(), key);
1731  }));
1732  }
1733 
1742  iterator upper_bound(const key_type& key) const {
1743  return iterator(this,
1744  internal::lower_bound(node_.get(), [&](const node_type& p) {
1745  return !key_comp(key, p.key());
1746  }));
1747  }
1748 
1760  std::pair<iterator, iterator> equal_range(const key_type& key) const {
1761  return {lower_bound(key), upper_bound(key)};
1762  }
1763 
1772  const value_type& at_index(size_t k) const {
1773  return internal::at_index(node_.get(), k)->value();
1774  }
1775 
1784  size_t count(const key_type& key) const {
1785  const node_type* p =
1786  internal::lower_bound(node_.get(), [&](const node_type& p) {
1787  return key_comp(p.key(), key);
1788  }).first;
1789  return p && key_eq(p->key(), key) ? 1 : 0;
1790  }
1791 
1808  bool includes(const set& other) const {
1809  check(other);
1810  return internal::includes(env(), &internal::rank<traits>, node_,
1811  other.node_);
1812  }
1813 
1817  const provider_ptr& provider() const { return provider_; }
1818 
1826  bool empty() const { return !node_; }
1827 
1833  size_t size() const { return internal::size(node_); }
1834 
1840  size_t hash() const { return internal::hash(node_); }
1841 
1852  bool operator==(const set& rhs) const {
1853  check(rhs);
1854  return node_ == rhs.node_;
1855  }
1856 
1867  bool operator!=(const set& rhs) const { return node_ != rhs.node_; }
1868 
1869  private:
1870  typedef typename internal::node_ptr<traits> node_ptr;
1871 
1872  set(provider_ptr provider, node_ptr node)
1873  : provider_(std::move(provider)), node_(std::move(node)) {}
1874 
1875  void check(const set& other) const { assert(provider_ == other.provider_); }
1876 
1877  void check(const iterator& first, const iterator& last) const {
1878  assert(provider_ == first.container_->provider_);
1879  assert(provider_ == last.container_->provider_);
1880  assert(first.pos_ <= last.pos_);
1881  assert(last.pos_ <= size());
1882  }
1883 
1884  bool key_comp(const key_type& lhs, const key_type& rhs) const {
1885  return provider_->key_comp()(lhs, rhs);
1886  }
1887 
1888  bool key_eq(const key_type& lhs, const key_type& rhs) const {
1889  return provider_->key_eq()(lhs, rhs);
1890  }
1891 
1892  env_type env() const { return {provider_.get()}; }
1893 
1894  provider_ptr provider_;
1895  node_ptr node_;
1896 };
1897 
1907 template <class T, class Compare, class Hash, class Equal>
1908 void swap(set<T, Compare, Hash, Equal>& x, set<T, Compare, Hash, Equal>& y) {
1909  x.swap(y);
1910 }
1911 
1921 template <class T, class Compare, class Hash, class Equal>
1922 size_t hash(const set<T, Compare, Hash, Equal>& x) {
1923  return x.hash();
1924 }
1925 
1926 } // namespace confluent
1927 
1928 #endif // CONFLUENT_SET_H_INCLUDED
set & operator-=(const set &rhs)
Definition: set.h:1619
set(InputIterator first, InputIterator last, provider_ptr provider=provider_type::default_provider())
Definition: set.h:1180
iterator cend() const
Definition: set.h:1689
reverse_iterator rbegin() const
Definition: set.h:1694
const provider_ptr & provider() const
Definition: set.h:1817
Definition: set.h:1141
iterator lower_bound(const key_type &key) const
Definition: set.h:1727
set & operator=(set &&other)
Definition: set.h:1470
size_t size() const
Definition: set.h:1833
size_t insert(const set &other)
Definition: set.h:1305
size_t size() const
Definition: set.h:1102
iterator end() const
Definition: set.h:1679
size_t count(const key_type &key) const
Definition: set.h:1784
iterator find(const key_type &key) const
Definition: set.h:1709
size_t retain(iterator first, iterator last)
Definition: set.h:1384
set & operator&=(const set &rhs)
Definition: set.h:1572
size_t insert(const value_type &value)
Definition: set.h:1253
Definition: map.h:406
std::pair< iterator, iterator > equal_range(const key_type &key) const
Definition: set.h:1760
size_t insert(InputIterator first, InputIterator last)
Definition: set.h:1270
static const std::shared_ptr< set_provider > & default_provider()
Definition: set.h:1110
set & operator=(std::initializer_list< value_type > ilist)
Definition: set.h:1486
size_t erase(const key_type &key)
Definition: set.h:1320
size_t erase(const set &other)
Definition: set.h:1363
set(const set &other)
Definition: set.h:1225
size_t insert(std::initializer_list< value_type > ilist)
Definition: set.h:1285
size_t retain(const set &other)
Definition: set.h:1409
set & operator^=(const set &rhs)
Definition: set.h:1665
void clear()
Definition: set.h:1423
void swap(set &other)
Definition: set.h:1433
iterator upper_bound(const key_type &key) const
Definition: set.h:1742
set operator-(const set &rhs) const
Definition: set.h:1595
const Equal & key_eq() const
Definition: set.h:1097
set(set &&other)
Definition: set.h:1238
Definition: set.h:1062
iterator cbegin() const
Definition: set.h:1684
reverse_iterator rend() const
Definition: set.h:1699
bool operator!=(const set &rhs) const
Definition: set.h:1867
const value_type & at_index(size_t k) const
Definition: set.h:1772
bool empty() const
Definition: set.h:1826
set operator^(const set &rhs) const
Definition: set.h:1642
size_t erase(iterator first, iterator last)
Definition: set.h:1338
set operator&(const set &rhs) const
Definition: set.h:1548
iterator begin() const
Definition: set.h:1674
set operator|(const set &rhs) const
Definition: set.h:1505
const Compare & key_comp() const
Definition: set.h:1087
bool includes(const set &other) const
Definition: set.h:1808
set(iterator first, iterator last)
Definition: set.h:1212
set & operator|=(const set &rhs)
Definition: set.h:1525
bool operator==(const set &rhs) const
Definition: set.h:1852
size_t hash() const
Definition: set.h:1840
set(std::initializer_list< value_type > ilist, provider_ptr provider=provider_type::default_provider())
Definition: set.h:1196
const Hash & key_hash() const
Definition: set.h:1092
set_provider(const Compare &compare=Compare(), const Hash &hash=Hash(), const Equal &equal=Equal())
Definition: set.h:1075
set & operator=(const set &other)
Definition: set.h:1450
set(provider_ptr provider=provider_type::default_provider())
Definition: set.h:1166