lock_free_chromatic_tree.h 30.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
/*
 * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef EMBB_CONTAINERS_LOCK_FREE_CHROMATIC_TREE_H_
#define EMBB_CONTAINERS_LOCK_FREE_CHROMATIC_TREE_H_

#include <stddef.h>
#include <functional>

33
#include <embb/base/c/errors.h>
34
#include <embb/base/mutex.h>
35
#include <embb/containers/internal/hazard_pointer.h>
36 37
#include <embb/containers/lock_free_tree_value_pool.h>
#include <embb/containers/object_pool.h>
38 39 40 41 42

namespace embb {
namespace containers {
namespace internal {

43 44 45
template<typename Key, typename Value>
class ChromaticTreeOperation;

46
/**
47
 * Chromatic tree node.
48 49 50 51 52 53 54 55 56 57
 * 
 * Stores the key-value pair, as well as the weight value (used for rebalancing)
 * and two pointers to child nodes (left and right).
 * 
 * \tparam Key   Key type
 * \tparam Value Value type
 */
template<typename Key, typename Value>
class ChromaticTreeNode {
 public:
58
  /** Node of the tree (self type). */
59
  typedef ChromaticTreeNode         Node;
60
  /** Atomic pointer to a node. */
61
  typedef embb::base::Atomic<Node*> AtomicNodePtr;
62
  /** Chromatic tree operation. */
63
  typedef ChromaticTreeOperation<Key, Value> Operation;
64
  /** Atomic pointer to a tree operation. */
65
  typedef embb::base::Atomic<Operation*>     AtomicOperationPtr;
66

67 68 69
  /**
   * Creates a node with given parameters.
   * 
70 71 72 73 74 75
   * \param[IN] key       Key of the new node
   * \param[IN] value     Value of the new node
   * \param[IN] weight    Weight of the new node
   * \param[IN] left      Pointer to the left child node
   * \param[IN] right     Pointer to the right child node
   * \param[IN] operation Pointer to an operation object
76
   */
77
  ChromaticTreeNode(const Key& key, const Value& value, int weight,
78
                    Node* left, Node* right, Operation* operation);
79 80
  
  /**
81
   * Creates a node with given parameters and no child nodes.
82
   * 
83 84 85 86
   * \param[IN] key       Key of the new node
   * \param[IN] value     Value of the new node
   * \param[IN] weight    Weight of the new node
   * \param[IN] operation Pointer to an operation object
87
   */
88 89
  ChromaticTreeNode(const Key& key, const Value& value, int weight,
                    Operation* operation);
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
  
  /**
   * Accessor for the stored key.
   * 
   * \return Stored key
   */
  const Key&   GetKey() const;
  
  /**
   * Accessor for the stored value.
   * 
   * \return Stored value
   */
  const Value& GetValue() const;
  
  /**
   * Accessor for the weight of the node.
   * 
   * \return Weight of the node
   */
110
  int GetWeight() const;
111 112 113 114 115 116
  
  /**
   * Accessor for the left child pointer.
   * 
   * \return Reference to the left child pointer
   */
117 118
  AtomicNodePtr& GetLeft();
  Node* GetLeft() const;
119 120 121 122 123 124
  
  /**
   * Accessor for the right child pointer.
   * 
   * \return Reference to the right child pointer
   */
125 126 127 128
  AtomicNodePtr& GetRight();
  Node* GetRight() const;

  /**
129 130 131 132 133 134 135 136 137 138 139 140 141 142
   * Checks if the node is a leaf.
   * 
   * @return \c true if node is a leaf, \c false otherwise
   */
  bool IsLeaf() const;

  /**
   * Checks if the node is a sentinel.
   *
   * @return \c true if node is a sentinel, \c false otherwise
   */
  bool IsSentinel() const;

