// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FBL_INTRUSIVE_WAVL_TREE_H_
#define FBL_INTRUSIVE_WAVL_TREE_H_

#include <zircon/assert.h>
#include <fbl/algorithm.h>
#include <fbl/intrusive_container_utils.h>
#include <fbl/intrusive_pointer_traits.h>
#include <fbl/intrusive_wavl_tree_internal.h>

#include <utility>

// Implementation Notes:
//
// WAVLTree<> is an implementation of a "Weak AVL" tree; a self
// balancing binary search tree whose rebalancing algorithm was
// originally described in
//
// Bernhard Haeupler, Siddhartha Sen, and Robert E. Tarjan. 2015.
// Rank-Balanced Trees. ACM Trans. Algorithms 11, 4, Article 30 (June 2015), 26 pages.
// DOI=http://dx.doi.org/10.1145/2689412
//
// See also
// https://en.wikipedia.org/wiki/WAVL_tree
// http://sidsen.azurewebsites.net/papers/rb-trees-talg.pdf
//
// WAVLTree<>s, like HashTables, are associative containers and support all of
// the same key-centric operations (such as find() and insert_or_find()) that
// HashTables support.
//
// Additionally, WAVLTree's are internally ordered by key (unlike HashTables
// which are un-ordered).  Iteration forwards or backwards runs in amortized
// constant time, but in O(log) time in an individual worst case.  Forward
// iteration will enumerate the elements in monotonically increasing order (as
// defined by the KeyTraits::LessThan operation).
//
// Two additional operations are supported because of the ordered nature of a
// WAVLTree:
// upper_bound(key) : Finds the element (E) in the tree such that E.key > key
// lower_bound(key) : Finds the element (E) in the tree such that E.key >= key
//
// The worst depth of a WAVL tree depends on whether or not the tree has ever
// been subject to erase operations.
// ++ If the tree has seen only insert operations, the worst case depth of the
//    tree is log_phi(N), where phi is the golden ratio.  This is the same bound
//    as that of an AVL tree.
// ++ If the tree has seen erase operations in addition to insert operations,
//    the worst case depth of the tree is 2*log_2(N).  This is the same bound as
//    a Red-Black tree.
//
// Insertion runs in O(log) time; finding the location takes O(log) time while
// post-insert rebalancing runs in amortized constant time.
//
// Erase-by-key runs in O(log) time; finding the node to erase takes O(log) time
// while post-erase rebalancing runs in amortized constant time.
//
// Because of the intrusive nature of the container, direct-erase operations
// (AKA, erase operations where the reference to the element to be erased is
// already known) run in amortized constant time.
//
namespace fbl {

namespace tests {
namespace intrusive_containers {
class WAVLTreeChecker;
class WAVLBalanceTestObserver;
}  // namespace tests
}  // namespace intrusive_containers

template <typename PtrType, typename RankType>
struct WAVLTreeNodeStateBase {
    using PtrTraits = internal::ContainerPtrTraits<PtrType>;

    bool IsValid() const     { return (parent_ || (!parent_ && !left_ && !right_)); }
    bool InContainer() const { return (parent_ != nullptr); }

protected:
    template <typename, typename, typename, typename, typename, typename> friend class WAVLTree;
    friend class tests::intrusive_containers::WAVLTreeChecker;
    friend class tests::intrusive_containers::WAVLBalanceTestObserver;

    typename PtrTraits::RawPtrType parent_ = nullptr;
    typename PtrTraits::RawPtrType left_   = nullptr;
    typename PtrTraits::RawPtrType right_  = nullptr;
    RankType rank_;
};

template <typename PtrType>
struct WAVLTreeNodeState<PtrType, DefaultWAVLTreeRankType>
       : public WAVLTreeNodeStateBase<PtrType, DefaultWAVLTreeRankType> {
    bool rank_parity() const   { return this->rank_; }
    void promote_rank()        { this->rank_ = !this->rank_; }
    void double_promote_rank() { }
    void demote_rank()         { this->rank_ = !this->rank_; }
    void double_demote_rank()  { }
};

template <typename PtrType, typename TagType>
struct WAVLTreeContainable;

template <typename PtrType, typename RankType = DefaultWAVLTreeRankType>
struct DefaultWAVLTreeTraits {
private:
    using ValueType = typename internal::ContainerPtrTraits<PtrType>::ValueType;

    template <typename TagType>
    using NodeType = std::conditional_t<internal::has_tag_types_v<ValueType>,
                                        WAVLTreeContainable<PtrType, TagType>,
                                        ValueType>;

public:
    using PtrTraits = internal::ContainerPtrTraits<PtrType>;
    template <typename TagType = DefaultObjectTag>
    static WAVLTreeNodeState<PtrType, RankType>& node_state(typename PtrTraits::RefType obj) {
        using Node [[maybe_unused]] = NodeType<TagType>;
        return obj.Node::wavl_node_state_;
    }
};

template <typename PtrType, typename TagType_ = DefaultObjectTag>
struct WAVLTreeContainable {
public:
    using TagType = TagType_;
    template <typename TagType = TagType_>
    bool InContainer() const {
        using Node = NodeType<TagType>;
        return Node::wavl_node_state_.InContainer();
    }

private:
    friend DefaultWAVLTreeTraits<PtrType, DefaultWAVLTreeRankType>;
    WAVLTreeNodeState<PtrType, DefaultWAVLTreeRankType> wavl_node_state_;

    using ValueType = typename internal::ContainerPtrTraits<PtrType>::ValueType;

    template <typename TagType>
    using NodeType = std::conditional_t<std::is_same_v<TagType, DefaultObjectTag>,
                                        WAVLTreeContainable<PtrType, TagType>,
                                        ValueType>;
};

template <typename KeyType_,
          typename PtrType_,
          typename KeyTraits_  = DefaultKeyedObjectTraits<
                                    KeyType_,
                                    typename internal::ContainerPtrTraits<PtrType_>::ValueType>,
          typename NodeTraits_ = DefaultWAVLTreeTraits<PtrType_>,
          typename TagType_    = DefaultObjectTag,
          typename Observer_   = tests::intrusive_containers::DefaultWAVLTreeObserver>
class WAVLTree {
private:
    // Private fwd decls of the iterator implementation.
    template <typename IterTraits> class iterator_impl;
    struct iterator_traits;
    struct const_iterator_traits;

    template <typename NodeTraits, typename = void>
    struct AddGenericNodeState;

public:
    // Aliases used to reduce verbosity and expose types/traits to tests
    using KeyType       = KeyType_;
    using PtrType       = PtrType_;
    using KeyTraits     = KeyTraits_;
    using NodeTraits    = AddGenericNodeState<NodeTraits_>;
    using TagType       = TagType_;
    using Observer      = Observer_;
    using PtrTraits     = internal::ContainerPtrTraits<PtrType>;
    using RawPtrType    = typename PtrTraits::RawPtrType;
    using ValueType     = typename PtrTraits::ValueType;
    using ContainerType = WAVLTree<KeyType, PtrType, KeyTraits, NodeTraits_, TagType, Observer>;
    using CheckerType   = ::fbl::tests::intrusive_containers::WAVLTreeChecker;

    // Declarations of the standard iterator types.
    using iterator       = iterator_impl<iterator_traits>;
    using const_iterator = iterator_impl<const_iterator_traits>;

    // WAVL Trees support amortized constant erase.  Technically, the worst case
    // for any individual erase operation involves O(log) demotions, followed by
    // a double rotation operation.  Given D total erase operations, however,
    // the maximum number of operations (demotions + rotations) is 2*D, given
    // the amortized constant erase time.
    //
    static constexpr bool SupportsConstantOrderErase = true;
    static constexpr bool SupportsConstantOrderSize = true;
    static constexpr bool IsAssociative = true;
    static constexpr bool IsSequenced = false;

    // Default construction gives an empty tree.
    constexpr WAVLTree() { }

    // Rvalue construction is permitted, but will result in the move of the tree
    // contents from one instance of the list to the other (even for unmanaged
    // pointers)
    WAVLTree(WAVLTree&& other_tree) {
        swap(other_tree);
    }

    // Rvalue assignment is permitted for managed trees, and when the target is
    // an empty tree of unmanaged pointers.  Like Rvalue construction, it will
    // result in the move of the source contents to the destination.
    WAVLTree& operator=(WAVLTree&& other_tree) {
        ZX_DEBUG_ASSERT(PtrTraits::IsManaged || is_empty());

        clear();
        swap(other_tree);

        return *this;
    }

    ~WAVLTree() {
        // It is considered an error to allow a tree of unmanaged pointers to
        // destruct of there are still elements in it.  Managed pointer trees
        // will automatically release their references to their elements.
        ZX_DEBUG_ASSERT(PtrTraits::IsManaged || is_empty());
        clear();
    }

    // Standard begin/end, cbegin/cend iterator accessors.
    iterator        begin()       { return iterator(left_most_); }
    const_iterator  begin() const { return const_iterator(left_most_); }
    const_iterator cbegin() const { return const_iterator(left_most_); }

