// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// 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
// OWNER 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 V8_SPLAY_TREE_INL_H_
#define V8_SPLAY_TREE_INL_H_

#include "splay-tree.h"

namespace v8 {
namespace internal {


template<typename Config, class Allocator>
SplayTree<Config, Allocator>::~SplayTree() {
  NodeDeleter deleter;
  ForEachNode(&deleter);
}


template<typename Config, class Allocator>
bool SplayTree<Config, Allocator>::Insert(const Key& key, Locator* locator) {
  if (is_empty()) {
    // If the tree is empty, insert the new node.
    root_ = new Node(key, Config::NoValue());
  } else {
    // Splay on the key to move the last node on the search path
    // for the key to the root of the tree.
    Splay(key);
    // Ignore repeated insertions with the same key.
    int cmp = Config::Compare(key, root_->key_);
    if (cmp == 0) {
      locator->bind(root_);
      return false;
    }
    // Insert the new node.
    Node* node = new Node(key, Config::NoValue());
    InsertInternal(cmp, node);
  }
  locator->bind(root_);
  return true;
}


template<typename Config, class Allocator>
void SplayTree<Config, Allocator>::InsertInternal(int cmp, Node* node) {
  if (cmp > 0) {
    node->left_ = root_;
    node->right_ = root_->right_;
    root_->right_ = NULL;
  } else {
    node->right_ = root_;
    node->left_ = root_->left_;
    root_->left_ = NULL;
  }
  root_ = node;
}


template<typename Config, class Allocator>
bool SplayTree<Config, Allocator>::FindInternal(const Key& key) {
  if (is_empty())
    return false;
  Splay(key);
  return Config::Compare(key, root_->key_) == 0;
}


template<typename Config, class Allocator>
bool SplayTree<Config, Allocator>::Find(const Key& key, Locator* locator) {
  if (FindInternal(key)) {
    locator->bind(root_);
    return true;
  } else {
    return false;
  }
}


template<typename Config, class Allocator>
bool SplayTree<Config, Allocator>::FindGreatestLessThan(const Key& key,
                                                        Locator* locator) {
  if (is_empty())
    return false;
  // Splay on the key to move the node with the given key or the last
  // node on the search path to the top of the tree.
  Splay(key);
  // Now the result is either the root node or the greatest node in
  // the left subtree.
  int cmp = Config::Compare(root_->key_, key);
  if (cmp <= 0) {
    locator->bind(root_);
    return true;
  } else {
    Node* temp = root_;
    root_ = root_->left_;
    bool result = FindGreatest(locator);
    root_ = temp;
    return result;
  }
}


template<typename Config, class Allocator>
bool SplayTree<Config, Allocator>::FindLeastGreaterThan(const Key& key,
                                                        Locator* locator) {
  if (is_empty())
    return false;
  // Splay on the key to move the node with the given key or the last
  // node on the search path to the top of the tree.
  Splay(key);
  // Now the result is either the root node or the least node in
  // the right subtree.
  int cmp = Config::Compare(root_->key_, key);
  if (cmp >= 0) {
    locator->bind(root_);
    return true;
  } else {
    Node* temp = root_;
    root_ = root_->right_;
    bool result = FindLeast(locator);
    root_ = temp;
    return result;
  }
}


template<typename Config, class Allocator>
bool SplayTree<Config, Allocator>::FindGreatest(Locator* locator) {
  if (is_empty())
    return false;
  Node* current = root_;
  while (current->right_ != NULL)
    current = current->right_;
  locator->bind(current);
  return true;
}


template<typename Config, class Allocator>
bool SplayTree<Config, Allocator>::FindLeast(Locator* locator) {
  if (is_empty())
    return false;
  Node* current = root_;
  while (current->left_ != NULL)
    current = current->left_;
  locator->bind(current);
  return true;
}


template<typename Config, class Allocator>
bool SplayTree<Config, Allocator>::Move(const Key& old_key,
                                        const Key& new_key) {
  if (!FindInternal(old_key))
    return false;
  Node* node_to_move = root_;
  RemoveRootNode(old_key);
  Splay(new_key);
  int cmp = Config::Compare(new_key, root_->key_);
  if (cmp == 0) {
    // A node with the target key already exists.
    delete node_to_move;
    return false;
  }
  node_to_move->key_ = new_key;
  InsertInternal(cmp, node_to_move);
  return true;
}


template<typename Config, class Allocator>
bool SplayTree<Config, Allocator>::Remove(const Key& key) {
  if (!FindInternal(key))
    return false;
  Node* node_to_remove = root_;
  RemoveRootNode(key);
  delete node_to_remove;
  return true;
}


template<typename Config, class Allocator>
void SplayTree<Config, Allocator>::RemoveRootNode(const Key& key) {
  if (root_->left_ == NULL) {
    // No left child, so the new tree is just the right child.
    root_ = root_->right_;
  } else {
    // Left child exists.
    Node* right = root_->right_;
    // Make the original left child the new root.
    root_ = root_->left_;
    // Splay to make sure that the new root has an empty right child.
    Splay(key);
    // Insert the original right child as the right child of the new
    // root.
    root_->right_ = right;
  }
}


template<typename Config, class Allocator>
void SplayTree<Config, Allocator>::Splay(const Key& key) {
  if (is_empty())
    return;
  Node dummy_node(Config::kNoKey, Config::NoValue());
  // Create a dummy node.  The use of the dummy node is a bit
  // counter-intuitive: The right child of the dummy node will hold
  // the L tree of the algorithm.  The left child of the dummy node
  // will hold the R tree of the algorithm.  Using a dummy node, left
  // and right will always be nodes and we avoid special cases.
  Node* dummy = &dummy_node;
  Node* left = dummy;
  Node* right = dummy;
  Node* current = root_;
  while (true) {
    int cmp = Config::Compare(key, current->key_);
    if (cmp < 0) {
      if (current->left_ == NULL)
        break;
      if (Config::Compare(key, current->left_->key_) < 0) {
        // Rotate right.
        Node* temp = current->left_;
        current->left_ = temp->right_;
        temp->right_ = current;
        current = temp;
        if (current->left_ == NULL)
          break;
      }
      // Link right.
      right->left_ = current;
      right = current;
      current = current->left_;
    } else if (cmp > 0) {
      if (current->right_ == NULL)
        break;
      if (Config::Compare(key, current->right_->key_) > 0) {
        // Rotate left.
        Node* temp = current->right_;
        current->right_ = temp->left_;
        temp->left_ = current;
        current = temp;
        if (current->right_ == NULL)
          break;
      }
      // Link left.
      left->right_ = current;
      left = current;
      current = current->right_;
    } else {
      break;
    }
  }
  // Assemble.
  left->right_ = current->left_;
  right->left_ = current->right_;
  current->left_ = dummy->right_;
  current->right_ = dummy->left_;
  root_ = current;
}


template <typename Config, class Allocator> template <class Callback>
void SplayTree<Config, Allocator>::ForEach(Callback* callback) {
  NodeToPairAdaptor<Callback> callback_adaptor(callback);
  ForEachNode(&callback_adaptor);
}


template <typename Config, class Allocator> template <class Callback>
void SplayTree<Config, Allocator>::ForEachNode(Callback* callback) {
  // Pre-allocate some space for tiny trees.
  List<Node*, Allocator> nodes_to_visit(10);
  if (root_ != NULL) nodes_to_visit.Add(root_);
  int pos = 0;
  while (pos < nodes_to_visit.length()) {
    Node* node = nodes_to_visit[pos++];
    if (node->left() != NULL) nodes_to_visit.Add(node->left());
    if (node->right() != NULL) nodes_to_visit.Add(node->right());
    callback->Call(node);
  }
}


} }  // namespace v8::internal

#endif  // V8_SPLAY_TREE_INL_H_
