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

#include "cc/base/list_container_helper.h"

#include <stddef.h>

#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "base/memory/aligned_memory.h"

namespace {
const size_t kDefaultNumElementTypesToReserve = 32;
}  // namespace

namespace cc {

// CharAllocator
////////////////////////////////////////////////////
// This class deals only with char* and void*. It does allocation and passing
// out raw pointers, as well as memory deallocation when being destroyed.
class ListContainerHelper::CharAllocator {
 public:
  // CharAllocator::InnerList
  /////////////////////////////////////////////
  // This class holds the raw memory chunk, as well as information about its
  // size and availability.
  struct InnerList {
    InnerList(const InnerList&) = delete;
    InnerList& operator=(const InnerList&) = delete;

    std::unique_ptr<char[], base::AlignedFreeDeleter> data;
    // The number of elements in total the memory can hold. The difference
    // between capacity and size is the how many more elements this list can
    // hold.
    size_t capacity;
    // The number of elements have been put into this list.
    size_t size;
    // The size of each element is in bytes. This is used to move from between
    // elements' memory locations.
    size_t step;

    InnerList() : capacity(0), size(0), step(0) {}

    void Erase(char* position) {
      // Confident that destructor is called by caller of this function. Since
      // CharAllocator does not handle construction after
      // allocation, it doesn't handle desctrution before deallocation.
      DCHECK_LE(position, LastElement());
      DCHECK_GE(position, Begin());
      char* start = position + step;
      std::copy(start, End(), position);

      --size;
      // Decrease capacity to avoid creating not full not last InnerList.
      --capacity;
    }

    void InsertBefore(size_t alignment, char** position, size_t count) {
      DCHECK_LE(*position, LastElement() + step);
      DCHECK_GE(*position, Begin());

      // Adjust the size and capacity
      size_t old_size = size;
      size += count;
      capacity = size;

      // Allocate the new data and update the iterator's pointer.
      std::unique_ptr<char[], base::AlignedFreeDeleter> new_data(
          static_cast<char*>(base::AlignedAlloc(size * step, alignment)));
      size_t position_offset = *position - Begin();
      *position = new_data.get() + position_offset;

      // Copy the data before the inserted segment
      memcpy(new_data.get(), data.get(), position_offset);
      // Copy the data after the inserted segment.
      memcpy(new_data.get() + position_offset + count * step,
             data.get() + position_offset, old_size * step - position_offset);
      data = std::move(new_data);
    }

    bool IsEmpty() const { return !size; }
    bool IsFull() { return capacity == size; }
    size_t NumElementsAvailable() const { return capacity - size; }

    void* AddElement() {
      DCHECK_LT(size, capacity);
      ++size;
      return LastElement();
    }

    void RemoveLast() {
      DCHECK(!IsEmpty());
      --size;
    }

    char* Begin() const { return data.get(); }
    char* End() const { return data.get() + size * step; }
    char* LastElement() const { return data.get() + (size - 1) * step; }
    char* ElementAt(size_t index) const { return data.get() + index * step; }
  };

  CharAllocator(size_t alignment, size_t element_size, size_t element_count)
      // base::AlignedAlloc does not accept alignment less than sizeof(void*).
      : alignment_(std::max(sizeof(void*), alignment)),
        element_size_(element_size),
        size_(0),
        last_list_index_(0),
        last_list_(nullptr) {
    // If this fails, then alignment of elements after the first could be wrong,
    // and we need to pad sizes to fix that.
    DCHECK_EQ(element_size % alignment, 0u);
    AllocateNewList(element_count > 0 ? element_count
                                      : kDefaultNumElementTypesToReserve);
    last_list_ = storage_[last_list_index_].get();
  }

  CharAllocator(const CharAllocator&) = delete;
  ~CharAllocator() = default;

  CharAllocator& operator=(const CharAllocator&) = delete;

  void* Allocate() {
    if (last_list_->IsFull()) {
      // Only allocate a new list if there isn't a spare one still there from
      // previous usage.
      if (last_list_index_ + 1 >= storage_.size())
        AllocateNewList(last_list_->capacity * 2);

      ++last_list_index_;
      last_list_ = storage_[last_list_index_].get();
    }

    ++size_;
    return last_list_->AddElement();
  }

  size_t alignment() const { return alignment_; }
  size_t element_size() const { return element_size_; }
  size_t list_count() const { return storage_.size(); }
  size_t size() const { return size_; }
  bool IsEmpty() const { return size() == 0; }

