// 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 <cstring>
#include <vector>

#include "base/check_op.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
