21 #ifndef _TULIPIDMANAGER_H 22 #define _TULIPIDMANAGER_H 32 #include <tulip/MutableContainer.h> 33 #include <tulip/StlIterator.h> 38 struct IdManagerState {
44 std::set<unsigned int> freeIds;
46 IdManagerState(): firstId(0), nextId(0) {}
51 template <
typename TYPE>
52 class IdManagerIterator:
public Iterator<TYPE> {
57 const std::set<unsigned int>& freeIds;
58 std::set<unsigned int>::const_iterator it;
62 IdManagerIterator(
const IdManagerState& info):
63 current(info.firstId), last(info.nextId), freeIds(info.freeIds), it(freeIds.begin()) {
64 #ifdef TLP_NO_IDS_REUSE 65 std::set<unsigned int>::const_reverse_iterator itr;
66 itr = freeIds.rbegin();
68 while(itr != freeIds.rend() && (*itr) == last - 1) {
75 ~IdManagerIterator() {}
78 return (current < last);
82 unsigned int tmp = current;
85 while(it != freeIds.end()) {
86 if (current < *it)
return (TYPE) tmp;
97 class TLP_SCOPE IdManager {
100 IdManagerState state;
107 bool is_free(
unsigned int)
const;
111 void free(
const unsigned int);
116 #ifdef TLP_NO_IDS_REUSE 117 return state.nextId++;
119 return state.firstId ?
121 (state.freeIds.empty() ? state.nextId++ : getFreeId());
127 unsigned int getFirstOfRange(
unsigned nb) {
128 unsigned int first = state.nextId;
133 #ifndef TLP_NO_IDS_REUSE 137 unsigned int getFreeId();
144 void getFreeId(
unsigned int id);
148 const IdManagerState& getState() {
154 void restoreState(
const IdManagerState& info) {
162 template<
typename TYPE>
164 return new IdManagerIterator<TYPE>(state);
167 friend std::ostream&
operator<<(std::ostream &,
const IdManager &);
168 friend class IdManagerTest;
171 std::ostream&
operator<<(std::ostream &,
const IdManager &);
175 template<
typename ID_TYPE>
176 class TLP_SCOPE IdContainer :
public std::vector<ID_TYPE> {
180 std::vector<unsigned int> pos;
182 inline ID_TYPE*& beginPtr() {
183 return ((ID_TYPE **)
this)[0];
186 inline ID_TYPE*& sizePtr() {
187 return ((ID_TYPE**)
this)[1];
190 inline void setSize(
unsigned int size) {
191 sizePtr() = beginPtr() + size;
195 IdContainer() : std::vector<ID_TYPE>(), nbFree(0) {}
199 std::vector<ID_TYPE>::clear();
205 void reserve(
size_t nb) {
206 std::vector<ID_TYPE>::reserve(nb);
211 inline bool hasFree()
const {
216 inline unsigned int numberOfFree()
const {
221 inline bool isElement(ID_TYPE elt)
const {
222 unsigned int id = (
unsigned int) elt;
223 return id < pos.size() && pos[id] != UINT_MAX;
228 return new StlIterator<ID_TYPE, typename std::vector<ID_TYPE>::const_iterator>(this->begin(), this->end());
232 inline unsigned int getPos(ID_TYPE elt)
const {
233 assert(isElement(elt));
234 return pos[(
unsigned int) elt];
239 unsigned int freePos = this->size();
242 setSize(freePos + 1);
246 this->resize(freePos + 1);
247 pos.resize(freePos + 1);
248 (*this)[freePos] = ID_TYPE(freePos);
251 ID_TYPE elt = (*this)[freePos];
252 pos[(
unsigned int) elt] = freePos;
257 unsigned int getFirstOfRange(
unsigned int nb) {
258 unsigned int freePos = this->size();
259 unsigned int i = std::min(nbFree, nb);
262 setSize(freePos + i);
267 this->resize(freePos + nb);
268 pos.resize(freePos + nb);
271 (*
this)[freePos + i] = ID_TYPE(freePos + i);
274 for (i = 0; i < nb; ++i)
275 pos[(
unsigned int)((*this)[freePos + i])] = freePos + i;
281 void free(ID_TYPE elt) {
282 unsigned int curPos = pos[(
unsigned int) elt];
283 unsigned int lastPos = this->size() - 1;
287 if (curPos != lastPos) {
289 tmp = (*this)[lastPos];
290 (*this)[lastPos] = (*this)[curPos];
291 assert((*
this)[curPos] == elt);
292 (*this)[curPos] = tmp;
293 pos[(
unsigned int) tmp] = curPos;
296 pos[(
unsigned int) elt] = UINT_MAX;
313 void copyTo(IdContainer<ID_TYPE>& ids)
const {
314 unsigned int sz = std::vector<ID_TYPE>::size() + nbFree;
316 memcpy(ids.data(), this->data(), sz *
sizeof(ID_TYPE));
318 memcpy(ids.pos.data(), this->pos.data(), sz *
sizeof(
unsigned int));
320 ids.setSize(std::vector<ID_TYPE>::size());
324 void swap(ID_TYPE a, ID_TYPE b) {
325 assert(isElement(a));
326 assert(isElement(b));
327 unsigned int pa = pos[(
unsigned int) a];
328 unsigned int tmp = pos[(
unsigned int) b];
329 pos[(
unsigned int) b] = pa;
330 pos[(
unsigned int) a] = tmp;
337 unsigned int nbElts = this->size();
339 #pragma omp parallel for 342 for(
unsigned int i = 0; i < nbElts; ++i)
343 pos[(
unsigned int) (*this)[i]] = i;
348 std::sort(this->begin(), this->end());
354 template<
typename ID_TYPE>
355 class SGraphIdContainer :
public std::vector<ID_TYPE> {
357 MutableContainer<unsigned int> pos;
359 SGraphIdContainer() {
360 pos.setAll(UINT_MAX);
362 inline bool isElement(ID_TYPE elt)
const {
363 return (pos.get((
unsigned int) elt) != UINT_MAX);
366 inline unsigned int getPos(ID_TYPE elt)
const {
367 assert(isElement(elt));
368 return pos.get((
unsigned int) elt);
371 void add(ID_TYPE elt) {
372 assert(!isElement(elt));
374 pos.set((
unsigned int) elt, this->size());
375 this->push_back(elt);
378 void clone(
const std::vector<ID_TYPE>& elts) {
379 ((std::vector<ID_TYPE>&)(*
this)) = elts;
380 unsigned int nb = elts.size();
382 for (
unsigned int i = 0; i < nb; ++i)
383 pos.set((
unsigned int) elts[i], i);
386 void remove(ID_TYPE elt) {
387 assert(isElement(elt));
389 unsigned int i = pos.get((
unsigned int) elt);
390 assert(i < this->size());
392 unsigned int last = this->size() - 1;
395 pos.set((
unsigned int) ((*
this)[i] = (*
this)[last]), i);
400 pos.set((
unsigned int) elt, UINT_MAX);
405 std::sort(this->begin(), this->end());
406 unsigned int nbElts = this->size();
408 for(
unsigned int i = 0; i < nbElts; ++i)
409 pos.set((
unsigned int) (*
this)[i], i);
std::ostream & operator<<(std::ostream &os, const Array< Obj, SIZE > &array)
operator << stream operator to easily print an array, or save it to a file.
Interface for Tulip iterators. Allows basic iteration operations only.