22NotifyCategoryDecl(uniqueIdAllocator, EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL);
23NotifyCategoryDef(uniqueIdAllocator,
"");
25const uint32_t UniqueIdAllocator::IndexEnd = (uint32_t)-1;
26const 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;
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;
213output(std::ostream &out)
const {
214 out <<
"UniqueIdAllocator(" << _min <<
", " << _max <<
"), "
215 << _free <<
" id's remaining of " << _size;
222write(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];
void initial_reserve_id(uint32_t id)
This may be called to mark a particular id as having already been allocated (for instance,...
void output(std::ostream &out) const
...intended for debugging only.
void write(std::ostream &out) const
...intended for debugging only.
uint32_t allocate()
Returns an id 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.
void free(uint32_t index)
Free an allocated index (index must be between _min and _max that were passed to the constructor).
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.