  size_t Capacity() const {
    size_t capacity_sum = 0;
    for (const auto& inner_list : storage_)
      capacity_sum += inner_list->capacity;
    return capacity_sum;
  }

  void Clear() {
    // Remove all except for the first InnerList.
    DCHECK(!storage_.empty());
    storage_.erase(storage_.begin() + 1, storage_.end());
    last_list_index_ = 0;
    last_list_ = storage_[0].get();
    last_list_->size = 0;
    size_ = 0;
  }

  void RemoveLast() {
    DCHECK(!IsEmpty());
    last_list_->RemoveLast();
    if (last_list_->IsEmpty() && last_list_index_ > 0) {
      --last_list_index_;
      last_list_ = storage_[last_list_index_].get();

      // If there are now two empty inner lists, free one of them.
      if (last_list_index_ + 2 < storage_.size())
        storage_.pop_back();
    }
    --size_;
  }

  void Erase(PositionInCharAllocator* position) {
    DCHECK_EQ(this, position->ptr_to_container);

    // Update |position| to point to the element after the erased element.
    InnerList* list = storage_[position->vector_index].get();
    char* item_iterator = position->item_iterator;
    if (item_iterator == list->LastElement())
      position->Increment();

    list->Erase(item_iterator);
    // TODO(weiliangc): Free the InnerList if it is empty.
    --size_;
  }

  void InsertBefore(ListContainerHelper::Iterator* position, size_t count) {
    if (!count)
      return;

    // If |position| is End(), then append |count| elements at the end. This
    // will happen to not invalidate any iterators or memory.
    if (!position->item_iterator) {
      // Set |position| to be the first inserted element.
      Allocate();
      position->vector_index = storage_.size() - 1;
      position->item_iterator = storage_[position->vector_index]->LastElement();
      // Allocate the rest.
      for (size_t i = 1; i < count; ++i)
        Allocate();
    } else {
      storage_[position->vector_index]->InsertBefore(
          alignment_, &position->item_iterator, count);
      size_ += count;
    }
  }

  InnerList* InnerListById(size_t id) const {
    DCHECK_LT(id, storage_.size());
    return storage_[id].get();
  }

  size_t FirstInnerListId() const {
    // |size_| > 0 means that at least one vector in |storage_| will be
    // non-empty.
    DCHECK_GT(size_, 0u);
    size_t id = 0;
    while (storage_[id]->size == 0)
      ++id;
    return id;
  }

  size_t LastInnerListId() const {
    // |size_| > 0 means that at least one vector in |storage_| will be
    // non-empty.
    DCHECK_GT(size_, 0u);
    size_t id = storage_.size() - 1;
    while (storage_[id]->size == 0)
      --id;
    return id;
  }

  size_t NumAvailableElementsInLastList() const {
    return last_list_->NumElementsAvailable();
  }

 private:
  void AllocateNewList(size_t list_size) {
    std::unique_ptr<InnerList> new_list(new InnerList);
    new_list->capacity = list_size;
    new_list->size = 0;
    new_list->step = element_size_;
    new_list->data.reset(static_cast<char*>(
        base::AlignedAlloc(list_size * element_size_, alignment_)));
    storage_.push_back(std::move(new_list));
  }

  std::vector<std::unique_ptr<InnerList>> storage_;
  const size_t alignment_;
  const size_t element_size_;

  // The number of elements in the list.
  size_t size_;

  // The index of the last list to have had elements added to it, or the only
  // list if the container has not had elements added since being cleared.
  size_t last_list_index_;