    iterator          end()       { return iterator(sentinel()); }
    const_iterator    end() const { return const_iterator(sentinel()); }
    const_iterator   cend() const { return const_iterator(sentinel()); }

    // make_iterator : construct an iterator out of a pointer to an object
    iterator make_iterator(ValueType& obj) { return iterator(&obj); }

    // is_empty : True if the tree has at least one element in it, false otherwise.
    bool is_empty() const { return root_ == nullptr; }

    // front
    //
    // Return a reference to the element at the front of the list without
    // removing it.  It is an error to call front on an empty list.
    typename PtrTraits::RefType front() {
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(left_most_));
        return *left_most_;
    }

    typename PtrTraits::ConstRefType front() const {
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(left_most_));
        return *left_most_;
    }

    // back
    //
    // Return a reference to the element at the back of the list without
    // removing it.  It is an error to call back on an empty list.
    typename PtrTraits::RefType back() {
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(right_most_));
        return *right_most_;
    }

    typename PtrTraits::ConstRefType back() const {
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(right_most_));
        return *right_most_;
    }

    void insert(const PtrType& ptr) { insert(PtrType(ptr)); }
    void insert(PtrType&& ptr)      { internal_insert(ptr); }

    // insert or find
    //
    // Insert the object pointed to by ptr if it is not already in the
    // tree, or find the object that the ptr collided with instead.
    //
    // @param ptr A pointer to the new object to insert.
    // @param iter An optional out parameter pointer to an iterator which
    // will reference either the newly inserted item, or the item whose key
    // collided with ptr.
    //
    // @return true if there was no collision and the item was successfully
    // inserted.  false otherwise.
    //
    bool insert_or_find(const PtrType& ptr, iterator* iter = nullptr) {
        return insert_or_find(PtrType(ptr), iter);
    }

    bool insert_or_find(PtrType&& ptr, iterator* iter = nullptr) {
        RawPtrType obj = PtrTraits::GetRaw(ptr);
        RawPtrType collision = nullptr;

        internal_insert(ptr, &collision);

        if (iter)
            *iter = collision ? iterator(collision) : iterator(obj);

        return !collision;
    }

    // insert_or_replace
    //
    // Find the element in the tree with the same key as *ptr and replace
    // it with ptr, then return the pointer to the element which was replaced.
    // If no element in the tree shares a key with *ptr, simply add ptr to
    // the tree and return nullptr.
    //
    PtrType insert_or_replace(const PtrType& ptr) {
        return insert_or_replace(PtrType(ptr));
    }

    PtrType insert_or_replace(PtrType&& ptr) {
        ZX_DEBUG_ASSERT(ptr != nullptr);
        ZX_DEBUG_ASSERT(! NodeTraits::node_state(*ptr).InContainer());

        RawPtrType collision = nullptr;
        internal_insert(ptr, &collision);

        // If there was a collision, swap our node with the node we collided
        // with.
        if (collision) {
            ZX_DEBUG_ASSERT(ptr != nullptr);
            return internal_swap(collision, std::move(ptr));
        }

        return nullptr;
    }

    // pop_front and pop_back
    //
    // Removes either the left-most or right-most member of tree and transfers
    // the pointer to the caller.  If the list is empty, return a nullptr
    // instance of PtrType.
    PtrType pop_front() { return internal_erase(left_most_); }
    PtrType pop_back()  { return internal_erase(right_most_); }

    // find
    //
    // Find the first node in the tree whose key matches "key" and return an
    // iterator to it.  Return end() if no node in the tree has a key which
    // matches "key".
    const_iterator find(const KeyType& key) const {
        RawPtrType node = root_;

        while (internal::valid_sentinel_ptr(node)) {
            auto node_key = KeyTraits::GetKey(*node);

            if (KeyTraits::EqualTo(key, node_key))
                return const_iterator(node);

            auto& ns = NodeTraits::node_state(*node);
            node = KeyTraits::LessThan(key, node_key) ? ns.left_ : ns.right_;
        }

        return end();
    }

    iterator find(const KeyType& key) {
        const_iterator citer = const_cast<const ContainerType*>(this)->find(key);
        return iterator(citer.node_);
    }

    // upper_bound
    //
    // Find the first node in the tree whose key is strictly greater than the
    // caller provided key.  Returns end() if no such node exists.
    const_iterator upper_bound(const KeyType& key) const {
        return internal_upper_lower_bound<UpperBoundTraits>(key);
    }

    iterator upper_bound(const KeyType& key) {
        const_iterator citer = const_cast<const ContainerType*>(this)->upper_bound(key);
        return iterator(citer.node_);
    }

    // lower_bound
    //
    // Find the first node in the tree whose key is greater than or equal to the
    // caller provided key.  Returns end() if no such node exists.
    const_iterator lower_bound(const KeyType& key) const {
        return internal_upper_lower_bound<LowerBoundTraits>(key);
    }

    iterator lower_bound(const KeyType& key) {
        const_iterator citer = const_cast<const ContainerType*>(this)->lower_bound(key);
        return iterator(citer.node_);
    }

    // erase
    //
    // Remove the first element in the tree whose key matches "key" and return a
    // pointer the removed object.  Return a nullptr instance of PtrType if no
    // such element exists in the tree.
    PtrType erase(const KeyType& key) { return erase(find(key)); }

    // erase (direct)
    //
    // Remove the object directly referenced either by "iter" or "obj" from the
    // tree and return a pointer to it.  In the case of an iterator based erase,
    // return a nullptr instance of PtrType if the iterator is invalid.  It is
    // an error to either use a valid iterator from a different tree instance,
    // or to attempt to remove an element which is not currently a member of
    // this tree instance.
    PtrType erase(const iterator& iter) {
        if (!iter.IsValid())
            return PtrType(nullptr);

        return internal_erase(&(*iter));
    }

    PtrType erase(ValueType& obj) {
        return internal_erase(&obj);
    }

    // clear
    //
    // Clear out the tree, unlinking all of the elements in the process.  For
    // managed pointer types, this will release all references held by the tree
    // to the objects which were in it.
    void clear() {
        if (is_empty())
            return;

        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(root_));
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(left_most_));
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(right_most_));

        // Clear the left and right sentinels right now so that we don't have
        // to worry about special casing them while cleaning up the tree.
        NodeTraits::node_state(*left_most_).left_   = nullptr;
        NodeTraits::node_state(*right_most_).right_ = nullptr;

        RawPtrType  owner    = sentinel();
        RawPtrType* link_ptr = &root_;

        while (true) {
            auto& ns = NodeTraits::node_state(**link_ptr);

            if ((ns.left_ == nullptr) && (ns.right_ == nullptr)) {
                // Leaf node.  Trim it.  Start by reclaiming the pointer
                // reference (if this is a managed pointer type) and holding
                // onto it until the end of this scope.  Note, we need to flag
                // this temp copy of the reference as UNUSED in case the pointer
                // type is unmanaged.
                ZX_DEBUG_ASSERT(ns.parent_ == owner);
                __UNUSED PtrType leaf = PtrTraits::Reclaim(*link_ptr);

                // This leaf node node now has no parent, and the pointer which
                // pointed to us is now null.
                ns.parent_ = nullptr;
                *link_ptr  = nullptr;

                // If we are removing the root, and it is a leaf node, then we
                // are done.
                if (link_ptr == &root_)
                    break;

                // Now climb back up the tree.
                link_ptr = &GetLinkPtrToNode(owner);
                owner    = NodeTraits::node_state(*owner).parent_;
            } else {
                // Non-leaf node, descend.  We have already detached the left
                // and right sentinels, so we shouldn't be seeing any here.
                ZX_DEBUG_ASSERT(!internal::is_sentinel_ptr(ns.left_));
                ZX_DEBUG_ASSERT(!internal::is_sentinel_ptr(ns.right_));

                owner    = *link_ptr;
                link_ptr = (ns.left_ != nullptr) ? &ns.left_ : &ns.right_;
            }
        }

        ZX_DEBUG_ASSERT(root_ == nullptr);
        left_most_  = sentinel();
        right_most_ = sentinel();
        count_ = 0;
    }

    // clear_unsafe
    //
    // See comments in fbl/intrusive_single_list.h
    // Think carefully before calling this!
    void clear_unsafe() {
        static_assert(PtrTraits::IsManaged == false,
                     "clear_unsafe is not allowed for containers of managed pointers");

        root_       = nullptr;
        left_most_  = sentinel();
        right_most_ = sentinel();
        count_      = 0;
    }

    // swap : swaps the contents of two trees.
    void swap(WAVLTree& other) {
        internal::Swap(root_,       other.root_);
        internal::Swap(left_most_,  other.left_most_);
        internal::Swap(right_most_, other.right_most_);
        internal::Swap(count_,      other.count_);

        // Fix up the sentinel values.
        FixSentinelsAfterSwap();
        other.FixSentinelsAfterSwap();
    }

    // size : return the current number of elements in the tree.
    size_t size() const { return count_; }

    // erase_if
    //
    // Find the first member of the list which satisfies the predicate given by
    // 'fn' and erase it from the list, returning a referenced pointer to the
    // removed element.  Return nullptr if no element satisfies the predicate.
    template <typename UnaryFn>
    PtrType erase_if(UnaryFn fn) {
        for (auto iter = begin(); iter != end(); ++iter) {
            if (fn(*iter))
                return erase(iter);
        }
        return PtrType(nullptr);
    }

    // find_if
    //
    // Find the first member of the list which satisfies the predicate given by
    // 'fn' and return a const& to the PtrType in the list which refers to it.
    // Return nullptr if no member satisfies the predicate.
    template <typename UnaryFn>
    const_iterator find_if(UnaryFn fn) const {
        for (auto iter = begin(); iter != end(); ++iter)
            if (fn(*iter))
                return const_iterator(iter.node_);

        return const_iterator(sentinel());
    }

    template <typename UnaryFn>
    iterator find_if(UnaryFn fn) {
        const_iterator citer = const_cast<const ContainerType*>(this)->find_if(fn);
        return iterator(citer.node_);
    }

