Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 | 120 |
| 115 void Clear() { | 121 void Clear() { |
| 116 size_t initial_allocation_size = storage_.front()->capacity; | 122 size_t initial_allocation_size = storage_.front()->capacity; |
| 117 storage_.clear(); | 123 storage_.clear(); |
| 118 list_count_ = 0; | 124 list_count_ = 0; |
| 119 last_list_ = NULL; | 125 last_list_ = NULL; |
| 120 size_ = 0; | 126 size_ = 0; |
| 121 AllocateNewList(initial_allocation_size); | 127 AllocateNewList(initial_allocation_size); |
| 122 } | 128 } |
| 123 | 129 |
| 130 void RemoveLast() { | |
| 131 DCHECK(!IsEmpty()); | |
| 132 last_list_->RemoveLast(); | |
| 133 if (last_list_->IsEmpty()) | |
| 134 DeallocateLastList(); | |
|
danakj
2015/06/02 20:04:32
Is it possible to avoid this deallocate and just l
| |
| 135 --size_; | |
| 136 } | |
| 137 | |
| 124 void Erase(PositionInListContainerCharAllocator position) { | 138 void Erase(PositionInListContainerCharAllocator position) { |
| 125 DCHECK_EQ(this, position.ptr_to_container); | 139 DCHECK_EQ(this, position.ptr_to_container); |
| 126 storage_[position.vector_index]->Erase(position.item_iterator); | 140 storage_[position.vector_index]->Erase(position.item_iterator); |
| 127 // TODO(weiliangc): Free the InnerList if it is empty. | 141 // TODO(weiliangc): Free the InnerList if it is empty. |
| 128 --size_; | 142 --size_; |
| 129 } | 143 } |
| 130 | 144 |
| 131 InnerList* InnerListById(size_t id) const { | 145 InnerList* InnerListById(size_t id) const { |
| 132 DCHECK_LT(id, list_count_); | 146 DCHECK_LT(id, list_count_); |
| 133 return storage_[id]; | 147 return storage_[id]; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 163 list->size = 0; | 177 list->size = 0; |
| 164 list->step = element_size_; | 178 list->step = element_size_; |
| 165 list->data.reset(new char[list->capacity * list->step]); | 179 list->data.reset(new char[list->capacity * list->step]); |
| 166 } | 180 } |
| 167 | 181 |
| 168 size_t NumAvailableElementsInLastList() const { | 182 size_t NumAvailableElementsInLastList() const { |
| 169 return last_list_->NumElementsAvailable(); | 183 return last_list_->NumElementsAvailable(); |
| 170 } | 184 } |
| 171 | 185 |
| 172 private: | 186 private: |
| 187 void DeallocateLastList() { | |
| 188 // Don't deallocate the only list; we always expect there to be one. | |
| 189 if (list_count_ <= 1) | |
| 190 return; | |
| 191 --list_count_; | |
| 192 storage_.pop_back(); | |
| 193 last_list_ = list_count_ ? storage_.back() : nullptr; | |
| 194 } | |
| 195 | |
| 173 ScopedPtrVector<InnerList> storage_; | 196 ScopedPtrVector<InnerList> storage_; |
| 174 const size_t element_size_; | 197 const size_t element_size_; |
| 175 size_t size_; | 198 size_t size_; |
| 176 size_t list_count_; | 199 size_t list_count_; |
| 177 InnerList* last_list_; | 200 InnerList* last_list_; |
| 178 | 201 |
| 179 DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator); | 202 DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator); |
| 180 }; | 203 }; |
| 181 | 204 |
| 182 // PositionInListContainerCharAllocator | 205 // PositionInListContainerCharAllocator |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 268 | 291 |
| 269 ListContainerBase::ListContainerBase(size_t max_size_for_derived_class, | 292 ListContainerBase::ListContainerBase(size_t max_size_for_derived_class, |
| 270 size_t num_of_elements_to_reserve_for) | 293 size_t num_of_elements_to_reserve_for) |
| 271 : data_(new ListContainerCharAllocator(max_size_for_derived_class, | 294 : data_(new ListContainerCharAllocator(max_size_for_derived_class, |
| 272 num_of_elements_to_reserve_for)) { | 295 num_of_elements_to_reserve_for)) { |
| 273 } | 296 } |
| 274 | 297 |
| 275 ListContainerBase::~ListContainerBase() { | 298 ListContainerBase::~ListContainerBase() { |
| 276 } | 299 } |
| 277 | 300 |
| 301 void ListContainerBase::RemoveLast() { | |
| 302 data_->RemoveLast(); | |
| 303 } | |
| 304 | |
| 278 void ListContainerBase::EraseAndInvalidateAllPointers( | 305 void ListContainerBase::EraseAndInvalidateAllPointers( |
| 279 ListContainerBase::Iterator position) { | 306 ListContainerBase::Iterator position) { |
| 280 data_->Erase(position); | 307 data_->Erase(position); |
| 281 } | 308 } |
| 282 | 309 |
| 283 ListContainerBase::ConstReverseIterator ListContainerBase::crbegin() const { | 310 ListContainerBase::ConstReverseIterator ListContainerBase::crbegin() const { |
| 284 if (data_->IsEmpty()) | 311 if (data_->IsEmpty()) |
| 285 return crend(); | 312 return crend(); |
| 286 | 313 |
| 287 size_t id = data_->LastInnerListId(); | 314 size_t id = data_->LastInnerListId(); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 } | 494 } |
| 468 | 495 |
| 469 ListContainerBase::ConstReverseIterator::~ConstReverseIterator() { | 496 ListContainerBase::ConstReverseIterator::~ConstReverseIterator() { |
| 470 } | 497 } |
| 471 | 498 |
| 472 size_t ListContainerBase::ConstReverseIterator::index() const { | 499 size_t ListContainerBase::ConstReverseIterator::index() const { |
| 473 return index_; | 500 return index_; |
| 474 } | 501 } |
| 475 | 502 |
| 476 } // namespace cc | 503 } // namespace cc |
| OLD | NEW |