Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Unified Diff: cc/base/list_container.cc

Issue 1163803003: cc: Implement RemoveLast for DisplayItemList. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: danakj comments Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/base/list_container.h ('k') | cc/base/sidecar_list_container.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/base/list_container.cc
diff --git a/cc/base/list_container.cc b/cc/base/list_container.cc
index df21a5b2e486a144736e9c817c66aa30d5acccda..ef4d08c116faecd8033d11ff4a82a8135f290fef 100644
--- a/cc/base/list_container.cc
+++ b/cc/base/list_container.cc
@@ -53,6 +53,7 @@ class ListContainerBase::ListContainerCharAllocator {
--capacity;
}
+ bool IsEmpty() const { return !size; }
bool IsFull() { return capacity == size; }
size_t NumElementsAvailable() const { return capacity - size; }
@@ -62,6 +63,11 @@ class ListContainerBase::ListContainerCharAllocator {
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; }
@@ -74,32 +80,41 @@ class ListContainerBase::ListContainerCharAllocator {
explicit ListContainerCharAllocator(size_t element_size)
: element_size_(element_size),
size_(0),
- list_count_(0),
+ last_list_index_(0),
last_list_(NULL) {
AllocateNewList(kDefaultNumElementTypesToReserve);
+ last_list_ = storage_[last_list_index_];
}
ListContainerCharAllocator(size_t element_size, size_t element_count)
: element_size_(element_size),
size_(0),
- list_count_(0),
+ last_list_index_(0),
last_list_(NULL) {
AllocateNewList(element_count > 0 ? element_count
: kDefaultNumElementTypesToReserve);
+ last_list_ = storage_[last_list_index_];
}
~ListContainerCharAllocator() {}
void* Allocate() {
- if (last_list_->IsFull())
- AllocateNewList(last_list_->capacity * 2);
+ 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_];
+ }
++size_;
return last_list_->AddElement();
}
size_t element_size() const { return element_size_; }
- size_t list_count() const { return list_count_; }
+ size_t list_count() const { return storage_.size(); }
size_t size() const { return size_; }
bool IsEmpty() const { return size() == 0; }
@@ -115,10 +130,25 @@ class ListContainerBase::ListContainerCharAllocator {
void Clear() {
size_t initial_allocation_size = storage_.front()->capacity;
storage_.clear();
- list_count_ = 0;
last_list_ = NULL;
+ last_list_index_ = 0;
size_ = 0;
AllocateNewList(initial_allocation_size);
+ last_list_ = storage_[last_list_index_];
+ }
+
+ void RemoveLast() {
+ DCHECK(!IsEmpty());
+ last_list_->RemoveLast();
+ if (last_list_->IsEmpty() && last_list_index_ > 0) {
+ --last_list_index_;
+ last_list_ = storage_[last_list_index_];
+
+ // 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(PositionInListContainerCharAllocator position) {
@@ -129,7 +159,7 @@ class ListContainerBase::ListContainerCharAllocator {
}
InnerList* InnerListById(size_t id) const {
- DCHECK_LT(id, list_count_);
+ DCHECK_LT(id, storage_.size());
return storage_[id];
}
@@ -147,33 +177,37 @@ class ListContainerBase::ListContainerCharAllocator {
// |size_| > 0 means that at least one vector in |storage_| will be
// non-empty.
DCHECK_GT(size_, 0u);
- size_t id = list_count_ - 1;
+ size_t id = storage_.size() - 1;
while (storage_[id]->size == 0)
--id;
return id;
}
- void AllocateNewList(size_t list_size) {
- ++list_count_;
- scoped_ptr<InnerList> new_list(new InnerList);
- storage_.push_back(new_list.Pass());
- last_list_ = storage_.back();
- InnerList* list = last_list_;
- list->capacity = list_size;
- list->size = 0;
- list->step = element_size_;
- list->data.reset(new char[list->capacity * list->step]);
- }
-
size_t NumAvailableElementsInLastList() const {
return last_list_->NumElementsAvailable();
}
private:
+ void AllocateNewList(size_t list_size) {
+ scoped_ptr<InnerList> new_list(new InnerList);
+ new_list->capacity = list_size;
+ new_list->size = 0;
+ new_list->step = element_size_;
+ new_list->data.reset(new char[list_size * element_size_]);
+ storage_.push_back(new_list.Pass());
+ }
+
ScopedPtrVector<InnerList> storage_;
const size_t element_size_;
+
+ // The number of elements in the list.
size_t size_;
- size_t list_count_;
+
+ // 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_;
DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator);
@@ -275,6 +309,10 @@ ListContainerBase::ListContainerBase(size_t max_size_for_derived_class,
ListContainerBase::~ListContainerBase() {
}
+void ListContainerBase::RemoveLast() {
+ data_->RemoveLast();
+}
+
void ListContainerBase::EraseAndInvalidateAllPointers(
ListContainerBase::Iterator position) {
data_->Erase(position);
« no previous file with comments | « cc/base/list_container.h ('k') | cc/base/sidecar_list_container.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698