private:
    // The traits of a non-const iterator
    struct iterator_traits {
        using RefType    = typename PtrTraits::RefType;
        using RawPtrType = typename PtrTraits::RawPtrType;
    };

    // The traits of a const iterator
    struct const_iterator_traits {
        using RefType    = typename PtrTraits::ConstRefType;
        using RawPtrType = typename PtrTraits::ConstRawPtrType;
    };

    // Trait classes used to help implement symmetric operations.
    //
    // Notes about notation:
    // + LR denotes Left for the Forward version of the operation and Right
    //   for the Reverse version.
    // + RL denotes Right for the Forward version of the operation and Left
    //   for the Reverse version.
    //
    // Examples...
    // Forward : LR-child of node X == the left child of node X.
    // Reverse : LR-child of node X == the right child of node X.
    //
    // Forward : RL-most node of the tree == the right most node of the tree
    // Reverse : RL-most node of the tree == the left most node of the tree
    struct ReverseTraits;   // fwd decl
    struct ForwardTraits {
        using Inverse = ReverseTraits;

        template <typename NodeState>
        static RawPtrType& LRChild(NodeState& ns) { return ns.left_;  }
        template <typename NodeState>
        static RawPtrType& RLChild(NodeState& ns) { return ns.right_; }

        static RawPtrType& LRMost(ContainerType& tree) { return tree.left_most_; }
        static RawPtrType& RLMost(ContainerType& tree) { return tree.right_most_; }
    };

    struct ReverseTraits {
        using Inverse = ForwardTraits;

        template <typename NodeState>
        static RawPtrType& LRChild(NodeState& ns) { return ns.right_; }
        template <typename NodeState>
        static RawPtrType& RLChild(NodeState& ns) { return ns.left_;  }

        static RawPtrType& LRMost(ContainerType& tree) { return tree.right_most_; }
        static RawPtrType& RLMost(ContainerType& tree) { return tree.left_most_; }
    };

    // Trait classes used to define the bound condition for upper_bound and
    // lower_bound.
    struct UpperBoundTraits {
        static bool GoRight(const KeyType& key, const KeyType& node_key) {
            return KeyTraits::EqualTo(node_key, key) || KeyTraits::LessThan(node_key, key);
        }
    };

    struct LowerBoundTraits {
        static bool GoRight(const KeyType& key, const KeyType& node_key) {
            return KeyTraits::LessThan(node_key, key);
        }
    };

    // The shared implementation of the iterator
    template <class IterTraits>
    class iterator_impl {
    public:
        iterator_impl() { }
        iterator_impl(const iterator_impl& other) { node_ = other.node_; }

        iterator_impl& operator=(const iterator_impl& other) {
            node_ = other.node_;
            return *this;
        }

        bool IsValid() const { return internal::valid_sentinel_ptr(node_); }
        bool operator==(const iterator_impl& other) const { return node_ == other.node_; }
        bool operator!=(const iterator_impl& other) const { return node_ != other.node_; }

        // Prefix
        iterator_impl& operator++() {
            if (IsValid())
                advance<ForwardTraits>();
            return *this;
        }

        iterator_impl& operator--() {
            // If this was a default constructed iterator, then it cannot
            // back up.
            if (node_ != nullptr) {
                // If we are at the end() of the tree, then recover the tree
                // pointer from the sentinel and back up to the right-most node.
                if (internal::is_sentinel_ptr(node_)) {
                    node_ = internal::unmake_sentinel<ContainerType*>(node_)->right_most_;
                } else {
                    advance<ReverseTraits>();
                }
            }

            return *this;
        }

        // Postfix
        iterator_impl operator++(int) {
            iterator_impl ret(*this);
            ++(*this);
            return ret;
        }

        iterator_impl operator--(int) {
            iterator_impl ret(*this);
            --(*this);
            return ret;
        }

        typename PtrTraits::PtrType CopyPointer() const {
            return IsValid() ? PtrTraits::Copy(node_) : nullptr;
        }

        typename IterTraits::RefType operator*()     const { ZX_DEBUG_ASSERT(node_); return *node_; }
        typename IterTraits::RawPtrType operator->() const { ZX_DEBUG_ASSERT(node_); return node_; }

    private:
        friend ContainerType;

        iterator_impl(typename PtrTraits::RawPtrType node) : node_(node) { }

        template <typename LRTraits>
        void advance() {
            ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(node_));

            // Find the next node in the ordered sequence.
            // key.  This will be either...
            // 1) The RL-most child of our LR-hand sub-tree.
            // 2) Our first ancestor for which we are a LR-hand descendant.
            auto ns = &NodeTraits::node_state(*node_);
            auto rl_child = LRTraits::RLChild(*ns);
            if (rl_child != nullptr) {
                node_ = rl_child;

                // The RL-hand child of the RL-most node is terminated
                // using the sentinel value for this tree instead of nullptr.
                // Have we hit it?  If so, then we are done.
                if (internal::is_sentinel_ptr(node_))
                    return;

                // While we can go LR, do so.
                auto lr_child = LRTraits::LRChild(NodeTraits::node_state(*node_));
                while (lr_child != nullptr) {
                    ZX_DEBUG_ASSERT(!internal::is_sentinel_ptr(lr_child));
                    node_    = lr_child;
                    lr_child = LRTraits::LRChild(NodeTraits::node_state(*node_));
                }
            } else {
                // Climb up the tree until we traverse a LR-hand link.  Because
                // of the sentinel termination, we should never attempt to climb
                // up past the root.
                bool done;
                auto ns = &NodeTraits::node_state(*node_);
                do {
                    ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(ns->parent_));

                    auto parent_ns = &NodeTraits::node_state(*ns->parent_);
                    done = (LRTraits::LRChild(*parent_ns) == node_);

                    ZX_DEBUG_ASSERT(done || (LRTraits::RLChild(*parent_ns) == node_));

                    node_ = ns->parent_;
                    ns    = parent_ns;
                } while (!done);
            }
        }

        typename PtrTraits::RawPtrType node_ = nullptr;
    };  // class iterator_impl

    template <typename BaseNodeTraits>
    struct AddGenericNodeState<
               BaseNodeTraits,
               std::enable_if_t<internal::has_node_state_v<BaseNodeTraits>>>
        : public BaseNodeTraits {};

    template <typename BaseNodeTraits>
    struct AddGenericNodeState<
               BaseNodeTraits,
               std::enable_if_t<!internal::has_node_state_v<BaseNodeTraits>>>
        : public BaseNodeTraits {
    private:
        using RankType = decltype(std::remove_reference_t<
            decltype(BaseNodeTraits::node_state(
                     *std::declval<typename PtrTraits::RawPtrType>()))>::rank_);

    public:
        static WAVLTreeNodeState<PtrType, RankType>& node_state(typename PtrTraits::RefType obj) {
            return DefaultWAVLTreeTraits<PtrType, RankType>::template node_state<TagType>(obj);
        }
    };

    // The test framework's 'checker' class is our friend.
    friend CheckerType;

    // move semantics only
    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(WAVLTree);

    void internal_insert(PtrType& ptr, RawPtrType* collision = nullptr) {
        ZX_DEBUG_ASSERT(ptr != nullptr);

        auto& ns = NodeTraits::node_state(*ptr);
        ZX_DEBUG_ASSERT(ns.IsValid() && !ns.InContainer());

        // The rank of an inserted node always starts at 0.
        ns.rank_ = 0;

        // If the tree is currently empty, then this is easy.
        if (root_ == nullptr) {
            ns.parent_ = sentinel();
            ns.left_   = sentinel();
            ns.right_  = sentinel();

            ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(left_most_) &&
                            internal::is_sentinel_ptr(right_most_));
            left_most_  = PtrTraits::GetRaw(ptr);
            right_most_ = PtrTraits::GetRaw(ptr);

            root_ = PtrTraits::Leak(ptr);

            ++count_;
            Observer::RecordInsert();
            return;
        }

        // Find the proper position for this node.
        auto key = KeyTraits::GetKey(*ptr);
        bool is_left_most  = true;
        bool is_right_most = true;
        RawPtrType  parent  = root_;
        RawPtrType* owner;

        while (true) {
            auto parent_key = KeyTraits::GetKey(*parent);

            // Looks like we collided with an object in the collection which has
            // the same key as the object being inserted.  This is only allowed
            // during an insert_or_find operation (collision is non-null).
            // Assert this in debug builds.  If this is an insert_or_find
            // operation, fill out the collision [out] parameter so the called
            // knows which object he/she collided with.  Either way, do not
            // actually insert the object.
            if (KeyTraits::EqualTo(key, parent_key)) {
                ZX_DEBUG_ASSERT(collision);

                if (collision) {
                    ZX_DEBUG_ASSERT(*collision == nullptr);
                    *collision = parent;
                }

                return;
            }

            auto& parent_ns = NodeTraits::node_state(*parent);

            // Decide which side of the current parent-under-consideration the
            // node to be inserted belongs on.  If we are going left, then we
            // are no longer right-most, and vice-versa.
            if (KeyTraits::LessThan(key, parent_key)) {
                owner = &parent_ns.left_;
                is_right_most = false;
            } else {
                owner = &parent_ns.right_;
                is_left_most = false;
            }

            // If we would have run out of valid pointers in the direction we
            // should be searching, then we are done.
            if (!internal::valid_sentinel_ptr(*owner))
                break;

            // We belong on a side of the parent-under-consideration which
            // already has a child.  Move down to the child and consider it
            // instead.
            parent = *owner;
        }

        // We know that we are not the root of the tree, therefore we cannot be
        // both left and right-most.
        ZX_DEBUG_ASSERT(!is_left_most || !is_right_most);

        if (is_right_most) {
            ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(*owner));
            ns.right_   = sentinel();
            right_most_ = PtrTraits::GetRaw(ptr);
        } else if (is_left_most) {
            ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(*owner));
            ns.left_   = sentinel();
            left_most_ = PtrTraits::GetRaw(ptr);
        }

        // The owner link must either be nullptr or the sentinel.  This is
        // equivalent to saying that the pointer is not valid (using the pointer
        // traits definition of "valid").
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(*owner) == false);
        ns.parent_ = parent;
        *owner = PtrTraits::Leak(ptr);

        ++count_;
        Observer::RecordInsert();

        // Finally, perform post-insert balance operations.
        BalancePostInsert(*owner);
    }

    PtrType internal_erase(RawPtrType ptr) {
        if (!internal::valid_sentinel_ptr(ptr))
            return PtrType(nullptr);

        auto& ns = NodeTraits::node_state(*ptr);
        RawPtrType* owner = &GetLinkPtrToNode(ptr);
        ZX_DEBUG_ASSERT(*owner == ptr);

        // If the node we want to remove has two children, swap it with the
        // left-most node of the right-hand sub-tree before proceeding.  This
        // will guarantee that we are operating in a 0 or 1 child case.
        if (internal::valid_sentinel_ptr(ns.left_) && internal::valid_sentinel_ptr(ns.right_)) {
            RawPtrType* new_owner = &ns.right_;
            auto        new_ns    = &NodeTraits::node_state(*ns.right_);

            while (new_ns->left_ != nullptr) {
                ZX_DEBUG_ASSERT(!internal::is_sentinel_ptr(new_ns->left_));
                new_owner = &new_ns->left_;
                new_ns = &NodeTraits::node_state(*new_ns->left_);
            }

            owner = SwapWithRightDescendant(*owner, *new_owner);
            ZX_DEBUG_ASSERT(*owner == ptr);
        }

        // Now that we know our relationship with our parent, go ahead and start
        // the process of removing the node.  Keep track of the target node's
        // parent, whether it was it's parent's left or right child, and whether
        // it was a 1-child or a 2-child.  We will need this info when it comes
        // time to rebalance.
        RawPtrType parent = ns.parent_;
        bool was_one_child, was_left_child;

        ZX_DEBUG_ASSERT(parent != nullptr);
        if (!internal::is_sentinel_ptr(parent)) {
            auto& parent_ns = NodeTraits::node_state(*parent);

            was_one_child  = ns.rank_parity() != parent_ns.rank_parity();
            was_left_child = &parent_ns.left_ == owner;
        } else {
            was_one_child  = false;
            was_left_child = false;
        }

        // Reclaim our refernce from our owner and unlink.  We return the to the
        // caller when we are done.
        PtrType removed = PtrTraits::Reclaim(*owner);
        *owner = nullptr;

        // We know that we have at most one child.  If we do have a child,
        // promote it to our position.  While we are handling the cases,
        // maintain the LR-most bookkeeping.  Consider the 1 and 0 child cases
        // separately.
        //
        // 1-child case:
        // We are promoting the LR-child.  If we were RL-most, then our RL-child
        // is the sentinel value.  We need to transfer this sentinel value to
        // the RL-most node in our LR-subtree.  We also need to update the
        // parent pointer of our LR-child to point to the removed node's parent.
        //
        // 0-child case:
        // We are not promoting any node, but we may or may not have been the
        // LR-most.
        //
        // ++ If the target is both the left and right-most node in the tree, it
        //    is a leaf, then the target *must* be the final node in the tree.  The
        //    tree's left and right-most need to be updated to be the sentinel
        //    value, and the sentinels need to be cleared from the target node's
        //    state structure.
        // ++ If the target is the LR-most node in the tree and a leaf, then its
        //    parent is now the LR-most node in the tree.  We need to transfer
        //    the sentinel from the target's LR-child to the pointer which used
        //    to point to it, and update the LR-most bookkeeping in the tree to
        //    point to the target's parent. The target node's RL-child should
        //    already be nullptr.
        // ++ If the target neither the left nor the right most node in the
        //    tree, then nothing special needs to happen with regard to the
        //    left/right-most bookkeeping.
        RawPtrType target = PtrTraits::GetRaw(removed);
        if (internal::valid_sentinel_ptr(ns.left_)) {
            PromoteLRChild<ForwardTraits>(*owner, target);
        } else
        if (internal::valid_sentinel_ptr(ns.right_)) {
            PromoteLRChild<ReverseTraits>(*owner, target);
        } else {
            // The target's LR-child is the sentinel if and only if the target
            // is the LR-most node in the tree.
            ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(ns.left_)  == (left_most_  == target));
            ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(ns.right_) == (right_most_ == target));

            if (internal::is_sentinel_ptr(ns.left_)) {
                if (internal::is_sentinel_ptr(ns.right_)) {
                    // Target is both left and right most.
                    ZX_DEBUG_ASSERT(count_ == 1);
                    ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(ns.parent_));
                    left_most_  = sentinel();
                    right_most_ = sentinel();
                    ns.left_    = nullptr;
                    ns.right_   = nullptr;
                } else {
                    // Target is just left most.
                    ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(ns.parent_));
                    ZX_DEBUG_ASSERT(ns.right_ == nullptr);
                    left_most_ = ns.parent_;
                    *owner = ns.left_;
                    ns.left_ = nullptr;
                }
            } else if (internal::is_sentinel_ptr(ns.right_)) {
                    // Target is just right most.
                    ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(ns.parent_));
                    ZX_DEBUG_ASSERT(ns.left_ == nullptr);
                    right_most_ = ns.parent_;
                    *owner = ns.right_;
                    ns.right_ = nullptr;
            }

            // Disconnect the target's parent pointer and we should be done.
            ns.parent_ = nullptr;
        }

        // At this point in time, the target node should have been completely
        // removed from the tree.  Its internal state should be valid, and
        // indicate that it is not in the container.
        ZX_DEBUG_ASSERT(ns.IsValid() && !ns.InContainer());

        // Update the count bookkeeping.
        --count_;
        Observer::RecordErase();

        // Time to rebalance.  We know that we don't need to rebalance if we
        // just removed the root (IOW - its parent was the sentinel value).
        if (!internal::is_sentinel_ptr(parent)) {
            if (was_one_child) {
                // If the node we removed was a 1-child, then we may have just
                // turned its parent into a 2,2 leaf node.  If so, we have a
                // leaf node with non-zero rank and need to fix the problem.
                BalancePostErase_Fix22Leaf(parent);
            } else {
                // If the node we removed was a 2-child, the we may have just
                // created a 3 child which we need to fix.  The balance routine
                // will handle checking for us, but it will need to know whether
                // the node we removed was its parent's left or right child in
                // order to un-ambiguously perform the check.
                if (was_left_child) BalancePostErase_FixLR3Child<ForwardTraits>(parent);
                else                BalancePostErase_FixLR3Child<ReverseTraits>(parent);
            }
        }

        // Give the reference to the node we just removed back to the caller.
        return removed;
    }

    // internal::Swap a node which is currently in the tree with a new node.
    //
    // old_node *must* already be in the tree.
    // new_node *must* not be in the tree.
    // old_node and new_node *must* have the same key.
    //
    PtrType internal_swap(RawPtrType old_node, PtrType&& new_node) {
        ZX_DEBUG_ASSERT(old_node != nullptr);
        ZX_DEBUG_ASSERT(new_node != nullptr);
        ZX_DEBUG_ASSERT(KeyTraits::EqualTo(KeyTraits::GetKey(*old_node),
                                           KeyTraits::GetKey(*new_node)));

        auto& old_ns  = NodeTraits::node_state(*old_node);
        auto& new_ns  = NodeTraits::node_state(*new_node);
        auto  new_raw = PtrTraits::GetRaw(new_node);

        ZX_DEBUG_ASSERT(old_ns.InContainer());
        ZX_DEBUG_ASSERT(!new_ns.InContainer());

        // Start with the left child state.
        if (internal::valid_sentinel_ptr(old_ns.left_)) {
            // Fix the left-child's parent pointer.
            NodeTraits::node_state(*old_ns.left_).parent_ = new_raw;
        } else {
            // We have no left child, so there is no left-child parent pointer
            // to fixup, but we may need to fix the left-most bookkeeping.
            if (internal::is_sentinel_ptr(old_ns.left_)) {
                ZX_DEBUG_ASSERT(left_most_ == old_node);
                left_most_ = new_raw;
            }
        }
        new_ns.left_ = old_ns.left_;
        old_ns.left_ = nullptr;

        // Same routine, but this time with the right child state.
        if (internal::valid_sentinel_ptr(old_ns.right_)) {
            // Fix the right-child's parent pointer.
            NodeTraits::node_state(*old_ns.right_).parent_ = new_raw;
        } else {
            // We have no right child, so there is no right-child parent pointer
            // to fixup, but we may need to fix the right-most bookkeeping.
            if (internal::is_sentinel_ptr(old_ns.right_)) {
                ZX_DEBUG_ASSERT(right_most_ == old_node);
                right_most_ = new_raw;
            }
        }
        new_ns.right_ = old_ns.right_;
        old_ns.right_ = nullptr;

        // Don't forget transfer the rank bookkeeping from the old node to the
        // new node.
        new_ns.rank_ = old_ns.rank_;

        // Finally, update the pointer which pointed to the old node to point to
        // the new node, taking ownership of the managed reference (if any) in
        // the process.  The update the parent pointers, and finally reclaim the
        // reference from the node we just swapped out and give it back to the
        // caller.
        GetLinkPtrToNode(old_node) = PtrTraits::Leak(new_node);
        new_ns.parent_ = old_ns.parent_;
        old_ns.parent_ = nullptr;
        return PtrTraits::Reclaim(old_node);
    }

    template <typename BoundTraits>
    const_iterator internal_upper_lower_bound(const KeyType& key) const {
        RawPtrType node  = root_;
        RawPtrType found = sentinel();

        while (internal::valid_sentinel_ptr(node)) {
            auto node_key = KeyTraits::GetKey(*node);

            if (BoundTraits::GoRight(key, node_key)) {
                // If we need to look for a larger node value (key > node_key in
                // the case of lower_bound, key >= node_key in the case of
                // upper_bound), then go right.  If we cannot go right, then
                // there is other element in this container whose key satisfies
                // the bound condition.  Break out of the loop and return the
                // best node we have found so far.
                auto& ns = NodeTraits::node_state(*node);

                if (ns.right_ == nullptr)
                    break;

                node = ns.right_;
            } else {
                // If this node's key must be greater than or equal to the
                // user's key.  This node is now our candidate for our found
                // node.
                found = node;

                // If this node has a left-hand child, it is possible that there
                // is a better bound somewhere underneath it.  Set the node
                // pointer to the root of the left hand sub-tree and keep
                // looking.
                node = NodeTraits::node_state(*node).left_;
            }
        }

        return const_iterator(found);
    }

    constexpr RawPtrType sentinel() const {
        return internal::make_sentinel<RawPtrType>(this);
    }

    // Swaps the positions of two nodes, one of which is guaranteed to be a
    // right-hand descendant of the other.
    //
    // @note Node #1 is the ancestor node while node #2 is the descendant node.
    //
    // @param  ptr_ref1 A reference to the pointer which points to node #1.
    // @param  ptr_ref2 A reference to the pointer which points to node #2.
    // @return The new pointer to the pointer which points to node #1.
    //
    RawPtrType* SwapWithRightDescendant(RawPtrType& ptr_ref1, RawPtrType& ptr_ref2) {
        RawPtrType node1 = ptr_ref1;
        RawPtrType node2 = ptr_ref2;

        auto& ns1 = NodeTraits::node_state(*node1);
        auto& ns2 = NodeTraits::node_state(*node2);

        auto ns1_lp = internal::valid_sentinel_ptr(ns1.left_)
                    ? &NodeTraits::node_state(*ns1.left_).parent_
                    : nullptr;
        auto ns2_lp = internal::valid_sentinel_ptr(ns2.left_)
                    ? &NodeTraits::node_state(*ns2.left_).parent_
                    : nullptr;
        auto ns2_rp = internal::valid_sentinel_ptr(ns2.right_)
                    ? &NodeTraits::node_state(*ns2.right_).parent_
                    : nullptr;

        // node 2 is a right-hand descendant of node 1, so node 1's right hand
        // pointer must be valid.
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(ns1.right_));
        auto ns1_rp = &NodeTraits::node_state(*ns1.right_).parent_;

        // Start by updating the LR-most bookkeeping.  Node 1 cannot be the
        // right-most node, and node 2 cannot be the left most node (because we
        // know that node 2 is to the right of node 1).
        //
        // If node 1 is currently the left-most, then node 2 will be when we are
        // done.  Likewise, if node 2 is currently the right-most, then node 1
        // will be the right-most when we are done.
        if (node1 == left_most_)  left_most_  = node2;
        if (node2 == right_most_) right_most_ = node1;

        // Next, swap the core state of node 1 and node 2.
        internal::Swap(ns1.parent_, ns2.parent_);
        internal::Swap(ns1.left_,  ns2.left_);
        internal::Swap(ns1.right_, ns2.right_);
        internal::Swap(ns1.rank_, ns2.rank_);

        // At this point, there are two scenarios.
        //
        // Case #1
        // Node 2 was an indirect descendant of node 1.  In this case, all we
        // need to do is swap the ptr_ref[12] pointers and fix-up the various
        // children's parent pointers (when they exist).
        //
        // Case #2
        // Node 2 was the direct descendant of node 1; in this case the right
        // hand child.  In this case, we know 2 things...
        //
        // 1) node1.right is the same pointer as ptr_ref2
        // 2) node2.parent is the same pointer as node 1's right-child's parent.
        //
        // Because of this (and because of the swapping of core state prior to
        // this), we know...
        //
        // 1) node1.parent currently points to node 1, but should point to node 2.
        // 2) node2.right currently points to node 2, but should point to node 1.
        // 3) ptr_ref1 still points to node 1, but should point to node 2.
        // 4) node2.parent (aka; ns1_rp) currently points to node 1's old
        //    parent (which is correct).
        //
        // We fix issues 1-3 by swapping ptr_ref1 and node2.right, and by
        // directly setting setting node1.parent to node2.
        //
        // Finally, we need to return the new pointer to the pointer which
        // points to node 1.  In case #1, this is just ptr_ref2.  In case #2,
        // however, this has become node 2's right hand pointer.
        //
        // Perform the common child fixup first, then deal with the special
        // cases.
        if (ns1_lp) *ns1_lp = node2;
        if (ns2_lp) *ns2_lp = node1;
        if (ns2_rp) *ns2_rp = node1;

        if (&ptr_ref2 != &ns1.right_) {
            // Case #1.
            internal::Swap(ptr_ref1, ptr_ref2);
            *ns1_rp = node2;
            return &ptr_ref2;
        } else {
            ZX_DEBUG_ASSERT(ns1.parent_ == node1);
            ZX_DEBUG_ASSERT(ns2.right_ == node2);
            internal::Swap(ptr_ref1, ns2.right_);
            ns1.parent_ = node2;
            return &ns2.right_;
        }
    }

    // Promote the LR-child of a node to be removed into the node's position.
    // Update the LR-node bookkeeping in the process.  The LRTraits will
    // determine if we are promoting the left or right child (the forward
    // operation promotes left).
    //
    // Requirements:
    // ++ The node being removed *must* have an LR-child.
    // ++ The node being removed *must not* have an RL-child.
    // ++ The owner reference *must* have already been disconnected from the
    //    node to be removed.
    //
    // @param owner A reference to the pointer which points to the node to be
    // removed.
    // @param node A pointer to the node to be removed.
    //
    template <typename LRTraits>
    void PromoteLRChild(RawPtrType& owner, RawPtrType node) {
        ZX_DEBUG_ASSERT(owner == nullptr);
        ZX_DEBUG_ASSERT(node != nullptr);

        auto& ns = NodeTraits::node_state(*node);
        RawPtrType& lr_child = LRTraits::LRChild(ns);
        RawPtrType& rl_child = LRTraits::RLChild(ns);

        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(lr_child) &&
                        !internal::valid_sentinel_ptr(rl_child));

        // Promote by transferring the LR-Child pointer to the owner pointer and
        // fixing up the LR-Child's parent pointer be the current parent of the
        // node to be removed.
        owner    = lr_child;    // owner now points to the promoted node.
        lr_child = nullptr;     // the node being removed no longer has any lr child.
        NodeTraits::node_state(*owner).parent_ = ns.parent_;

        // The removed node is the RL-most node if (and only if) its RL-child
        // was the sentinel value.
        RawPtrType& rl_most = LRTraits::RLMost(*this);
        ZX_DEBUG_ASSERT((rl_most == node) == internal::is_sentinel_ptr(rl_child));
        if (internal::is_sentinel_ptr(rl_child)) {
            // The target node was the RL-most.  Find the new RL-most node. It will
            // be the RL-most node in the LR-subtree of the target node.  Once
            // found, update the RL-child of the new RL-most node to be the
            // sentinel value.
            RawPtrType  replacement = owner;
            RawPtrType* next_rl_child;

            while (true) {
                auto& replacement_ns = NodeTraits::node_state(*replacement);
                next_rl_child = &LRTraits::RLChild(replacement_ns);

                ZX_DEBUG_ASSERT(!internal::is_sentinel_ptr(*next_rl_child));
                if (*next_rl_child == nullptr)
                    break;

                replacement = *next_rl_child;
            }

            // Update the bookkeeping.
            rl_most        = replacement;
            *next_rl_child = sentinel();
            rl_child       = nullptr;
        }

        // Unlink the parent pointer for the target node and we should be done.
        // The left and right children of the target node should already be
        // nullptr by now.
        ns.parent_ = nullptr;
        ZX_DEBUG_ASSERT(ns.left_  == nullptr);
        ZX_DEBUG_ASSERT(ns.right_ == nullptr);
    }

    // After we have swapped contents with another tree, we need to fix up the
    // sentinel values so that they refer to the proper tree.  Otherwise tree
    // A's sentinels will point at tree B's, and vice-versa.
    void FixSentinelsAfterSwap() {
        if (root_) {
            ZX_DEBUG_ASSERT(!internal::is_sentinel_ptr(root_));
            ZX_DEBUG_ASSERT(left_most_ &&  !internal::is_sentinel_ptr(left_most_));
            ZX_DEBUG_ASSERT(right_most_ && !internal::is_sentinel_ptr(right_most_));

            auto& root_ns       = NodeTraits::node_state(*root_);
            auto& left_most_ns  = NodeTraits::node_state(*left_most_);
            auto& right_most_ns = NodeTraits::node_state(*right_most_);

            ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(left_most_ns.left_));
            ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(right_most_ns.right_));

            root_ns.parent_      = sentinel();
            left_most_ns.left_   = sentinel();
            right_most_ns.right_ = sentinel();
        } else {
            ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(left_most_));
            ZX_DEBUG_ASSERT(internal::is_sentinel_ptr(right_most_));
            left_most_  = sentinel();
            right_most_ = sentinel();
        }
    }

    // GetLinkPtrToNode.
    //
    // Obtain a reference to the pointer which points to node.  The will either be
    // a reference to the node's parent's left child, right child, or the root
    // node of the tree if the child has no parent.
    RawPtrType& GetLinkPtrToNode(RawPtrType node) {
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(node));

        auto& ns = NodeTraits::node_state(*node);
        if (internal::is_sentinel_ptr(ns.parent_)) {
            ZX_DEBUG_ASSERT(ns.parent_ == sentinel());
            ZX_DEBUG_ASSERT(root_ == node);
            return root_;
        }

        ZX_DEBUG_ASSERT(ns.parent_ != nullptr);
        auto& parent_ns = NodeTraits::node_state(*ns.parent_);
        if (parent_ns.left_ == node)
            return parent_ns.left_;

        ZX_DEBUG_ASSERT(parent_ns.right_ == node);
        return parent_ns.right_;
    }

    // RotateLR<LRTraits>
    //
    // Perform a Rotate-LR operation at 'node'.
    //
    // Let...
    // X = node
    // Y = LR-Child of X (if any)
    // Z = X's parent.
    //
    // A Rotate-LR operation at 'node' is defined as follows.
    // 1) Z becomes the LR-Child of X
    // 2) Y becomes the RL-Child of Z
    // 3) X takes Z's position in the tree
    //
    // If [XYZ]_link is the pointer which points to [XYZ], then we can describe
    // the operation as the following permutation of the links.
    //
    //   link  | before | swap1 | swap2 |
    // --------+--------+-------+-------+
    //  X_link |   X    |   Y   |   Y   +
    //  Y_link |   Y    |   X   |   Z   +
    //  Z_link |   Z    |   Z   |   X   +
    //
    // Note that link's are bi-directional.  We need to update the parent
    // pointers as well.  Let G be Z's parent at the start of the operation.
    // The permutation should be.
    //
    //   node  | P(n) before | P(n) after |
    // --------+-------------+------------+
    //    X    |      Z      |     G      |
    //    Y    |      X      |     Z      |
    //    Z    |      G      |     X      |
    //
    // We should not need to worry about the LR-most-ness of any of the nodes.
    // Reasoning is as follows...
    //
    // 1) Z might be the LR-most node in the tree, but only if it has no
    //    LR-Child.  It cannot be the RL-most node in the tree, because we know
    //    that it has an RL-child (X).  When we rotate, Z moves to the LR.  So
    //    if it or one of its LR-children was LR-most, they remain that way.
    // 2) X might be the RL-most node in the tree, but only if it has no
    //    RL-child.  It cannot be the LR-most node in the tree because it is the
    //    RL-child of Z.  When we rotate, X moves up in the tree following Z's
    //    RL-child link.  This means that if X was on the RL-edge of the tree
    //    (implying that it or one of its children was RL-most), it remains
    //    there, preserving the RL-most-ness of it or its children.
    // 3) Before the rotation, Y cannot be either the RL-most node in the tree
    //    (it is X's LR-child), or the LR-most node in the tree (it's parent, X,
    //    is Z's RL-child).  After the rotation, Y still cannot be either
    //    LR-most (it is now Z's RL-child) or RL-most (it's parent, Z, is X's
    //    LR-child).
    template <typename LRTraits>
    void RotateLR(RawPtrType node, RawPtrType parent) {
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(node));     // Node must be valid
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(parent));   // Node must have a parent

        // Aliases, just to make the code below match the notation used above.
        RawPtrType X = node;
        RawPtrType Z = parent;

        auto& X_ns = NodeTraits::node_state(*X);
        auto& Z_ns = NodeTraits::node_state(*Z);

        // X must be the RL-child of Z.
        ZX_DEBUG_ASSERT(LRTraits::RLChild(Z_ns) == X);

        RawPtrType& X_link = LRTraits::RLChild(Z_ns);
        RawPtrType& Y_link = LRTraits::LRChild(X_ns);
        RawPtrType& Z_link = GetLinkPtrToNode(Z);

        RawPtrType G = Z_ns.parent_;
        RawPtrType Y = Y_link;

        // The pointer to Y cannot be a sentinel, because that would imply that
        // X was LR-most.
        ZX_DEBUG_ASSERT(!internal::is_sentinel_ptr(Y));

        // Permute the downstream links.
        RawPtrType tmp = X_link;
        X_link = Y_link;
        Y_link = Z_link;
        Z_link = tmp;

        // Update the parent pointers (note that Y may not exist).
        X_ns.parent_ = G;
        Z_ns.parent_ = X;
        if (Y) {
            NodeTraits::node_state(*Y).parent_ = Z;
        }
    }

    // PostInsertFixupLR<LRTraits>
    //
    // Called after the promotion stage of an insert operation, when node's
    // parent has become 0,2 node and the rank rule needs to be restored.
    //
    // If node is the LR-child of parent, define...
    // X = node
    // Y = RL-child of X
    // Z = parent
    //
    // There are two possibilities of what to do next.
    //
    // if (Y is null) or (Y is a 2-child)
    // then...
    // 1) rotate-RL about X
    // 2) demote Z
    //
    // OR
    //
    // if (Y is a 1-child)
    // then...
    // 1) rotate-LR about Y
    // 2) rotate-RL about Y
    // 3) promote Y
    // 4) demote X
    // 5) demote Z
    template <typename LRTraits>
    void PostInsertFixupLR(RawPtrType node, RawPtrType parent) {
        using RLTraits = typename LRTraits::Inverse;

        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(node));
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(parent));

        auto& node_ns   = NodeTraits::node_state(*node);
        auto& parent_ns = NodeTraits::node_state(*parent);

        ZX_DEBUG_ASSERT(LRTraits::LRChild(parent_ns) == node);

        RawPtrType rl_child = LRTraits::RLChild(node_ns);
        auto rl_child_ns    = internal::valid_sentinel_ptr(rl_child)
                            ? &NodeTraits::node_state(*rl_child)
                            : nullptr;
        if (!rl_child_ns || (rl_child_ns->rank_parity() == node_ns.rank_parity())) {
            // Case #1; single rotation
            //
            // Start by performing a Rotate-RL at node
            RotateLR<RLTraits>(node, parent);
            Observer::RecordInsertRotation();

            // Now demote node's old parent (now its LR-child)
            parent_ns.demote_rank();
        } else {
            // Case #2; double rotation.
            //
            // Start by performing a Rotate-LR at rl_child.  Afterwards,
            // rl_child will be LR-child of parent (and node is now its
            // LR-child).  Rotate-RL at rl_child.
            RotateLR<LRTraits>(rl_child, node);
            RotateLR<RLTraits>(rl_child, parent);
            Observer::RecordInsertDoubleRotation();

            // 1 promotion and 2 demotions.
            rl_child_ns->promote_rank();
            node_ns.demote_rank();
            parent_ns.demote_rank();
        }
    }

    // BalancePostInsert
    //
    // Execute the bottom-up post-insert rebalancing algorithm.
    //
    // @param node A pointer to the node which was just inserted.
    //
    void BalancePostInsert(RawPtrType node) {
        // We do not balance the tree after inserting the first (root)
        // node, so we should be able to assert that we have a valid parent.
        auto node_ns = &NodeTraits::node_state(*node);
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(node_ns->parent_));

        // If we have a sibling, then our parent just went from being a 1,2
        // unary node into a 1,1 binary node and no action needs to be taken.
        RawPtrType parent = node_ns->parent_;
        auto parent_ns = &NodeTraits::node_state(*parent);
        if (internal::valid_sentinel_ptr(parent_ns->left_) &&
            internal::valid_sentinel_ptr(parent_ns->right_))
            return;

        // We have no sibling, therefor we just changed our parent from a 1,1
        // leaf node into a 0,1 unary node.  The WAVL rank rule states that all
        // rank differences are 1 or 2; 0 is not allowed.  Rebalance the tree in
        // order to restore the rule.
        //
        // Start with the promotions.  Pseudo code is...
        //
        // while (IsValid(parent) && parent is a 0,1 node)
        //    promote parent
        //    climb up the tree
        bool node_parity;
        bool parent_parity;
        bool sibling_parity;
        bool is_left_child;
        do {
            // Promote
            parent_ns->promote_rank();
            Observer::RecordInsertPromote();

            // Climb
            node    = parent;
            node_ns = &NodeTraits::node_state(*node);
            parent  = node_ns->parent_;

            // If we have run out of room to climb, then we must be done.
            if (!internal::valid_sentinel_ptr(parent))
                return;

            // We have a parent.  Determine the relationship between our rank
            // parity,  our parent's rank parity, and our sibling's rank parity
            // (if any).  Note; null children have a rank of -1, therefor the
            // rank parity of a sibling is always odd (1).  In the process, make
            // a note of whether we are our parent's left or right child.
            parent_ns = &NodeTraits::node_state(*parent);
            is_left_child = (parent_ns->left_ == node);
            if (is_left_child) {
                sibling_parity = internal::valid_sentinel_ptr(parent_ns->right_)
                               ? NodeTraits::node_state(*parent_ns->right_).rank_parity()
                               : true;
            } else {
                ZX_DEBUG_ASSERT(parent_ns->right_ == node);
                sibling_parity = internal::valid_sentinel_ptr(parent_ns->left_)
                               ? NodeTraits::node_state(*parent_ns->left_).rank_parity()
                               : true;
            }

            node_parity   = node_ns->rank_parity();
            parent_parity = parent_ns->rank_parity();

            // We need to keep promoting and climbing if we just turned our new
            // parent into a 0,1 node.  Let N, P and S denote the current node,
            // parent, and sibling parities.  Working out the truth tables, our
            // parent is now a 0,1 node iff (!N * !P * S) + (N * P * !S)
        } while ((!node_parity && !parent_parity &&  sibling_parity) ||
                 ( node_parity &&  parent_parity && !sibling_parity));

        // OK.  At this point, we know that we have a parent, and our parent is
        // not a 0,1 node.  Either our rank rule has been restored and we are
        // done, or our parent is 0,2 and we need to perform either one or two
        // rotations.  Start by checking to see if our parent is 0,2.  Using the
        // notation from above...
        //
        // ++ our parent is a 0,2 node iff (!N * !P * !S) + (N * P * S).
        // ++ which implies that we are finished iff (N != P) + (N != S)
        //
        if ((node_parity != parent_parity) || (node_parity != sibling_parity))
            return;

        // Looks like our parent is a 0,2 node.  Perform the post-insert fixup
        // operations, forward if we are our parent's left child, reverse if we
        // are our parent's right child.
        if (is_left_child) PostInsertFixupLR<ForwardTraits>(node, parent);
        else               PostInsertFixupLR<ReverseTraits>(node, parent);
    }

    // BalancePostErase_Fix22Leaf
    //
    // Called after an erase operation which erased the 1-child of a node.
    // Checks to see if the node has become a 2,2 leaf node and takes
    // appropriate action to restore the rank rule if needed.
    void BalancePostErase_Fix22Leaf(RawPtrType node) {
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(node));

        // If we just turned node into a 2,2 leaf, it will have no children and
        // odd rank-parity.  If it has even parity, or any children at all,
        // there is nothing we need to do.
        auto& ns = NodeTraits::node_state(*node);
        if (!ns.rank_parity() ||
            internal::valid_sentinel_ptr(ns.left_) ||
            internal::valid_sentinel_ptr(ns.right_))
            return;

        // Demote the node turning it into a 1,1 leaf.
        ns.demote_rank();
        Observer::RecordEraseDemote();

        // By demoting this node, we may have just created a 3-child.  Find its
        // parent, figure out if it was the left or right child, then use the
        // FixLR3Child method to check for the 3-child case and deal with it if
        // we need to.  If this node had no parent, then we know that we are
        // finished.
        ZX_DEBUG_ASSERT(ns.parent_ != nullptr);
        if (internal::is_sentinel_ptr(ns.parent_))
            return;

        auto& parent_ns     = NodeTraits::node_state(*ns.parent_);
        bool  is_left_child = parent_ns.left_ == node;
        ZX_DEBUG_ASSERT(is_left_child || (parent_ns.right_ == node));

        if (is_left_child) BalancePostErase_FixLR3Child<ForwardTraits>(ns.parent_);
        else               BalancePostErase_FixLR3Child<ReverseTraits>(ns.parent_);
    }

    // BalancePostErase_FixLR3Child<LRTraits>
    //
    // Called during post-erase rebalancing when it is possible that a 3-child
    // may have been created.  There are 3 ways that this may have happened.
    //
    // 1) A node's 2-child leaf node was erased making the link to null a
    //    3-child link.
    // 2) A node's 2-child unary node was erased making the promoted node
    //    a 3-child.
    // 3) During rebalancing fix-up of a 2,2 leaf, the 2,2 leaf node is a
    //    2-child.  Demoting it to turn it into a 1,1 leaf makes it a 3-child.
    //
    // Note: this method is templated using LRTraits because the method needs to
    // know which link may have become a 3-child based on prior circumstances.
    // Without this knowledge, it is not possible to detect a 3 child using only
    // rank parity.  For this method, the LR-Child of 'node' is known to now be
    // either a 2-child or a 3-child, it cannot be a 1-child.
    template <typename LRTraits>
    void BalancePostErase_FixLR3Child(RawPtrType node) {
        using RLTraits = typename LRTraits::Inverse;
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(node));

        // Throughout this method, we will use the following notation.
        //
        // Let...
        // Z = The node with the (potential) 3-child.
        // X = The (potential) 3-child.
        // Y = X's sibling. (if any)
        //
        RawPtrType Z    = node;
        auto       Z_ns = &NodeTraits::node_state(*Z);
        RawPtrType X    = LRTraits::LRChild(*Z_ns);

        // Check to see if X is a 3-child of Z.  We know it is if...
        // 1) X exists and Z has odd rank parity
        // 2) X does not exist and Z has even rank parity
        if (internal::valid_sentinel_ptr(X) != Z_ns->rank_parity())
            return;

        // Phase 1, demotions.
        //
        // While X is a 3-child and Y is a 2-child, or a 2,2 node
        //    Demote Y if it is is a 2,2 node
        //    Demote Z
        //    Climb (set Z = Z-parent, update definitions of X and Y)
        //
        bool X_is_LR_child = true;
        RawPtrType Y = LRTraits::RLChild(*Z_ns);
        while (true) {
            // We know that X is a 3 child, Determine the status of Y.  We know
            // that whenever X is a 3-child that Y must exist because...
            //
            // 1) Z's rank is at least 2. In the case that X does not exist, X's rank
            //    is -1 so Z's rank is (-1 + 3) = 2.  If X does exist, Z's rank
            //    is even larger.
            // 2) The rank rule for the Y,Z relationship should currently hold,
            //    meaning that the rank difference between Y and Z is either 1 or 2,
            //    therefor Y's rank is at least 0.
            // 3) Because Y has non-negative rank, it must exist.
            ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(Y));

            auto& Y_ns = NodeTraits::node_state(*Y);
            bool  Y_is_2_child = (Y_ns.rank_parity() == Z_ns->rank_parity());

            // Our next steps are already determined and don't involve Y if
            // Y is currently a 2 child.  Don't bother to compute
            // Y_is_22_node if we already know that Y is a 2-child.
            if (!Y_is_2_child) {
                bool Y_is_22_node;
                if (Y_ns.rank_parity()) {
                    // If Y has odd rank parity, it is a 2,2 node if both its
                    // children have odd parity, meaning each child either does
                    // not exist, or exists and has odd parity..
                    Y_is_22_node = ((!internal::valid_sentinel_ptr(Y_ns.left_) ||
                                     NodeTraits::node_state(*Y_ns.left_).rank_parity()) &&
                                    (!internal::valid_sentinel_ptr(Y_ns.right_) ||
                                     NodeTraits::node_state(*Y_ns.right_).rank_parity()));
                } else {
                    // If Y has even rank parity, it can only be a 2,2 node if it is
                    // a binary node and both of its children have even parity.
                    Y_is_22_node = internal::valid_sentinel_ptr(Y_ns.left_) &&
                                   internal::valid_sentinel_ptr(Y_ns.right_) &&
                                   !NodeTraits::node_state(*Y_ns.left_).rank_parity() &&
                                   !NodeTraits::node_state(*Y_ns.right_).rank_parity();
                }

                // If Y is neither a 2-child or a 2,2 node, then we are done
                // with phase 1.  X is still a 3-child, but it will take one or
                // more rotations to fix the problem.
                if (!Y_is_22_node)
                    break;
            }

            // Demote Z.  If Y was a 1-child, demote Y as well.
            Z_ns->demote_rank();
            Observer::RecordEraseDemote();

            if (!Y_is_2_child) {
                Y_ns.demote_rank();
                Observer::RecordEraseDemote();
            }

            // Climb.  If we cannot climb because we have no parent, or we can
            // climb and the new X is no longer a 3-child, then we are done
            // with the rebalance operation.
            if (!internal::valid_sentinel_ptr(Z_ns->parent_))
                return;

            bool X_rank_parity = Z_ns->rank_parity();
            X    = Z;
            Z    = Z_ns->parent_;
            Z_ns = &NodeTraits::node_state(*Z);
            if (Z_ns->rank_parity() == X_rank_parity)
                return;

            X_is_LR_child = (LRTraits::LRChild(*Z_ns) == X);
            Y = X_is_LR_child
              ? LRTraits::RLChild(*Z_ns)
              : LRTraits::LRChild(*Z_ns);
        }

        // Phase 2, rotations
        //
        // At this point, we know...
        //
        // 1) Z exists
        // 2) X is a 3-child of Z (but may not exist).
        // 3) Y exists (because X is a 3-child of Z, see above)
        // 4) Y is not a 2-child of Z (so, Z is a 1,3 node)
        // 5) Y is not a 2,2 node.
        //
        // We will need to perform either 1 or 2 rotations to fix this problem.
        // Which directions we rotate will now depend on whether or not X is a
        // left or right child of Z.  Invoke the post-erase rotation method
        // using the traits which will normalize the notation so that X is an
        // LR-child of Z.
        if (X_is_LR_child) BalancePostErase_DoRotations<LRTraits>(Y, Z);
        else               BalancePostErase_DoRotations<RLTraits>(Y, Z);
    }

    // BalancePostErase_DoRotations<LRTraits>
    //
    // Refer to the notes at the end of BalancePostErase_FixLR3Child<LRTraits>
    // for a description of the current situation.  In addition to the
    // assertions there, we also now know that X is the LR-Child of Z (and
    // therefor Y is the RL-child of Z) (note; X is only indirectly involved
    // here, so not passed as an argument).
    template <typename LRTraits>
    void BalancePostErase_DoRotations(RawPtrType Y, RawPtrType Z) {
        using RLTraits = typename LRTraits::Inverse;
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(Y));
        ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(Z));

        auto& Y_ns = NodeTraits::node_state(*Y);
        auto& Z_ns = NodeTraits::node_state(*Z);

        // Let...
        // V = the LR-child of Y
        // W = the RL-child of Y
        //
        // Perform rotations to fix the fact that X is a 3-child of Z.  We will
        // need to do 1 of 2 things depending on whether W is a 1-child or
        // 2-child of Y.
        //
        RawPtrType W = LRTraits::RLChild(Y_ns);
        bool W_rank_parity = internal::valid_sentinel_ptr(W)
                           ? NodeTraits::node_state(*W).rank_parity()
                           : true;
        if (Y_ns.rank_parity() != W_rank_parity) {
            // Case #1: W is a 1-child of Y
            //
            // 1)  Rotate-LR at Y
            // 2)  Promote Y
            // 3a) If Z is a leaf, demote it twice.
            // 3b) else demote Z once.
            RotateLR<LRTraits>(Y, Z);
            Observer::RecordEraseRotation();

            Y_ns.promote_rank();

            if (!internal::valid_sentinel_ptr(Z_ns.left_) &&
                !internal::valid_sentinel_ptr(Z_ns.right_)) {
                Z_ns.double_demote_rank();
            } else {
                Z_ns.demote_rank();
            }
        } else {
            // Case #2: W is a 2-child of Y
            //
            // 1) Rotate-RL at V
            // 2) Rotate-LR at V
            // 3) Promote V twice.
            // 3) Demote Y once.
            // 3) Demote Z twice.
            RawPtrType V = LRTraits::LRChild(Y_ns);
            ZX_DEBUG_ASSERT(internal::valid_sentinel_ptr(V));                     // V must exist
            auto& V_ns = NodeTraits::node_state(*V);
            ZX_DEBUG_ASSERT(V_ns.rank_parity() != Y_ns.rank_parity());  // V must be a 1-child of Y

            // TODO(johngro) : Special case the implementation of a double
            // rotation operation.  It would almost certainly be more efficient
            // than performing 2 sequential single rotation operations.
            RotateLR<RLTraits>(V, Y);
            RotateLR<LRTraits>(V, Z);
            Observer::RecordEraseDoubleRotation();

            V_ns.double_promote_rank();
            Y_ns.demote_rank();
            Z_ns.double_demote_rank();
        }
    }

    // Tree state consists of...
    //
    // 1) a root node
    // 2) a left-most node
    // 3) a right-most node
    // 4) a count of nodes
    //
    // Technically, only #1 is required.  #2-4 are optimizations to assist in
    // iteration and size operations.
    RawPtrType root_       = nullptr;
    RawPtrType left_most_  = sentinel();
    RawPtrType right_most_ = sentinel();
    size_t     count_      = 0;
};

