16 #include "pandabase.h" 18 #include "notifyCategoryProxy.h" 20 #include "uniqueIdAllocator.h" 22 NotifyCategoryDecl(uniqueIdAllocator, EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL);
23 NotifyCategoryDef(uniqueIdAllocator,
"");
25 const PN_uint32 UniqueIdAllocator::IndexEnd = (PN_uint32)-1;
26 const PN_uint32 UniqueIdAllocator::IndexAllocated = (PN_uint32)-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 58 : _min(min), _max(max) {
59 uniqueIdAllocator_debug(
"UniqueIdAllocator("<<min<<
", "<<max<<
")");
61 nassertv(_max >= _min);
65 _table = (PN_uint32 *)PANDA_MALLOC_ARRAY(_size *
sizeof(PN_uint32));
68 for (PN_uint32 i = 0; i < _size; ++i) {
71 _table[_size - 1] = IndexEnd;
73 _last_free = _size - 1;
83 ~UniqueIdAllocator() {
84 uniqueIdAllocator_debug(
"~UniqueIdAllocator()");
85 PANDA_FREE_ARRAY(_table);
98 if (_next_free == IndexEnd) {
100 uniqueIdAllocator_warning(
"allocate Error: no more free ids.");
103 PN_uint32 index = _next_free;
104 nassertr(_table[index] != IndexAllocated, IndexEnd);
106 _next_free = _table[_next_free];
107 _table[index] = IndexAllocated;
111 PN_uint32
id = index + _min;
112 uniqueIdAllocator_debug(
"allocate() returning " <<
id);
134 nassertv(
id >= _min &&
id <= _max);
135 PN_uint32 index =
id - _min;
137 nassertv(_table[index] != IndexAllocated);
141 _next_free = IndexEnd;
143 }
else if (_next_free == index) {
145 _next_free = _table[index];
161 PN_uint32 prev_index = index;
162 while (prev_index > 0 && _table[prev_index - 1] != index) {
165 if (prev_index > 0 && _table[prev_index - 1] == index) {
171 prev_index = index + 1;
172 while (prev_index < _size && _table[prev_index] != index) {
177 nassertv(_table[prev_index] == index);
178 _table[prev_index] = _table[index];
180 if (index == _last_free) {
181 _last_free = prev_index;
185 _table[index] = IndexAllocated;
198 uniqueIdAllocator_debug(
"free("<<
id<<
")");
200 nassertv(
id >= _min &&
id <= _max);
201 PN_uint32 index =
id - _min;
202 nassertv(_table[index] == IndexAllocated);
203 if (_next_free != IndexEnd) {
204 nassertv(_table[_last_free] == IndexEnd);
205 _table[_last_free] = index;
207 _table[index] = IndexEnd;
210 if (_next_free == IndexEnd) {
227 return PN_stdfloat(_size-_free)/_size;
237 out <<
"UniqueIdAllocator(" << _min <<
", " << _max <<
"), " 238 << _free <<
" id's remaining of " << _size;
248 out <<
"_min: " << _min <<
"; _max: " << _max
249 <<
";\n_next_free: " << PN_int32(_next_free)
250 <<
"; _last_free: " << PN_int32(_last_free)
251 <<
"; _size: " << _size
252 <<
"; _free: " << _free
253 <<
"; used: " << _size - _free
258 for (PN_uint32 i = 0; i < _size; ++i) {
259 out <<
" " << PN_int32(_table[i]);
263 out <<
"Free chain:";
264 PN_uint32 index = _next_free;
265 while (index != IndexEnd) {
266 out <<
" " << index + _min;
267 index = _table[index];
void output(ostream &out) const
...intended for debugging only.
void free(PN_uint32 index)
Free an allocated index (index must be between _min and _max that were passed to the constructor)...
void initial_reserve_id(PN_uint32 id)
This may be called to mark a particular id as having already been allocated (for instance, by a prior pass).
PN_stdfloat fraction_used() const
return the decimal fraction of the pool that is used.
void write(ostream &out) const
...intended for debugging only.
PN_uint32 allocate()
Returns an id between _min and _max (that were passed to the constructor).
UniqueIdAllocator(PN_uint32 min=0, PN_uint32 max=20)
Create a free id pool in the range [min:max].