22 NotifyCategoryDecl(uniqueIdAllocator, EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL);
23 NotifyCategoryDef(uniqueIdAllocator,
"");
25 const uint32_t UniqueIdAllocator::IndexEnd = (uint32_t)-1;
26 const uint32_t UniqueIdAllocator::IndexAllocated = (uint32_t)-2;
30 #define uniqueIdAllocator_debug(msg) \
31 if (uniqueIdAllocator_cat.is_debug()) { \
32 uniqueIdAllocator_cat->debug() << msg << endl; \
35 #define uniqueIdAllocator_info(msg) \
36 uniqueIdAllocator_cat->info() << msg << endl
38 #define uniqueIdAllocator_warning(msg) \
39 uniqueIdAllocator_cat->warning() << msg << endl
42 #define uniqueIdAllocator_debug(msg) ((void)0)
43 #define uniqueIdAllocator_info(msg) ((void)0)
44 #define uniqueIdAllocator_warning(msg) ((void)0)
52 : _min(min), _max(max) {
53 uniqueIdAllocator_debug(
"UniqueIdAllocator("<<min<<
", "<<max<<
")");
55 nassertv(_max >= _min);
59 _table = (uint32_t *)PANDA_MALLOC_ARRAY(_size *
sizeof(uint32_t));
62 for (uint32_t i = 0; i < _size; ++i) {
65 _table[_size - 1] = IndexEnd;
67 _last_free = _size - 1;
75 ~UniqueIdAllocator() {
76 uniqueIdAllocator_debug(
"~UniqueIdAllocator()");
77 PANDA_FREE_ARRAY(_table);
87 if (_next_free == IndexEnd) {
89 uniqueIdAllocator_warning(
"allocate Error: no more free ids.");
92 uint32_t index = _next_free;
93 nassertr(_table[index] != IndexAllocated, IndexEnd);
95 _next_free = _table[_next_free];
96 _table[index] = IndexAllocated;
100 uint32_t
id = index + _min;
101 uniqueIdAllocator_debug(
"allocate() returning " <<
id);
118 nassertv(
id >= _min &&
id <= _max);
119 uint32_t index =
id - _min;
121 nassertv(_table[index] != IndexAllocated);
125 _next_free = IndexEnd;
127 }
else if (_next_free == index) {
129 _next_free = _table[index];
144 uint32_t prev_index = index;
145 while (prev_index > 0 && _table[prev_index - 1] != index) {
148 if (prev_index > 0 && _table[prev_index - 1] == index) {
154 prev_index = index + 1;
155 while (prev_index < _size && _table[prev_index] != index) {
160 nassertv(_table[prev_index] == index);
161 _table[prev_index] = _table[index];
163 if (index == _last_free) {
164 _last_free = prev_index;
168 _table[index] = IndexAllocated;
179 uniqueIdAllocator_debug(
"free("<<
id<<
")");
181 nassertv(
id >= _min &&
id <= _max);
182 uint32_t index =
id - _min;
183 nassertv(_table[index] == IndexAllocated);
184 if (_next_free != IndexEnd) {
185 nassertv(_table[_last_free] == IndexEnd);
186 _table[_last_free] = index;
188 _table[index] = IndexEnd;
191 if (_next_free == IndexEnd) {
206 return PN_stdfloat(_size-_free)/_size;
213 output(std::ostream &out)
const {
214 out <<
"UniqueIdAllocator(" << _min <<
", " << _max <<
"), "
215 << _free <<
" id's remaining of " << _size;
222 write(std::ostream &out)
const {
223 out <<
"_min: " << _min <<
"; _max: " << _max
224 <<
";\n_next_free: " << int32_t(_next_free)
225 <<
"; _last_free: " << int32_t(_last_free)
226 <<
"; _size: " << _size
227 <<
"; _free: " << _free
228 <<
"; used: " << _size - _free
233 for (uint32_t i = 0; i < _size; ++i) {
234 out <<
" " << int32_t(_table[i]);
238 out <<
"Free chain:";
239 uint32_t index = _next_free;
240 while (index != IndexEnd) {
241 out <<
" " << index + _min;
242 index = _table[index];