  // This is equivalent to |storage_[last_list_index_]|.
  InnerList* last_list_;
};

// PositionInCharAllocator
//////////////////////////////////////////////////////
ListContainerHelper::PositionInCharAllocator::PositionInCharAllocator(
    const ListContainerHelper::PositionInCharAllocator& other) = default;

ListContainerHelper::PositionInCharAllocator::PositionInCharAllocator(
    ListContainerHelper::CharAllocator* container,
    size_t vector_ind,
    char* item_iter)
    : ptr_to_container(container),
      vector_index(vector_ind),
      item_iterator(item_iter) {}

bool ListContainerHelper::PositionInCharAllocator::operator==(
    const ListContainerHelper::PositionInCharAllocator& other) const {
  DCHECK_EQ(ptr_to_container, other.ptr_to_container);
  return vector_index == other.vector_index &&
         item_iterator == other.item_iterator;
}

bool ListContainerHelper::PositionInCharAllocator::operator!=(
    const ListContainerHelper::PositionInCharAllocator& other) const {
  return !(*this == other);
}

ListContainerHelper::PositionInCharAllocator
ListContainerHelper::PositionInCharAllocator::Increment() {
  CharAllocator::InnerList* list =
      ptr_to_container->InnerListById(vector_index);
  if (item_iterator == list->LastElement()) {
    ++vector_index;
    while (vector_index < ptr_to_container->list_count()) {
      if (ptr_to_container->InnerListById(vector_index)->size != 0)
        break;
      ++vector_index;
    }
    if (vector_index < ptr_to_container->list_count())
      item_iterator = ptr_to_container->InnerListById(vector_index)->Begin();
    else
      item_iterator = nullptr;
  } else {
    item_iterator += list->step;
  }
  return *this;
}

ListContainerHelper::PositionInCharAllocator
ListContainerHelper::PositionInCharAllocator::ReverseIncrement() {
  CharAllocator::InnerList* list =
      ptr_to_container->InnerListById(vector_index);
  if (item_iterator == list->Begin()) {
    --vector_index;
    // Since |vector_index| is unsigned, we compare < list_count() instead of
    // comparing >= 0, as the variable will wrap around when it goes out of
    // range (below 0).
    while (vector_index < ptr_to_container->list_count()) {
      if (ptr_to_container->InnerListById(vector_index)->size != 0)
        break;
      --vector_index;
    }
    if (vector_index < ptr_to_container->list_count()) {
      item_iterator =
          ptr_to_container->InnerListById(vector_index)->LastElement();
    } else {
      item_iterator = nullptr;
    }
  } else {
    item_iterator -= list->step;
  }
  return *this;
}

// ListContainerHelper
////////////////////////////////////////////
ListContainerHelper::ListContainerHelper(size_t alignment,
                                         size_t max_size_for_derived_class,
                                         size_t num_of_elements_to_reserve_for)
    : data_(new CharAllocator(alignment,
                              max_size_for_derived_class,
                              num_of_elements_to_reserve_for)) {}

ListContainerHelper::~ListContainerHelper() = default;

void ListContainerHelper::RemoveLast() {
  data_->RemoveLast();
}

void ListContainerHelper::EraseAndInvalidateAllPointers(
    ListContainerHelper::Iterator* position) {
  data_->Erase(position);
}

void ListContainerHelper::InsertBeforeAndInvalidateAllPointers(
    ListContainerHelper::Iterator* position,
    size_t count) {
  data_->InsertBefore(position, count);
}

ListContainerHelper::ConstReverseIterator ListContainerHelper::crbegin() const {
  if (data_->IsEmpty())
    return crend();

  size_t id = data_->LastInnerListId();
  return ConstReverseIterator(data_.get(), id,
                              data_->InnerListById(id)->LastElement(), 0);
}

ListContainerHelper::ConstReverseIterator ListContainerHelper::crend() const {
  return ConstReverseIterator(data_.get(), static_cast<size_t>(-1), nullptr,
                              size());
}

ListContainerHelper::ReverseIterator ListContainerHelper::rbegin() {
  if (data_->IsEmpty())
    return rend();

  size_t id = data_->LastInnerListId();
  return ReverseIterator(data_.get(), id,
                         data_->InnerListById(id)->LastElement(), 0);
}

ListContainerHelper::ReverseIterator ListContainerHelper::rend() {
  return ReverseIterator(data_.get(), static_cast<size_t>(-1), nullptr, size());
}

ListContainerHelper::ConstIterator ListContainerHelper::cbegin() const {
  if (data_->IsEmpty())
    return cend();

  size_t id = data_->FirstInnerListId();
  return ConstIterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0);
}

ListContainerHelper::ConstIterator ListContainerHelper::cend() const {
  if (data_->IsEmpty())
    return ConstIterator(data_.get(), 0, nullptr, size());

  size_t id = data_->list_count();
  return ConstIterator(data_.get(), id, nullptr, size());
}

ListContainerHelper::Iterator ListContainerHelper::begin() {
  if (data_->IsEmpty())
    return end();

  size_t id = data_->FirstInnerListId();
  return Iterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0);
}

ListContainerHelper::Iterator ListContainerHelper::end() {
  if (data_->IsEmpty())
    return Iterator(data_.get(), 0, nullptr, size());

  size_t id = data_->list_count();
  return Iterator(data_.get(), id, nullptr, size());
}