// TaggedWAVLTree<> is intended for use with ContainableBaseClasses<>.
//
// For an easy way to allow instances of your class to live in multiple
// intrusive containers at once, simply derive from
// ContainableBaseClasses<YourContainables<PtrType, TagType>...> and then use
// this template instead of WAVLTree<> as the container, passing the same tag
// type you used earlier as the third parameter.
//
// See comments on ContainableBaseClasses<> in fbl/intrusive_container_utils.h
// for more details.
//
template <typename KeyType,
          typename PtrType,
          typename TagType,
          typename KeyTraits = DefaultKeyedObjectTraits<
                                  KeyType,
                                  typename internal::ContainerPtrTraits<PtrType>::ValueType>,
          typename NodeTraits = DefaultWAVLTreeTraits<PtrType>,
          typename Observer = tests::intrusive_containers::DefaultWAVLTreeObserver>
using TaggedWAVLTree = WAVLTree<KeyType, PtrType, KeyTraits, NodeTraits, TagType, Observer>;

template <typename KeyType, typename PtrType, typename KeyTraits,
          typename NodeTraits, typename TagType, typename Obs>
constexpr bool WAVLTree<KeyType, PtrType, KeyTraits,
                        NodeTraits, TagType, Obs>::SupportsConstantOrderErase;
template <typename KeyType, typename PtrType, typename KeyTraits,
          typename NodeTraits, typename TagType, typename Obs>
constexpr bool WAVLTree<KeyType, PtrType, KeyTraits,
                        NodeTraits, TagType, Obs>::SupportsConstantOrderSize;
template <typename KeyType, typename PtrType, typename KeyTraits,
          typename NodeTraits, typename TagType, typename Obs>
constexpr bool WAVLTree<KeyType, PtrType, KeyTraits,
                        NodeTraits, TagType, Obs>::IsAssociative;
template <typename KeyType, typename PtrType, typename KeyTraits,
          typename NodeTraits, typename TagType, typename Obs>
constexpr bool WAVLTree<KeyType, PtrType, KeyTraits,
                        NodeTraits, TagType, Obs>::IsSequenced;

}  // namespace fbl

#endif  // FBL_INTRUSIVE_WAVL_TREE_H_