  /**
143 144 145 146 147 148 149 150 151 152 153 154
   * Tries to replace one of the child pointers that compares equal to
   * \c old_child with the \c new_child using an atomic compare-and-swap
   * operation. If neither left nor right child pointer is pointing to
   * \c old_child, returns \c false.
   *
   * \param old_child[IN] Pointer to an old child node to compare against
   * \param new_child[IN] Pointer to the new child node
   *
   * \return \c true if one of the child pointers is now pointing to
   *         \c new_child, \c false otherwise
   */
  bool ReplaceChild(Node* old_child, Node* new_child);
155

156 157 158 159 160 161
  /**
   * Marks node for deletion from the tree
   */
  void Retire();

  /**
162
   * Checks whether the node is marked for deletion from the tree.
163 164 165 166 167 168
   *
   * \return \c true if node is retired, \c false otherwise
   */
  bool IsRetired() const;

  /**
169
   * Accessor for the operation pointer of the node.
170
   *
171
   * \return Reference to this node's operation pointer
172
   */
173
  AtomicOperationPtr& GetOperation();
174 175

 private:
176
  /** Atomic boolean flag. */
177 178
  typedef embb::base::Atomic<bool> AtomicFlag;

179 180 181
  /**
   * Disable copy construction and assignment.
   */
182 183 184
  ChromaticTreeNode(const ChromaticTreeNode&);
  ChromaticTreeNode& operator=(const ChromaticTreeNode&);
  
185 186 187 188 189 190 191 192 193
  const Key          key_;         /**< Stored key. */
  const Value        value_;       /**< Stored value. */
  const int          weight_;      /**< Weight of the node. */
  const bool         is_leaf_;     /**< True if node is a leaf. */
  const bool         is_sentinel_; /**< True if node is a sentinel. */
  AtomicNodePtr      left_;        /**< Pointer to left child node. */
  AtomicNodePtr      right_;       /**< Pointer to right child node. */
  AtomicFlag         retired_;     /**< Retired (marked for deletion) flag. */
  AtomicOperationPtr operation_;   /**< Pointer to a tree operation object. */
194 195
};

196 197 198 199 200 201 202 203 204 205 206 207 208
/**
 * Tree operation
 *
 * Describes a chromatic tree operation (insertion, deletion or rotation).
 * Contains pointers to the root node of the operation, nodes that are part of
 * the operation window, and the newly created node to become a new child of the
 * root node. For all existing nodes, the original operation pointers acquired
 * through a previous WeakLLXs are stored. Methods for initialization, helping
 * and status enquiries are provided.
 *
 * \tparam Key   Key type
 * \tparam Value Value type
 */
209 210 211
template<typename Key, typename Value>
class ChromaticTreeOperation {
 public:
212
  /** Node of the tree. */
213
  typedef ChromaticTreeNode<Key, Value>  Node;
214
  /** Atomic pointer to a node. */
215
  typedef embb::base::Atomic<Node*>      AtomicNodePtr;
216
  /** Hazard-protected pointer to a node. */
217
  typedef UniqueHazardPointer<Node>      HazardNodePtr;
218
  /** Chromatic tree operation (self type). */
219
  typedef ChromaticTreeOperation         Operation;
220
  /** Atomic pointer to a tree operation. */
221
  typedef embb::base::Atomic<Operation*> AtomicOperationPtr;
222
  /** Hazard-protected pointer to a tree operation. */
223 224
  typedef UniqueHazardPointer<Operation> HazardOperationPtr;

225 226
  /**
   * Creates an empty operation object with an "in progress" state.
227 228 229
   *
   * \param is_dummy Boolean flag for creation of dummy operation objects.
   *
230
   */
231
  ChromaticTreeOperation(bool is_dummy = false);
232

233 234 235 236 237 238 239 240
  /**
   * Set the root node of this operation together with its original operation
   * pointer.
   *
   * \param root           The root node of the operation
   * \param root_operation The original operation pointer of the root node
   */
  void SetRoot(Node* root, Operation* root_operation);
241

242 243 244 245 246 247 248 249
  /**
   * Sets the nodes of this operation window together with their original
   * operation pointers.
   *
   * \param node1      The node from the operation window
   * \param operation1 The original operation pointer of \c node1
   */
  void SetOldNodes(Node* node1, Operation* operation1);
250 251

  void SetOldNodes(Node* node1, Operation* operation1,
252
                   Node* node2, Operation* operation2);
253 254 255