ListContainerHelper::ConstIterator ListContainerHelper::IteratorAt(
    size_t index) const {
  DCHECK_LT(index, size());
  size_t original_index = index;
  size_t list_index;
  for (list_index = 0; list_index < data_->list_count(); ++list_index) {
    size_t current_size = data_->InnerListById(list_index)->size;
    if (index < current_size)
      break;
    index -= current_size;
  }
  return ConstIterator(data_.get(), list_index,
                       data_->InnerListById(list_index)->ElementAt(index),
                       original_index);
}

ListContainerHelper::Iterator ListContainerHelper::IteratorAt(size_t index) {
  DCHECK_LT(index, size());
  size_t original_index = index;
  size_t list_index;
  for (list_index = 0; list_index < data_->list_count(); ++list_index) {
    size_t current_size = data_->InnerListById(list_index)->size;
    if (index < current_size)
      break;
    index -= current_size;
  }
  return Iterator(data_.get(), list_index,
                  data_->InnerListById(list_index)->ElementAt(index),
                  original_index);
}

void* ListContainerHelper::Allocate(size_t alignment,
                                    size_t size_of_actual_element_in_bytes) {
  DCHECK_LE(alignment, data_->alignment());
  DCHECK_LE(size_of_actual_element_in_bytes, data_->element_size());
  return data_->Allocate();
}

size_t ListContainerHelper::size() const {
  return data_->size();
}

bool ListContainerHelper::empty() const {
  return data_->IsEmpty();
}

size_t ListContainerHelper::MaxSizeForDerivedClass() const {
  return data_->element_size();
}

size_t ListContainerHelper::GetCapacityInBytes() const {
  return data_->Capacity() * data_->element_size();
}

void ListContainerHelper::clear() {
  data_->Clear();
}

size_t ListContainerHelper::AvailableSizeWithoutAnotherAllocationForTesting()
    const {
  return data_->NumAvailableElementsInLastList();
}

// ListContainerHelper::Iterator
/////////////////////////////////////////////////
ListContainerHelper::Iterator::Iterator(CharAllocator* container,
                                        size_t vector_ind,
                                        char* item_iter,
                                        size_t index)
    : PositionInCharAllocator(container, vector_ind, item_iter),
      index_(index) {}

ListContainerHelper::Iterator::~Iterator() = default;

size_t ListContainerHelper::Iterator::index() const {
  return index_;
}

// ListContainerHelper::ConstIterator
/////////////////////////////////////////////////
ListContainerHelper::ConstIterator::ConstIterator(
    const ListContainerHelper::Iterator& other)
    : PositionInCharAllocator(other), index_(other.index()) {}

ListContainerHelper::ConstIterator::ConstIterator(CharAllocator* container,
                                                  size_t vector_ind,
                                                  char* item_iter,
                                                  size_t index)
    : PositionInCharAllocator(container, vector_ind, item_iter),
      index_(index) {}

ListContainerHelper::ConstIterator::~ConstIterator() = default;

size_t ListContainerHelper::ConstIterator::index() const {
  return index_;
}

// ListContainerHelper::ReverseIterator
/////////////////////////////////////////////////
ListContainerHelper::ReverseIterator::ReverseIterator(CharAllocator* container,
                                                      size_t vector_ind,
                                                      char* item_iter,
                                                      size_t index)
    : PositionInCharAllocator(container, vector_ind, item_iter),
      index_(index) {}

ListContainerHelper::ReverseIterator::~ReverseIterator() = default;

size_t ListContainerHelper::ReverseIterator::index() const {
  return index_;
}

// ListContainerHelper::ConstReverseIterator
/////////////////////////////////////////////////
ListContainerHelper::ConstReverseIterator::ConstReverseIterator(
    const ListContainerHelper::ReverseIterator& other)
    : PositionInCharAllocator(other), index_(other.index()) {}

ListContainerHelper::ConstReverseIterator::ConstReverseIterator(
    CharAllocator* container,
    size_t vector_ind,
    char* item_iter,
    size_t index)
    : PositionInCharAllocator(container, vector_ind, item_iter),
      index_(index) {}

ListContainerHelper::ConstReverseIterator::~ConstReverseIterator() = default;

size_t ListContainerHelper::ConstReverseIterator::index() const {
  return index_;
}

}  // namespace cc
