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

Side by Side 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, 6 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/base/list_container.h" 5 #include "cc/base/list_container.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "cc/base/scoped_ptr_vector.h" 10 #include "cc/base/scoped_ptr_vector.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 DCHECK_LE(position, LastElement()); 46 DCHECK_LE(position, LastElement());
47 DCHECK_GE(position, Begin()); 47 DCHECK_GE(position, Begin());
48 char* start = position + step; 48 char* start = position + step;
49 std::copy(start, End(), position); 49 std::copy(start, End(), position);
50 50
51 --size; 51 --size;
52 // Decrease capacity to avoid creating not full not last InnerList. 52 // Decrease capacity to avoid creating not full not last InnerList.
53 --capacity; 53 --capacity;
54 } 54 }
55 55
56 bool IsEmpty() const { return !size; }
56 bool IsFull() { return capacity == size; } 57 bool IsFull() { return capacity == size; }
57 size_t NumElementsAvailable() const { return capacity - size; } 58 size_t NumElementsAvailable() const { return capacity - size; }
58 59
59 void* AddElement() { 60 void* AddElement() {
60 DCHECK_LT(size, capacity); 61 DCHECK_LT(size, capacity);
61 ++size; 62 ++size;
62 return LastElement(); 63 return LastElement();
63 } 64 }
64 65
66 void RemoveLast() {
67 DCHECK(!IsEmpty());
68 --size;
69 }
70
65 char* Begin() const { return data.get(); } 71 char* Begin() const { return data.get(); }
66 char* End() const { return data.get() + size * step; } 72 char* End() const { return data.get() + size * step; }
67 char* LastElement() const { return data.get() + (size - 1) * step; } 73 char* LastElement() const { return data.get() + (size - 1) * step; }
68 char* ElementAt(size_t index) const { return data.get() + index * step; } 74 char* ElementAt(size_t index) const { return data.get() + index * step; }
69 75
70 private: 76 private:
71 DISALLOW_COPY_AND_ASSIGN(InnerList); 77 DISALLOW_COPY_AND_ASSIGN(InnerList);
72 }; 78 };
73 79
74 explicit ListContainerCharAllocator(size_t element_size) 80 explicit ListContainerCharAllocator(size_t element_size)
75 : element_size_(element_size), 81 : element_size_(element_size),
76 size_(0), 82 size_(0),
77 list_count_(0), 83 last_list_index_(0),
78 last_list_(NULL) { 84 last_list_(NULL) {
79 AllocateNewList(kDefaultNumElementTypesToReserve); 85 AllocateNewList(kDefaultNumElementTypesToReserve);
86 last_list_ = storage_[last_list_index_];
80 } 87 }
81 88
82 ListContainerCharAllocator(size_t element_size, size_t element_count) 89 ListContainerCharAllocator(size_t element_size, size_t element_count)
83 : element_size_(element_size), 90 : element_size_(element_size),
84 size_(0), 91 size_(0),
85 list_count_(0), 92 last_list_index_(0),
86 last_list_(NULL) { 93 last_list_(NULL) {
87 AllocateNewList(element_count > 0 ? element_count 94 AllocateNewList(element_count > 0 ? element_count
88 : kDefaultNumElementTypesToReserve); 95 : kDefaultNumElementTypesToReserve);
96 last_list_ = storage_[last_list_index_];
89 } 97 }
90 98
91 ~ListContainerCharAllocator() {} 99 ~ListContainerCharAllocator() {}
92 100
93 void* Allocate() { 101 void* Allocate() {
94 if (last_list_->IsFull()) 102 if (last_list_->IsFull()) {
95 AllocateNewList(last_list_->capacity * 2); 103 // Only allocate a new list if there isn't a spare one still there from
104 // previous usage.
105 if (last_list_index_ + 1 >= storage_.size())
106 AllocateNewList(last_list_->capacity * 2);
107
108 ++last_list_index_;
109 last_list_ = storage_[last_list_index_];
110 }
96 111
97 ++size_; 112 ++size_;
98 return last_list_->AddElement(); 113 return last_list_->AddElement();
99 } 114 }
100 115
101 size_t element_size() const { return element_size_; } 116 size_t element_size() const { return element_size_; }
102 size_t list_count() const { return list_count_; } 117 size_t list_count() const { return storage_.size(); }
103 size_t size() const { return size_; } 118 size_t size() const { return size_; }
104 bool IsEmpty() const { return size() == 0; } 119 bool IsEmpty() const { return size() == 0; }
105 120
106 size_t Capacity() const { 121 size_t Capacity() const {
107 size_t capacity_sum = 0; 122 size_t capacity_sum = 0;
108 for (ScopedPtrVector<InnerList>::const_iterator iter = storage_.begin(); 123 for (ScopedPtrVector<InnerList>::const_iterator iter = storage_.begin();
109 iter != storage_.end(); ++iter) { 124 iter != storage_.end(); ++iter) {
110 capacity_sum += (*iter)->capacity; 125 capacity_sum += (*iter)->capacity;
111 } 126 }
112 return capacity_sum; 127 return capacity_sum;
113 } 128 }
114 129
115 void Clear() { 130 void Clear() {
116 size_t initial_allocation_size = storage_.front()->capacity; 131 size_t initial_allocation_size = storage_.front()->capacity;
117 storage_.clear(); 132 storage_.clear();
118 list_count_ = 0;
119 last_list_ = NULL; 133 last_list_ = NULL;
134 last_list_index_ = 0;
120 size_ = 0; 135 size_ = 0;
121 AllocateNewList(initial_allocation_size); 136 AllocateNewList(initial_allocation_size);
137 last_list_ = storage_[last_list_index_];
138 }
139
140 void RemoveLast() {
141 DCHECK(!IsEmpty());
142 last_list_->RemoveLast();
143 if (last_list_->IsEmpty() && last_list_index_ > 0) {
144 --last_list_index_;
145 last_list_ = storage_[last_list_index_];
146
147 // If there are now two empty inner lists, free one of them.
148 if (last_list_index_ + 2 < storage_.size())
149 storage_.pop_back();
150 }
151 --size_;
122 } 152 }
123 153
124 void Erase(PositionInListContainerCharAllocator position) { 154 void Erase(PositionInListContainerCharAllocator position) {
125 DCHECK_EQ(this, position.ptr_to_container); 155 DCHECK_EQ(this, position.ptr_to_container);
126 storage_[position.vector_index]->Erase(position.item_iterator); 156 storage_[position.vector_index]->Erase(position.item_iterator);
127 // TODO(weiliangc): Free the InnerList if it is empty. 157 // TODO(weiliangc): Free the InnerList if it is empty.
128 --size_; 158 --size_;
129 } 159 }
130 160
131 InnerList* InnerListById(size_t id) const { 161 InnerList* InnerListById(size_t id) const {
132 DCHECK_LT(id, list_count_); 162 DCHECK_LT(id, storage_.size());
133 return storage_[id]; 163 return storage_[id];
134 } 164 }
135 165
136 size_t FirstInnerListId() const { 166 size_t FirstInnerListId() const {
137 // |size_| > 0 means that at least one vector in |storage_| will be 167 // |size_| > 0 means that at least one vector in |storage_| will be
138 // non-empty. 168 // non-empty.
139 DCHECK_GT(size_, 0u); 169 DCHECK_GT(size_, 0u);
140 size_t id = 0; 170 size_t id = 0;
141 while (storage_[id]->size == 0) 171 while (storage_[id]->size == 0)
142 ++id; 172 ++id;
143 return id; 173 return id;
144 } 174 }
145 175
146 size_t LastInnerListId() const { 176 size_t LastInnerListId() const {
147 // |size_| > 0 means that at least one vector in |storage_| will be 177 // |size_| > 0 means that at least one vector in |storage_| will be
148 // non-empty. 178 // non-empty.
149 DCHECK_GT(size_, 0u); 179 DCHECK_GT(size_, 0u);
150 size_t id = list_count_ - 1; 180 size_t id = storage_.size() - 1;
151 while (storage_[id]->size == 0) 181 while (storage_[id]->size == 0)
152 --id; 182 --id;
153 return id; 183 return id;
154 } 184 }
155 185
156 void AllocateNewList(size_t list_size) {
157 ++list_count_;
158 scoped_ptr<InnerList> new_list(new InnerList);
159 storage_.push_back(new_list.Pass());
160 last_list_ = storage_.back();
161 InnerList* list = last_list_;
162 list->capacity = list_size;
163 list->size = 0;
164 list->step = element_size_;
165 list->data.reset(new char[list->capacity * list->step]);
166 }
167
168 size_t NumAvailableElementsInLastList() const { 186 size_t NumAvailableElementsInLastList() const {
169 return last_list_->NumElementsAvailable(); 187 return last_list_->NumElementsAvailable();
170 } 188 }
171 189
172 private: 190 private:
191 void AllocateNewList(size_t list_size) {
192 scoped_ptr<InnerList> new_list(new InnerList);
193 new_list->capacity = list_size;
194 new_list->size = 0;
195 new_list->step = element_size_;
196 new_list->data.reset(new char[list_size * element_size_]);
197 storage_.push_back(new_list.Pass());
198 }
199
173 ScopedPtrVector<InnerList> storage_; 200 ScopedPtrVector<InnerList> storage_;
174 const size_t element_size_; 201 const size_t element_size_;
202
203 // The number of elements in the list.
175 size_t size_; 204 size_t size_;
176 size_t list_count_; 205
206 // The index of the last list to have had elements added to it, or the only
207 // list if the container has not had elements added since being cleared.
208 size_t last_list_index_;
209
210 // This is equivalent to |storage_[last_list_index_]|.
177 InnerList* last_list_; 211 InnerList* last_list_;
178 212
179 DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator); 213 DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator);
180 }; 214 };
181 215
182 // PositionInListContainerCharAllocator 216 // PositionInListContainerCharAllocator
183 ////////////////////////////////////////////////////// 217 //////////////////////////////////////////////////////
184 ListContainerBase::PositionInListContainerCharAllocator:: 218 ListContainerBase::PositionInListContainerCharAllocator::
185 PositionInListContainerCharAllocator( 219 PositionInListContainerCharAllocator(
186 const ListContainerBase::PositionInListContainerCharAllocator& other) 220 const ListContainerBase::PositionInListContainerCharAllocator& other)
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 302
269 ListContainerBase::ListContainerBase(size_t max_size_for_derived_class, 303 ListContainerBase::ListContainerBase(size_t max_size_for_derived_class,
270 size_t num_of_elements_to_reserve_for) 304 size_t num_of_elements_to_reserve_for)
271 : data_(new ListContainerCharAllocator(max_size_for_derived_class, 305 : data_(new ListContainerCharAllocator(max_size_for_derived_class,
272 num_of_elements_to_reserve_for)) { 306 num_of_elements_to_reserve_for)) {
273 } 307 }
274 308
275 ListContainerBase::~ListContainerBase() { 309 ListContainerBase::~ListContainerBase() {
276 } 310 }
277 311
312 void ListContainerBase::RemoveLast() {
313 data_->RemoveLast();
314 }
315
278 void ListContainerBase::EraseAndInvalidateAllPointers( 316 void ListContainerBase::EraseAndInvalidateAllPointers(
279 ListContainerBase::Iterator position) { 317 ListContainerBase::Iterator position) {
280 data_->Erase(position); 318 data_->Erase(position);
281 } 319 }
282 320
283 ListContainerBase::ConstReverseIterator ListContainerBase::crbegin() const { 321 ListContainerBase::ConstReverseIterator ListContainerBase::crbegin() const {
284 if (data_->IsEmpty()) 322 if (data_->IsEmpty())
285 return crend(); 323 return crend();
286 324
287 size_t id = data_->LastInnerListId(); 325 size_t id = data_->LastInnerListId();
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 } 505 }
468 506
469 ListContainerBase::ConstReverseIterator::~ConstReverseIterator() { 507 ListContainerBase::ConstReverseIterator::~ConstReverseIterator() {
470 } 508 }
471 509
472 size_t ListContainerBase::ConstReverseIterator::index() const { 510 size_t ListContainerBase::ConstReverseIterator::index() const {
473 return index_; 511 return index_;
474 } 512 }
475 513
476 } // namespace cc 514 } // namespace cc
OLDNEW
« 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