  void SetOldNodes(Node* node1, Operation* operation1,
                   Node* node2, Operation* operation2,
256
                   Node* node3, Operation* operation3);
257

258 259 260
  void SetOldNodes(Node* node1, Operation* operation1,
                   Node* node2, Operation* operation2,
                   Node* node3, Operation* operation3,
261
                   Node* node4, Operation* operation4);
262 263 264 265 266

  void SetOldNodes(Node* node1, Operation* operation1,
                   Node* node2, Operation* operation2,
                   Node* node3, Operation* operation3,
                   Node* node4, Operation* operation4,
267
                   Node* node5, Operation* operation5);
268

269 270 271 272 273 274
  /**
   * Set the node that is to become the new child of the operation root.
   *
   * \param new_child Node to become the new child of the operation root
   */
  void SetNewChild(Node* new_child);
275

276 277 278 279 280 281 282 283 284 285 286 287 288 289
  /**
   * Help execute the operation. First tries to freeze all the nodes in the
   * operation window, and if succeeds - retires those nodes and injects the new
   * window into the tree. If the freezing step fails, rolls back the operation
   * by unfreezing all the nodes of the original window.
   *
   * \param node_guard Node hazard guard used to protect the helped nodes
   * \param oper_guard Operation hazard guard to protect the original operation
   *                   pointers of the helped nodes
   *
   * \return \c true is the operation successfully commits, \c false if it
   *         aborts
   */
  bool Help(AtomicNodePtr& node_guard, AtomicOperationPtr& oper_guard);
290

291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
  /**
   * Help an operation that has successfully frozen all the nodes in its window
   * to complete. This operation may no longer fail or abort.
   *
   * \param node_guard Node hazard guard used to protect the helped nodes
   */
  void HelpCommit(AtomicNodePtr& node_guard);

  /**
   * Help an aborted operation by unfreezing the given \c node.
   *
   * \param node The node to be unfrozen
   */
  void HelpAbort(Node* node);

  /**
   * Check whether the operation is aborted.
   *
   * \return \c true if operation is aborted, \c false otherwise
   */
  bool IsAborted();
312

313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
  /**
   * Check whether the operation is in progress.
   *
   * \return \c true if operation is in progress, \c false otherwise
   */
  bool IsInProgress();

  /**
   * Check whether the operation is committed.
   *
   * \return \c true if operation is committed, \c false otherwise
   */
  bool IsCommitted();

  /**
   * Performs the necessary post-processing steps for the operation, i.e. if the
   * operation commits, resets all the operation pointers of the nodes of the
   * removed operation window to point to the retired dummy-operation. Must be
   * called only once after the operation either commits or aborts.
332 333 334
   *
   * \param retired_dummy Dummy operation object used to reset operation
   *                      pointers in the retired nodes.
335
   */
336
  void CleanUp(Operation* retired_dummy);
337 338

#ifdef EMBB_DEBUG
339 340 341 342 343
  /**
   * Set the deleted flag for this operation. No other method of this operation
   * is allowed to be called after this method returns.
   */
  void SetDeleted();
344 345 346
#endif

