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) 47 #define audio_error(msg) \ 48 audio_cat->error() << msg << endl 56 : _min(min), _max(max) {
57 uniqueIdAllocator_debug(
"UniqueIdAllocator("<<min<<
", "<<max<<
")");
59 nassertv(_max >= _min);
63 _table = (uint32_t *)PANDA_MALLOC_ARRAY(_size *
sizeof(uint32_t));
66 for (uint32_t i = 0; i < _size; ++i) {
69 _table[_size - 1] = IndexEnd;
71 _last_free = _size - 1;
79 ~UniqueIdAllocator() {
80 uniqueIdAllocator_debug(
"~UniqueIdAllocator()");
81 PANDA_FREE_ARRAY(_table);
91 if (_next_free == IndexEnd) {
93 uniqueIdAllocator_warning(
"allocate Error: no more free ids.");
96 uint32_t index = _next_free;
97 nassertr(_table[index] != IndexAllocated, IndexEnd);
99 _next_free = _table[_next_free];
100 _table[index] = IndexAllocated;
104 uint32_t
id = index + _min;
105 uniqueIdAllocator_debug(
"allocate() returning " <<
id);
122 nassertv(
id >= _min &&
id <= _max);
123 uint32_t index =
id - _min;
125 nassertv(_table[index] != IndexAllocated);
129 _next_free = IndexEnd;
131 }
else if (_next_free == index) {
133 _next_free = _table[index];
148 uint32_t prev_index = index;
149 while (prev_index > 0 && _table[prev_index - 1] != index) {
152 if (prev_index > 0 && _table[prev_index - 1] == index) {
158 prev_index = index + 1;
159 while (prev_index < _size && _table[prev_index] != index) {
164 nassertv(_table[prev_index] == index);
165 _table[prev_index] = _table[index];
167 if (index == _last_free) {
168 _last_free = prev_index;
172 _table[index] = IndexAllocated;
183 uniqueIdAllocator_debug(
"free("<<
id<<
")");
185 nassertv(
id >= _min &&
id <= _max);
186 uint32_t index =
id - _min;
187 nassertv(_table[index] == IndexAllocated);
188 if (_next_free != IndexEnd) {
189 nassertv(_table[_last_free] == IndexEnd);
190 _table[_last_free] = index;
192 _table[index] = IndexEnd;
195 if (_next_free == IndexEnd) {
210 return PN_stdfloat(_size-_free)/_size;
218 out <<
"UniqueIdAllocator(" << _min <<
", " << _max <<
"), " 219 << _free <<
" id's remaining of " << _size;
227 out <<
"_min: " << _min <<
"; _max: " << _max
228 <<
";\n_next_free: " << int32_t(_next_free)
229 <<
"; _last_free: " << int32_t(_last_free)
230 <<
"; _size: " << _size
231 <<
"; _free: " << _free
232 <<
"; used: " << _size - _free
237 for (uint32_t i = 0; i < _size; ++i) {
238 out <<
" " << int32_t(_table[i]);
242 out <<
"Free chain:";
243 uint32_t index = _next_free;
244 while (index != IndexEnd) {
245 out <<
" " << index + _min;
246 index = _table[index];
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void initial_reserve_id(uint32_t id)
This may be called to mark a particular id as having already been allocated (for instance,...
uint32_t allocate()
Returns an id between _min and _max (that were passed to the constructor).
void write(std::ostream &out) const
...intended for debugging only.
void output(std::ostream &out) const
...intended for debugging only.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void free(uint32_t index)
Free an allocated index (index must be between _min and _max that were passed to the constructor).
PN_stdfloat fraction_used() const
return the decimal fraction of the pool that is used.
UniqueIdAllocator(uint32_t min=0, uint32_t max=20)
Create a free id pool in the range [min:max].
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.