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

Side by Side Diff: gpu/command_buffer/common/id_allocator.cc

Issue 988693005: Chromium roll (https://codereview.chromium.org/976353002) (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: fixed bad android build patch Created 5 years, 9 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // This file contains the implementation of IdAllocator. 5 // This file contains the implementation of IdAllocator.
6 6
7 #include "gpu/command_buffer/common/id_allocator.h" 7 #include "gpu/command_buffer/common/id_allocator.h"
8 8
9 #include <limits>
9 #include "base/logging.h" 10 #include "base/logging.h"
10 11
11 namespace gpu { 12 namespace gpu {
12 13
13 IdAllocator::IdAllocator() {} 14 IdAllocator::IdAllocator() {
15 COMPILE_ASSERT(kInvalidResource == 0u, invalid_resource_is_not_zero);
16 // Simplify the code by making sure that lower_bound(id) never
17 // returns the beginning of the map, if id is valid (eg !=
18 // kInvalidResource).
19 used_ids_.insert(std::make_pair(0u, 0u));
20 }
14 21
15 IdAllocator::~IdAllocator() {} 22 IdAllocator::~IdAllocator() {}
16 23
17 ResourceId IdAllocator::AllocateID() { 24 ResourceId IdAllocator::AllocateID() {
18 ResourceId id; 25 return AllocateIDRange(1u);
19 ResourceIdSet::iterator iter = free_ids_.begin(); 26 }
20 if (iter != free_ids_.end()) { 27
21 id = *iter; 28 ResourceId IdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) {
29 if (desired_id == 0u || desired_id == 1u) {
30 return AllocateIDRange(1u);
31 }
32
33 ResourceIdRangeMap::iterator current = used_ids_.lower_bound(desired_id);
34 ResourceIdRangeMap::iterator next = current;
35 if (current == used_ids_.end() || current->first > desired_id) {
36 current--;
22 } else { 37 } else {
23 id = LastUsedId() + 1; 38 next++;
24 if (!id) { 39 }
25 // We wrapped around to 0. 40
26 id = FindFirstUnusedId(); 41 ResourceId first_id = current->first;
27 } 42 ResourceId last_id = current->second;
28 } 43
29 MarkAsUsed(id); 44 DCHECK(desired_id >= first_id);
30 return id; 45
31 } 46 if (desired_id - 1u <= last_id) {
32 47 // Append to current range.
33 ResourceId IdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) { 48 last_id++;
34 ResourceId id; 49 if (last_id == 0) {
35 ResourceIdSet::iterator iter = free_ids_.lower_bound(desired_id); 50 // The increment overflowed.
36 if (iter != free_ids_.end()) { 51 return AllocateIDRange(1u);
37 id = *iter; 52 }
38 } else if (LastUsedId() < desired_id) { 53
39 id = desired_id; 54 current->second = last_id;
40 } else { 55
41 id = LastUsedId() + 1; 56 if (next != used_ids_.end() && next->first - 1u == last_id) {
42 if (!id) { 57 // Merge with next range.
43 // We wrapped around to 0. 58 current->second = next->second;
44 id = FindFirstUnusedId(); 59 used_ids_.erase(next);
45 } 60 }
46 } 61 return last_id;
47 MarkAsUsed(id); 62 } else if (next != used_ids_.end() && next->first - 1u == desired_id) {
48 return id; 63 // Prepend to next range.
64 ResourceId last_existing_id = next->second;
65 used_ids_.erase(next);
66 used_ids_.insert(std::make_pair(desired_id, last_existing_id));
67 return desired_id;
68 }
69 used_ids_.insert(std::make_pair(desired_id, desired_id));
70 return desired_id;
71 }
72
73 ResourceId IdAllocator::AllocateIDRange(uint32_t range) {
74 DCHECK(range > 0u);
75
76 ResourceIdRangeMap::iterator current = used_ids_.begin();
77 ResourceIdRangeMap::iterator next = current;
78
79 while (++next != used_ids_.end()) {
80 if (next->first - current->second > range) {
81 break;
82 }
83 current = next;
84 }
85
86 ResourceId first_id = current->second + 1u;
87 ResourceId last_id = first_id + range - 1u;
88
89 if (first_id == 0u || last_id < first_id) {
90 return kInvalidResource;
91 }
92
93 current->second = last_id;
94
95 if (next != used_ids_.end() && next->first - 1u == last_id) {
96 // Merge with next range.
97 current->second = next->second;
98 used_ids_.erase(next);
99 }
100
101 return first_id;
49 } 102 }
50 103
51 bool IdAllocator::MarkAsUsed(ResourceId id) { 104 bool IdAllocator::MarkAsUsed(ResourceId id) {
52 DCHECK(id); 105 DCHECK(id);
53 free_ids_.erase(id); 106 ResourceIdRangeMap::iterator current = used_ids_.lower_bound(id);
54 std::pair<ResourceIdSet::iterator, bool> result = used_ids_.insert(id); 107 if (current != used_ids_.end() && current->first == id) {
55 return result.second; 108 return false;
109 }
110
111 ResourceIdRangeMap::iterator next = current;
112 --current;
113
114 if (current->second >= id) {
115 return false;
116 }
117
118 DCHECK(current->first < id && current->second < id);
119
120 if (current->second + 1u == id) {
121 // Append to current range.
122 current->second = id;
123 if (next != used_ids_.end() && next->first - 1u == id) {
124 // Merge with next range.
125 current->second = next->second;
126 used_ids_.erase(next);
127 }
128 return true;
129 } else if (next != used_ids_.end() && next->first - 1u == id) {
130 // Prepend to next range.
131 ResourceId last_existing_id = next->second;
132 used_ids_.erase(next);
133 used_ids_.insert(std::make_pair(id, last_existing_id));
134 return true;
135 }
136
137 used_ids_.insert(std::make_pair(id, id));
138 return true;
56 } 139 }
57 140
58 void IdAllocator::FreeID(ResourceId id) { 141 void IdAllocator::FreeID(ResourceId id) {
59 if (id) { 142 FreeIDRange(id, 1u);
60 used_ids_.erase(id); 143 }
61 free_ids_.insert(id); 144
145 void IdAllocator::FreeIDRange(ResourceId first_id, uint32 range) {
146 COMPILE_ASSERT(kInvalidResource == 0u, invalid_resource_is_not_zero);
147
148 if (range == 0u || (first_id == 0u && range == 1u)) {
149 return;
150 }
151
152 if (first_id == 0u) {
153 first_id++;
154 range--;
155 }
156
157 ResourceId last_id = first_id + range - 1u;
158 if (last_id < first_id) {
159 last_id = std::numeric_limits<ResourceId>::max();
160 }
161
162 while (true) {
163 ResourceIdRangeMap::iterator current = used_ids_.lower_bound(last_id);
164 if (current == used_ids_.end() || current->first > last_id) {
165 --current;
166 }
167
168 if (current->second < first_id) {
169 return;
170 }
171
172 if (current->first >= first_id) {
173 ResourceId last_existing_id = current->second;
174 used_ids_.erase(current);
175 if (last_id < last_existing_id) {
176 used_ids_.insert(std::make_pair(last_id + 1u, last_existing_id));
177 }
178 } else if (current->second <= last_id) {
179 current->second = first_id - 1u;
180 } else {
181 DCHECK(current->first < first_id && current->second > last_id);
182 ResourceId last_existing_id = current->second;
183 current->second = first_id - 1u;
184 used_ids_.insert(std::make_pair(last_id + 1u, last_existing_id));
185 }
62 } 186 }
63 } 187 }
64 188
65 bool IdAllocator::InUse(ResourceId id) const { 189 bool IdAllocator::InUse(ResourceId id) const {
66 return id == kInvalidResource || used_ids_.find(id) != used_ids_.end(); 190 if (id == kInvalidResource) {
67 } 191 return false;
68 192 }
69 ResourceId IdAllocator::LastUsedId() const { 193
70 if (used_ids_.empty()) { 194 ResourceIdRangeMap::const_iterator current = used_ids_.lower_bound(id);
71 return 0u; 195 if (current != used_ids_.end()) {
72 } else { 196 if (current->first == id) {
73 return *used_ids_.rbegin(); 197 return true;
74 } 198 }
75 } 199 }
76 200
77 ResourceId IdAllocator::FindFirstUnusedId() const { 201 --current;
78 ResourceId id = 1; 202 return current->second >= id;
79 for (ResourceIdSet::const_iterator it = used_ids_.begin();
80 it != used_ids_.end(); ++it) {
81 if ((*it) != id) {
82 return id;
83 }
84 ++id;
85 }
86 return id;
87 } 203 }
88 204
89 } // namespace gpu 205 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/common/id_allocator.h ('k') | gpu/command_buffer/common/id_allocator_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698