 private:
347
  /** Enumeration of possible operation states. */
348 349 350 351 352 353 354
  typedef enum {
    STATE_ABORTED,
    STATE_ROLLBACK,
    STATE_FREEZING,
    STATE_ALL_FROZEN,
    STATE_COMMITTED
  } State;
355
  /** Atomic wrapper for the operation state. */
356 357
  typedef embb::base::Atomic<State> AtomicState;

358
  /** Maximal possible number of nodes in an operation window. */
359 360
  static const size_t MAX_NODES = 5;

361 362 363 364 365 366
  /**
   * Check whether the operation is rolling back.
   *
   * \return \c true if operation is rolling back, \c false otherwise
   */
  bool IsRollingBack();
367

368 369 370 371 372 373
  /**
   * Check whether the operation is freezing.
   *
   * \return \c true if operation is freezing, \c false otherwise
   */
  bool IsFreezing();
374

375 376 377 378 379 380 381
  /**
   * Check whether all the nodes from the operation window were successfully
   * frozen for this operation.
   *
   * \return \c true if all nodes of the window were frozen, \c false otherwise
   */
  bool IsAllFrozen();
382

383 384 385 386 387 388 389 390 391 392 393 394 395
  /**
   * Tries to freeze all the nodes from the operation window for this operation.
   * If the current operation encounters a conflict and fails, this method helps
   * to roll back the operation by unfreezing all the nodes.
   *
   * \param node_guard Node hazard guard used to protect the freezing nodes
   * \param oper_guard Operation hazard guard to protect the original operation
   *                   pointers of the freezing nodes
   *
   * \return \c true if all nodes of this operation window were successfully
   *         frozen, \c false otherwise
   */
  bool FreezeAll(AtomicNodePtr& node_guard, AtomicOperationPtr& oper_guard);
396

397 398 399 400 401 402 403 404 405 406 407 408
  /**
   * Tries to freeze the given \c node for the current operation by using a CAS
   * to set the node's operation pointer to point to this operation. If the CAS
   * fails and the node is not frozen for this operation, tries to switch to the
   * "rolling back" state.
   *
   * \param node      The node to be frozen
   * \param operation The original operation pointer of the \c node
   *
   * \return \c true if \c node was successfully frozen, \c false otherwise
   */
  bool Freeze(Node* node, Operation* operation);
409

410 411 412 413 414 415 416 417 418
  /**
   * Rolls back the current operation by unfreezing all the nodes of the
   * operation window, i.e. changing the operation pointers of those nodes to
   * their original values.
   *
   * \param node_guard Node hazard guard used to protect the nodes being
   *                   unfrozen
   */
  void UnfreezeAll(AtomicNodePtr& node_guard);
419

420 421 422 423 424 425 426 427
  /**
   * Unfreezes the given \c node by changing its operation pointer back to the
   * original value.
   *
   * \param node      The node to be unfrozen
   * \param operation The original operation pointer of the \c node
   */
  void Unfreeze(Node* node, Operation* operation);
428

429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
  /**
   * Tries to switch from one operation state to another. If current state is
   * already equal to \c new_state, returns \c true. Otherwise, tries to switch
   * from \c old_state to \c new_state atomically using a CAS operation, and
   * returns \c true if this CAS succeeds.
   * 
   * \param old_state Currently expected state of the operation
   * \param new_state New desired state of the operation
   *
   * \return \c true is state was successfully changed to \c new_state, \c false
   *         otherwise
   */
  bool SwitchState(State old_state, State new_state);

  /**
   * Disable copy construction and assignment.
   */
446 447 448
  ChromaticTreeOperation(const ChromaticTreeOperation&);
  ChromaticTreeOperation& operator=(const ChromaticTreeOperation&);

449
  /** Current state of the operation. */
450
  AtomicState state_;
451
  /** Root node of the operation. */
452
  Node*       root_;
453
  /** Original operation pointer of the root node. */
454
  Operation*  root_operation_;
455
  /** Number of nodes in the operation window. */
456
  size_t      num_old_nodes_;
457
  /** Nodes of the operation window. */
458
  Node*       old_nodes_[MAX_NODES];
459
  /** Original operation pointers for the nodes of the window. */
460
  Operation*  old_operations_[MAX_NODES];
461
  /** Pointer to the new node to become the new child of the root. */
462 463
  Node*       new_child_;
#ifdef EMBB_DEBUG
464
  /** Debug flag for memory management control (is set when node is deleted). */
465 466 467 468
  embb::base::Atomic<bool> deleted_;
#endif
};

469 470
} // namespace internal

471 472
namespace test {
/**
473
 * Forward declaration of the test class.
474 475 476 477 478
 */
template<typename Tree>
class TreeTest;

} // namespace test
479 480

/**
481
 * Chromatic balanced binary search tree.
482 483 484 485
 * 
 * Implements a balanced BST with support for \c Get, \c Insert and \c Delete
 * operations.
 * 
486 487 488 489 490 491 492
 * \tparam Key       Key type
 * \tparam Value     Value type
 * \tparam Compare   Custom comparator type for the keys. An object of the
 *                   type \c Compare must must be a functor taking two
 *                   arguments \c rhs and \c lhs of type \c Key and
 *                   returning \c true if and only if <tt>(rhs < lhs)</tt> holds
 * \tparam ValuePool Type of the value pool to be used inside object pools for
493
 *                   tree nodes and operation objects
494 495 496 497
 */
template<typename Key,
         typename Value,
         typename Compare = ::std::less<Key>,
498
         typename ValuePool = LockFreeTreeValuePool<bool, false>
499 500 501 502
         >
class ChromaticTree {
 public:
  /**
503
   * Exposing the \c Key template parameter back to the user.
504 505 506
   */
  typedef Key   KeyType;
  /**
507
   * Exposing the \c Value template parameter back to the user.
508 509 510 511
   */
  typedef Value ValueType;

  /**
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
   * Creates a new tree with given capacity.
   * 
   * \memory Allocates <tt>(2 * capacity + 7)</tt> tree nodes each of size
   *         <tt>sizeof(internal::ChromaticTreeNode<Key, Value>)</tt>.
   * 
   * \notthreadsafe
   * 
   * \param[IN] capacity        Required capacity of the tree
   * \param[IN] undefined_key   Object of type \c Key to be used as a dummy key.
   *                            Defaults to <tt>Key()</tt>
   * \param[IN] undefined_value Object of type \c Value to be used as a dummy 
   *                            value. Defaults to <tt>Value()</tt>
   * \param[IN] compare         Custom comparator object for managed keys.
   *                            Defaults to <tt>Compare()</tt>
   * 
   * \note If any of \c undefined_key, \c undefined_value or \c compare is not
   *       provided, that will require the corresponding type (\c Key, \c Value
   *       or \c Compare) to support value-initialization.
   */
  explicit ChromaticTree(size_t capacity, Key undefined_key = Key(),
                Value undefined_value = Value(), Compare compare = Compare());
  
  /**
   * Destroys the tree.
   * 
   * \notthreadsafe
   */
  ~ChromaticTree();
  
  
  /**
   * Tries to find a value for the given key.
   * 
   * \param[IN]     key    Key to search for
   * \param[IN,OUT] value  Reference to the found value. Unchanged if the given
   *                       key is not stored in the tree
   * 
   * \return \c true if the given key was found in the tree, \c false otherwise
   */
  bool Get(const Key& key, Value& value);
  
  /**
   * Tries to insert a new key-value pair into the tree. If a value for the
   * given key is already stored in the tree, tries to replace the stored value
   * with the new one.
   * 
   * \param[IN] key    New key to be inserted
   * \param[IN] value  New value to be inserted
   * 
   * \return \c true if the given key-value pair was successfully inserted into
562
   *         the tree, \c false if the tree has reached its capacity
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
   */
  bool TryInsert(const Key& key, const Value& value);
  
  /**
   * Tries to insert a new key-value pair into the tree. If a value for the
   * given key is already stored in the tree, tries to replace the stored value
   * with the new one. Also returns the original value stored in the tree for
   * the given \c key, or the \c undefined_value if the key was not present in
   * the tree.
   * 
   * \param[IN]     key       New key to be inserted
   * \param[IN]     value     New value to be inserted
   * \param[IN,OUT] old_value Reference to the value previously stored in the
   *                          tree for the given key
   * 
   * \return \c true if the given key-value pair was successfully inserted into
579
   *         the tree, \c false if the tree has reached its capacity
580 581 582 583 584 585 586 587 588
   */
  bool TryInsert(const Key& key, const Value& value, Value& old_value);
  
  /**
   * Tries to remove a given key-value pair from the tree.
   * 
   * \param[IN] key    Key to be removed
   * 
   * \return \c true if the given key-value pair was successfully deleted from
589
   *         the tree, \c false if there is not enough memory
590 591 592 593 594 595 596 597 598 599 600 601 602
   */
  bool TryDelete(const Key& key);
  
  /**
   * Tries to remove a given key-value pair from the tree, and returns the value
   * that was stored in the tree for the given key (or \c undefined_value if 
   * the key was not present in the tree).
   * 
   * \param[IN]     key       Key to be removed
   * \param[IN,OUT] old_value Reference to the value previously stored in the
   *                          tree for the given key
   * 
   * \return \c true if the given key-value pair was successfully deleted from
603
   *         the tree, \c false if there is not enough memory
604 605 606 607 608 609 610 611 612
   */
  bool TryDelete(const Key& key, Value& old_value);
  
  
  /**
   * Accessor for the capacity of the tree.
   * 
   * \return Number of key-value pairs the tree can store
   */
613
  size_t GetCapacity() const;
614 615 616 617 618 619
  
  /**
   * Accessor for the dummy value used by the tree
   * 
   * \return Object of type \c Value that is used by the tree as a dummy value
   */
620
  const Value& GetUndefinedValue() const;
621 622 623 624 625 626
  
  /**
   * Checks whether the tree is currently empty.
   * 
   * \return \c true if the tree stores no key-value pairs, \c false otherwise
   */
627
  bool IsEmpty() const;
628 629

 private:
630
  /** Node of the tree. */
631
  typedef internal::ChromaticTreeNode<Key, Value>   Node;
632
  /** Atomic pointer to a node. */
633
  typedef embb::base::Atomic<Node*>                 AtomicNodePtr;
634
  /** Hazard-protected pointer to a node. */
635
  typedef internal::UniqueHazardPointer<Node>       HazardNodePtr;
636
  /** Chromatic tree operation. */
637
  typedef internal::ChromaticTreeOperation<Key, Value> Operation;
638
  /** Atomic pointer to a tree operation. */
639
  typedef embb::base::Atomic<Operation*>               AtomicOperationPtr;
640
  /** Hazard-protected pointer to a tree operation. */
641
  typedef internal::UniqueHazardPointer<Operation>     HazardOperationPtr;
642
  /** Object pool for tree nodes. */
643
  typedef ObjectPool<Node, ValuePool>               NodePool;
644
  /** Object pool for tree operations. */
645
  typedef ObjectPool<Operation, ValuePool>          OperationPool;
646

647
  /** Enumeration of used hazard pointer indexes. */
648
  typedef enum {
649
    // Node/operation used for helping
650
    HIDX_HELPING = 0,
651
    // Common shared nodes/operations
652
    HIDX_GRANDGRANDPARENT,
653
    HIDX_GRANDPARENT,
654 655 656
    HIDX_PARENT,
    HIDX_LEAF,
    HIDX_SIBLING = HIDX_GRANDGRANDPARENT, // Never occur in the same scope
657
    // Rebalancing nodes/operations
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677
    HIDX_U    = HIDX_GRANDGRANDPARENT, // Renamed when passed to "Rebalance"
    HIDX_UX   = HIDX_GRANDPARENT,      // Renamed when passed to "Rebalance"
    HIDX_UXX  = HIDX_PARENT,           // Renamed when passed to "Rebalance"
    HIDX_UXXX = HIDX_LEAF,             // Renamed when passed to "Rebalance"
    HIDX_UXL = HIDX_LEAF + 1, // Restoring sequence
    HIDX_UXR,
    HIDX_UXXL,
    HIDX_UXXR,
    // Left overweight
    HIDX_UXXRL  = HIDX_U,   // Reusing hazard guard that is no longer used
    HIDX_UXXRR  = HIDX_UXR, // Reusing hazard guard that is no longer used
    HIDX_UXXRLR = HIDX_UXR, // Reusing hazard guard that is no longer used
    HIDX_UXXRLL = HIDX_UXL, // Reusing hazard guard that is no longer used
    // Right overweight
    HIDX_UXXLR  = HIDX_UXXRL,  // Symmetric rotation
    HIDX_UXXLL  = HIDX_UXXRR,  // Symmetric rotation
    HIDX_UXXLRL = HIDX_UXXRLR, // Symmetric rotation
    HIDX_UXXLRR = HIDX_UXXRLL, // Symmetric rotation
    // Current operation object
    HIDX_CURRENT_OP = HIDX_UXXR + 1, // Restoring sequence
678 679
    HIDX_MAX
  } HazardIndex;
680

681 682 683 684 685 686 687 688 689 690
  /**
   * Follows a path from the root of the tree to some leaf searching for the 
   * given key (the leaf found by this method may or may not contain the given
   * key). Returns the reached leaf together with its ancestors.
   * 
   * \param[IN]     key         Key to be searched for
   * \param[IN,OUT] leaf        Reference to the reached leaf
   * \param[IN,OUT] parent      Reference to the parent of the reached leaf
   * \param[IN,OUT] grandparent Reference to the grandparent of the reached leaf
   */
691 692
  void Search(const Key& key, HazardNodePtr& leaf, HazardNodePtr& parent,
              HazardNodePtr& grandparent);
693 694 695 696 697 698 699 700 701 702
  
  /**
   * Checks whether the given node has a specified child node.
   * 
   * \param[IN] parent Parent node
   * \param[IN] child  Node that is supposed to be a child of \c parent
   * 
   * \return \c true if \c child is a child node of \c parent, \c false
   *         otherwise
   */
703 704
  bool HasChild(const Node* parent, const Node* child) const;

705 706 707 708 709 710 711 712
  /**
   * Destroys all the nodes of a subtree rooted at the given node, including the
   * node itself.
   * 
   * \notthreadsafe
   * 
   * \param node Root of the subtree to be destroyed
   */
713
  void Destruct(Node* node);
714 715 716 717 718 719 720 721 722 723 724

  /**
   * Computes the hight of the subtree rooted at the given node.
   *
   * \notthreadsafe
   *
   * \param[IN] node Root of the subtree for which the height is requested
   *
   * \return The height of a subtree rooted at node \c node. (The height of a
   *         leaf node is defined to be zero).
   */
725
  int GetHeight(const Node* node) const;
726

727 728 729 730 731 732
  /**
   * Check whether the tree is currently in a balanced state (if it is a valid
   * red-black tree).
   *
   * \return \c true if the tree is balanced, \c false otherwise
   */
733
  bool IsBalanced() const;
734 735 736 737 738 739 740 741

  /**
   * Check whether a subtree rooted at the given node is balanced.
   *
   * \param[IN] node Root of the subtree for which the balance is checked
   *
   * \return \c true if the tree is balanced, \c false otherwise
   */
742
  bool IsBalanced(const Node* node) const;
743

744
  /**
745 746 747 748 749 750 751 752 753
   * Checks whether a given operation is a dummy operation.
   *
   * \param[IN] operation Operation to be checked
   *
   * \return \c true if the given operation is a dummy, \c false otherwise
   */
  bool IsDummyOperation(const Operation* operation) const;

  /**
754 755 756 757
   * Retire a hazardous node using the node hazard manager.
   *
   * \param node A hazardous node to be retired
   */
758 759
  void RetireNode(HazardNodePtr& node);

760 761 762 763 764
  /**
   * Retire a hazardous operation object using the operation hazard manager.
   *
   * \param operation A hazardous operation to be retired
   */
765 766
  void RetireOperation(HazardOperationPtr& operation);

767 768 769 770 771 772 773 774
  /**
   * Get a node hazard guard with the specified \c index from the node hazard
   * manager.
   *
   * \param index Index of requested guard
   *
   * \return Hazard guard with the specified index
   */
775 776
  AtomicNodePtr& GetNodeGuard(HazardIndex index);

777 778 779 780 781 782 783 784
  /**
   * Get an operation hazard guard with the specified \c index from the
   * operation hazard manager.
   *
   * \param index Index of requested guard
   *
   * \return Hazard guard with the specified index
   */
785 786
  AtomicOperationPtr& GetOperationGuard(HazardIndex index);

787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
  /**
   * Performs a WeakLLX operation according to the Tree Update template, i.e.
   * reads the operation pointer of the given \c node and check whether this
   * operation is completed or in progress. If it is completed and the \c node
   * is not retired, returns \c true and sets the \c operation variable to point
   * to the read operation. If the read operation is in progress, helps it and 
   * returns \c false.
   *
   * \param node      The node
   * \param operation Reference to the current operation pointer value of the
   *                  \c node to be used in the following SCX
   *
   * \return \c true if the \c node is not reserved by another operation and the
   *         \c operation was successfully read, \c false if the \c node is busy
   */
802
  bool WeakLLX(HazardNodePtr& node, HazardOperationPtr& operation);
803 804 805 806 807 808

  /**
   * Free a tree node by returning it to the node pool.
   *
   * \param[IN] node A node to be freed.
   */
809
  void FreeNode(Node* node);
810

811 812 813 814 815
  /**
   * Free a tree operation by returning it to the operation pool.
   *
   * \param[IN] operation An operation to be freed.
   */
816 817
  void FreeOperation(Operation* operation);

818 819 820 821 822
  /**
   * Follows the path from the root to some leaf (directed by the given key) and
   * checks for any tree balancing violations. If a violation is found, tries
   * to fix it by using a set of rebalancing rotations.
   * 
823
   * \param[IN] key Key to be searched for
824 825 826 827 828 829 830 831
   * 
   * \return \c true if the tree was successfully rebalanced, \c false otherwise
   */
  bool CleanUp(const Key& key);
  
  /**
   * Next block of methods is used internally to keep the balance of the tree.
   */
832 833 834
  embb_errors_t Rebalance(HazardNodePtr& u, HazardNodePtr& ux,
                          HazardNodePtr& uxx, HazardNodePtr& uxxx);

835 836 837
  embb_errors_t OverweightLeft(HazardNodePtr& u, HazardOperationPtr& u_op,
                               HazardNodePtr& ux, HazardOperationPtr& ux_op,
                               HazardNodePtr& uxx, HazardOperationPtr& uxx_op,
838
                               HazardNodePtr& uxl, HazardNodePtr& uxr,
839
                               HazardNodePtr& uxxl, HazardOperationPtr& uxxl_op,
840 841
                               HazardNodePtr& uxxr, bool uxx_is_left);

842 843 844
  embb_errors_t OverweightRight(HazardNodePtr& u, HazardOperationPtr& u_op,
                                HazardNodePtr& ux, HazardOperationPtr& ux_op,
                                HazardNodePtr& uxx, HazardOperationPtr& uxx_op,
845 846
                                HazardNodePtr& uxl, HazardNodePtr& uxr,
                                HazardNodePtr& uxxl, HazardNodePtr& uxxr,
847
                                HazardOperationPtr& uxxr_op, bool uxx_is_right);
848

849 850 851 852 853
  // The following included header contains the class methods implementing
  // tree rotations. It is generated automatically and must be included
  // directly inside the class definition.
# include <embb/containers/internal/lock_free_chromatic_tree-rebalance.h>

854
  /** Hazard pointer manager for protecting node pointers. */
855
  internal::HazardPointer<Node*> node_hazard_manager_;
856
  /** Hazard pointer manager for protecting operation pointers. */
857
  internal::HazardPointer<Operation*> operation_hazard_manager_;
858

859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876
  /** A dummy key used by the tree. */
  const Key     undefined_key_;   
  /** A dummy value used by the tree. */
  const Value   undefined_value_; 
  /** Comparator object for the keys. */
  const Compare compare_;         
  /** User-requested capacity of the tree. */
  size_t        capacity_;        
  /** Pool of tree nodes. */
  NodePool      node_pool_;       
  /** Pool of operation objects. */
  OperationPool operation_pool_;  
  /** Dummy operation used in newly created nodes. */
  Operation     initial_operation_dummy_;
  /** Dummy operation used in retired nodes. */
  Operation     retired_operation_dummy_;
  /** Pointer to the sentinel node used as the entry point into the tree. */
  Node* const   entry_;
877

878 879 880
  /**
   * Friending the test class for white-box testing
   */
881
  friend class test::TreeTest<ChromaticTree>;
882 883 884 885 886 887 888 889
};

} // namespace containers
} // namespace embb

#include <embb/containers/internal/lock_free_chromatic_tree-inl.h>

#endif // EMBB_CONTAINERS_LOCK_FREE_CHROMATIC_TREE_H_