gwenhywfar  5.10.1
idlist64.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Mon Mar 01 2004
3  copyright : (C) 2020 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #define DISABLE_DEBUGLOG
30 
31 
32 #include "idlist64_p.h"
33 
34 #include <gwenhywfar/memory.h>
35 #include <gwenhywfar/debug.h>
36 
37 
38 #include <stdlib.h>
39 #include <assert.h>
40 
41 
42 
43 /* ------------------------------------------------------------------------------------------------
44  * forward declarations
45  * ------------------------------------------------------------------------------------------------
46  */
47 
48 static GWENHYWFAR_CB void _attachToTable(GWEN_SIMPLEPTRLIST *pl, void *p);
49 static GWENHYWFAR_CB void _detachFromTable(GWEN_SIMPLEPTRLIST *pl, void *p);
50 
51 static int GWEN_IdList64__Sort(GWEN_IDLIST64 *idl, int ascending);
52 static int __compAscending(const void *pa, const void *pb);
53 static int __compDescending(const void *pa, const void *pb);
54 
55 static GWEN_IDTABLE64 *GWEN_IdTable64_new();
56 static void GWEN_IdTable64_free(GWEN_IDTABLE64 *ft);
57 static void GWEN_IdTable64_Attach(GWEN_IDTABLE64 *ft);
58 static GWEN_IDTABLE64 *GWEN_IdTable64_dup(const GWEN_IDTABLE64 *ftOrig);
59 static GWEN_IDTABLE64 *GWEN_IdTable64_Create(uint64_t maxEntries);
60 static uint64_t GWEN_IdTable64_GetMaxEntries(const GWEN_IDTABLE64 *ft);
61 static uint64_t GWEN_IdTable64_GetFreeEntries(const GWEN_IDTABLE64 *ft);
62 static void GWEN_IdTable64_DecFreeEntries(GWEN_IDTABLE64 *ft);
63 static uint64_t GWEN_IdTable64_GetHighestEntry(const GWEN_IDTABLE64 *ft);
64 static void GWEN_IdTable64_CheckAndSetHighestEntry(GWEN_IDTABLE64 *ft, uint64_t i);
65 
66 static uint32_t GWEN_IdTable64_GetRuntimeFlags(const GWEN_IDTABLE64 *ft);
67 static void GWEN_IdTable64_AddRuntimeFlags(GWEN_IDTABLE64 *ft, uint32_t i);
68 
69 static uint64_t *GWEN_IdTable64_GetPtrEntries(const GWEN_IDTABLE64 *ft);
70 static void GWEN_IdTable64_SetPtrEntries(GWEN_IDTABLE64 *ft, uint64_t *ptr);
71 
72 static GWEN_IDTABLE64 *GWEN_IdList64_GetTableAt(const GWEN_IDLIST64 *tl, uint64_t idx);
73 /*static int GWEN_IdList64_SetIdAt(GWEN_IDLIST64 *tl, uint64_t idx, uint64_t entry);*/
74 static int64_t GWEN_IdList64_AddTable(GWEN_IDLIST64 *idl, GWEN_IDTABLE64 *t);
75 
76 static uint64_t GWEN_IdList64__GetFirstId(const GWEN_IDLIST64 *idl, uint64_t *pos);
77 static uint64_t GWEN_IdList64__GetNextId(const GWEN_IDLIST64 *idl, uint64_t *pos);
78 
79 
80 
81 
82 /* ------------------------------------------------------------------------------------------------
83  * GWEN_IdList64
84  * ------------------------------------------------------------------------------------------------
85  */
86 
87 
89 {
90  return GWEN_IdList64_newWithSteps(GWEN_IDLIST64_ENTRIES_PER_TABLE);
91 }
92 
93 
94 
96 {
97  GWEN_IDLIST64 *idl;
98 
99  idl=GWEN_SimplePtrList_new(GWEN_IDLIST64_INITIAL_ENTRYCOUNT, GWEN_IDLIST64_STEPS);
105 
106  return idl;
107 }
108 
109 
110 
112 {
113  GWEN_IDLIST64 *idl;
114  uint64_t tableCount;
115  uint64_t i;
116 
118  tableCount=GWEN_SimplePtrList_GetUsedEntries(oldList);
119 
120  for (i=0; i<tableCount; i++) {
121  const GWEN_IDTABLE64 *oldTable;
122 
123  oldTable=GWEN_IdList64_GetTableAt(oldList, i);
124  if (oldTable) {
125  GWEN_IDTABLE64 *table;
126  int64_t rv;
127 
128  table=GWEN_IdTable64_dup(oldTable);
129  rv=GWEN_IdList64_AddTable(idl, table);
130  if (rv<0) {
131  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) rv);
132  GWEN_IdTable64_free(table);
133  GWEN_IdList64_free(idl);
134  return NULL;
135  }
136  GWEN_IdTable64_free(table);
137  }
138  } /* for */
140 
141  return idl;
142 }
143 
144 
145 
147 {
149 }
150 
151 
152 
154 {
156 }
157 
158 
159 
161 {
164 }
165 
166 
167 
169 {
171 }
172 
173 
174 
176 {
178 }
179 
180 
181 
183 {
185 }
186 
187 
188 
189 
191 {
193 }
194 
195 
196 
198 {
199  return GWEN_SimplePtrList_LazyCopy(oldList);
200 }
201 
202 
203 
204 GWEN_IDTABLE64 *GWEN_IdList64_GetTableAt(const GWEN_IDLIST64 *idl, uint64_t idx)
205 {
206  return GWEN_SimplePtrList_GetPtrAt(idl, idx);
207 }
208 
209 
210 
211 int GWEN_IdList64_SetTableAt(GWEN_IDLIST64 *idl, uint64_t idx, GWEN_IDTABLE64 *t)
212 {
213  return GWEN_SimplePtrList_SetPtrAt(idl, idx, t);
214 }
215 
216 
217 
218 int64_t GWEN_IdList64_AddTable(GWEN_IDLIST64 *idl, GWEN_IDTABLE64 *t)
219 {
220  return GWEN_SimplePtrList_AddPtr(idl, t);
221 }
222 
223 
224 
226 {
228 }
229 
230 
231 
233 {
234  uint64_t idx;
235 
237  if (idx)
238  return idx-1;
239  return GWEN_ERROR_NO_DATA;
240 }
241 
242 
243 
244 int64_t GWEN_IdList64_GetIdAt(const GWEN_IDLIST64 *idl, uint64_t idx)
245 {
246  int entriesPerTable;
247 
248  entriesPerTable=GWEN_SimplePtrList_GetUserIntData(idl);
249  if (entriesPerTable) {
250  uint64_t tablePos;
251  GWEN_IDTABLE64 *t;
252 
253  tablePos=idx/entriesPerTable;
254  t=GWEN_IdList64_GetTableAt(idl, tablePos);
255  if (t) {
256  uint64_t *entries;
257 
258  entries=GWEN_IdTable64_GetPtrEntries(t);
259  if (entries) {
260  uint64_t entryPos;
261 
262  entryPos=idx%entriesPerTable;
263  return entries[entryPos];
264  }
265  }
266  else {
267  DBG_ERROR(GWEN_LOGDOMAIN, "No table at table pos %lu", (unsigned long) tablePos);
268  }
269  }
270  else {
271  DBG_ERROR(GWEN_LOGDOMAIN, "No entriesPerTable");
272  }
273 
275 }
276 
277 
278 #if 0
279 int GWEN_IdList64_SetIdAt(GWEN_IDLIST64 *idl, uint64_t idx, uint64_t entry)
280 {
281  int rv;
282  int entriesPerTable;
283 
285  if (rv<0) {
286  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
287  return (int64_t) rv;
288  }
289 
290  entriesPerTable=GWEN_SimplePtrList_GetUserIntData(idl);
291  if (entriesPerTable) {
292  uint64_t tablePos;
293  GWEN_IDTABLE64 *t;
294 
295  tablePos=idx/entriesPerTable;
296  t=GWEN_IdList64_GetTableAt(idl, tablePos);
297  if (t) {
298  uint64_t *entries;
299 
300  /* copy table if necessary (copy-on-write) */
301  if (!(GWEN_IdTable64_GetRuntimeFlags(t) & GWEN_IDTABLE64_RUNTIME_FLAGS_ISCOPY)) {
302  GWEN_IDTABLE64 *pTableCopy;
303 
304  pTableCopy=GWEN_IdTable64_dup(t);
305  GWEN_IdList64_SetTableAt(idl, tablePos, pTableCopy);
306  t=pTableCopy;
307  GWEN_IdTable64_AddRuntimeFlags(t, GWEN_IDTABLE64_RUNTIME_FLAGS_ISCOPY);
308  }
309 
310  entries=GWEN_IdTable64_GetPtrEntries(t);
311  if (entries) {
312  uint64_t entryPos;
313 
314  entryPos=idx%entriesPerTable;
315  entries[entryPos]=entry;
316  return 0;
317  }
318  } /* if (t) */
319  else {
320  DBG_ERROR(GWEN_LOGDOMAIN, "No table at position %lu", (unsigned long int) tablePos);
321  return GWEN_ERROR_INTERNAL;
322  }
323  } /* if (entriesPerTable) */
324  else {
325  DBG_ERROR(GWEN_LOGDOMAIN, "No entriesPerTable, internal error");
326  return GWEN_ERROR_INTERNAL;
327  }
328 
330 
331 }
332 #endif
333 
334 
335 int64_t GWEN_IdList64_AddId(GWEN_IDLIST64 *idl, uint64_t entry)
336 {
337  GWEN_IDTABLE64 *pTableCurrent=NULL;
338  int64_t idxTableCurrent=0;
339  int entriesPerTable=GWEN_IdList64_GetTableMaxEntries(idl);
340  int rv;
341 
342  if (entry==0) {
343  DBG_ERROR(GWEN_LOGDOMAIN, "id 0 is not allowed");
344  return GWEN_ERROR_INVALID;
345  }
346 
348  if (rv<0) {
349  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
350  return (int64_t) rv;
351  }
352 
353  /* get last table */
354  idxTableCurrent=GWEN_IdList64_GetLastTablePos(idl);
355  DBG_VERBOUS(GWEN_LOGDOMAIN, "Last table pos is %d", (int)idxTableCurrent);
356  if (idxTableCurrent>=0)
357  pTableCurrent=GWEN_IdList64_GetTableAt(idl, idxTableCurrent);
358 
359  /* check last table for existence and free entries, possibly create and add new table */
360  if (pTableCurrent==NULL || GWEN_IdTable64_GetFreeEntries(pTableCurrent)==0) {
361  /* create new table */
362  if (pTableCurrent==NULL) {
363  DBG_VERBOUS(GWEN_LOGDOMAIN, "No table, need to create one");
364  }
365  else if (GWEN_IdTable64_GetFreeEntries(pTableCurrent)==0) {
366  DBG_VERBOUS(GWEN_LOGDOMAIN, "Current table has no free entries, need to create new one");
367  }
368 
369  DBG_VERBOUS(GWEN_LOGDOMAIN, "Creating table with %d entries", entriesPerTable);
370  pTableCurrent=GWEN_IdTable64_Create(entriesPerTable);
371  GWEN_IdTable64_AddRuntimeFlags(pTableCurrent, GWEN_IDTABLE64_RUNTIME_FLAGS_ISCOPY); /* no need to copy later */
372 
373  /* add table to list */
374  idxTableCurrent=GWEN_IdList64_AddTable(idl, pTableCurrent);
375  if (idxTableCurrent<0) {
376  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) idxTableCurrent);
377  GWEN_IdTable64_free(pTableCurrent);
378  return idxTableCurrent;
379  }
380  GWEN_IdTable64_free(pTableCurrent);
381  } /* if (pTableCurrent || GWEN_IdTable64_GetFreeEntries(pTableCurrent)==0) */
382 
383  /* allocate free entry in current table */
384  if (pTableCurrent && GWEN_IdTable64_GetFreeEntries(pTableCurrent)) {
385  uint64_t *ptr;
386  int64_t index=idxTableCurrent*entriesPerTable;
387  int64_t entryPos;
388 
389  /* copy table if necessary (copy-on-write) */
390  if (!(GWEN_IdTable64_GetRuntimeFlags(pTableCurrent) & GWEN_IDTABLE64_RUNTIME_FLAGS_ISCOPY)) {
391  GWEN_IDTABLE64 *pTableCopy;
392 
393  DBG_VERBOUS(GWEN_LOGDOMAIN, "Copying table at idx %lu", (unsigned long) idxTableCurrent);
394  pTableCopy=GWEN_IdTable64_dup(pTableCurrent);
395  GWEN_IdList64_SetTableAt(idl, idxTableCurrent, pTableCopy);
396  GWEN_IdTable64_free(pTableCopy);
397  pTableCurrent=pTableCopy;
398  GWEN_IdTable64_AddRuntimeFlags(pTableCurrent, GWEN_IDTABLE64_RUNTIME_FLAGS_ISCOPY);
399  }
400 
401  ptr=GWEN_IdTable64_GetPtrEntries(pTableCurrent);
402 
403  /* find entryPos of free entry in pTableCurrent */
404  DBG_VERBOUS(GWEN_LOGDOMAIN, "Current table (ptr=%p, %d entriesPerTable):", (void *)ptr, entriesPerTable);
405  /*GWEN_IdTable64_Dump(pTableCurrent);*/
406  if (GWEN_IdTable64_GetFreeEntries(pTableCurrent)==GWEN_IdTable64_GetMaxEntries(pTableCurrent)) {
408  entryPos=0;
409  }
410  else {
411  if (GWEN_IdTable64_GetHighestEntry(pTableCurrent)+1<entriesPerTable) {
412  /* fastest way: Just append to the end */
413  DBG_VERBOUS(GWEN_LOGDOMAIN, "Finding free empty the fast way");
414  entryPos=GWEN_IdTable64_GetHighestEntry(pTableCurrent)+1;
415  if (ptr[entryPos]!=0) {
416  DBG_ERROR(GWEN_LOGDOMAIN, "Entry[highest+1] should be 0 but isn't, SNH!");
417  return GWEN_ERROR_INTERNAL;
418  }
419  }
420  else {
421  /* slower way: find free entry somewhere in the table */
422  DBG_VERBOUS(GWEN_LOGDOMAIN, "Finding free empty the slow way");
423  for (entryPos=0; entryPos<entriesPerTable; entryPos++) {
424  if (ptr[entryPos]==0)
425  break;
426  }
427  }
428  }
429 
430  DBG_VERBOUS(GWEN_LOGDOMAIN, "New entry will be at index %lu in table %lu (index=%lu, resulting index: %lu)",
431  (unsigned long) entryPos,
432  (unsigned long) idxTableCurrent,
433  (unsigned long) index,
434  (unsigned long)(index+entryPos));
435 
436  if (entryPos<entriesPerTable) {
437  /* store new entry, get index */
438  ptr[entryPos]=entry;
439  index+=entryPos;
441  GWEN_IdTable64_DecFreeEntries(pTableCurrent);
442  GWEN_IdTable64_CheckAndSetHighestEntry(pTableCurrent, entryPos);
443  GWEN_IdTable64_AddRuntimeFlags(pTableCurrent, GWEN_IDTABLE64_RUNTIME_FLAGS_DIRTY);
444  return index;
445  }
446  else {
447  DBG_ERROR(GWEN_LOGDOMAIN, "Free entry not found, internal counter is invalid. SNH!");
448  return GWEN_ERROR_INTERNAL;
449  }
450  }
451  else {
452  DBG_ERROR(GWEN_LOGDOMAIN, "Still no table? SNH!");
453  return GWEN_ERROR_INTERNAL;
454  }
455 }
456 
457 
458 
459 int GWEN_IdList64_HasId(const GWEN_IDLIST64 *idl, uint64_t wantedId)
460 {
461  uint32_t idx;
462  int entriesPerTable=GWEN_IdList64_GetTableMaxEntries(idl);
463  int numTables=GWEN_IdList64_GetUsedTables(idl);
464 
465  for (idx=0; idx<numTables; idx++) {
466  GWEN_IDTABLE64 *idt;
467 
468  idt=GWEN_IdList64_GetTableAt(idl, idx);
469  if (idt) {
470  int i;
471 
472  for (i=0; i<entriesPerTable; i++) {
473  if (idt->ptrEntries[i]==wantedId) {
474  return 1;
475  }
476  }
477  }
478  }
479  return 0;
480 }
481 
482 
483 
484 int GWEN_IdList64_DelId(GWEN_IDLIST64 *idl, uint64_t wantedId)
485 {
486  uint32_t idx;
487  int entriesPerTable=GWEN_IdList64_GetTableMaxEntries(idl);
488  int numTables=GWEN_IdList64_GetUsedTables(idl);
489 
490  for (idx=0; idx<numTables; idx++) {
491  GWEN_IDTABLE64 *idt;
492 
493  idt=GWEN_IdList64_GetTableAt(idl, idx);
494  if (idt) {
495  int i;
496 
497  for (i=0; i<entriesPerTable; i++) {
498  if (idt->ptrEntries[i]==wantedId) {
499  idt->ptrEntries[i]=0;
501  return 1;
502  }
503  }
504  }
505  }
506  return 0;
507 }
508 
509 
510 
511 
512 
514 {
515  GWEN_IDTABLE64 *ft;
516 
517  ft=(GWEN_IDTABLE64 *) p;
519 }
520 
521 
522 
524 {
525  GWEN_IDTABLE64 *ft;
526 
527  ft=(GWEN_IDTABLE64 *) p;
529 }
530 
531 
532 
533 uint64_t GWEN_IdList64__GetFirstId(const GWEN_IDLIST64 *idl, uint64_t *pos)
534 {
535  uint32_t idx;
536  int idIndex=0;
537  int entriesPerTable=GWEN_IdList64_GetTableMaxEntries(idl);
538  int numTables=GWEN_IdList64_GetUsedTables(idl);
539 
540  *pos=0;
541  for (idx=0; idx<numTables; idx++) {
542  GWEN_IDTABLE64 *idt;
543 
544  idt=GWEN_IdList64_GetTableAt(idl, idx);
545  if (idt) {
546  int i;
547  uint64_t id;
548 
549  for (i=0; i<entriesPerTable; i++) {
550  if (idt->ptrEntries[i]!=0) {
551  id=idt->ptrEntries[i];
552  *pos=idIndex+i+1;
553  return id;
554  }
555  }
556  }
557  idIndex+=entriesPerTable;
558  }
559 
560  return 0;
561 }
562 
563 
564 
565 uint64_t GWEN_IdList64__GetNextId(const GWEN_IDLIST64 *idl, uint64_t *pos)
566 {
567  if (*pos) {
568  int entriesPerTable=GWEN_IdList64_GetTableMaxEntries(idl);
569  int numTables=GWEN_IdList64_GetUsedTables(idl);
570  uint64_t tableNum;
571  uint64_t tableIdx;
572  int idIndex=0;
573  uint32_t idx;
574 
575  tableNum=*pos / entriesPerTable;
576  tableIdx=*pos % entriesPerTable;
577 
578  if (tableNum>numTables) {
579  DBG_ERROR(GWEN_LOGDOMAIN, "Table number out of range");
580  *pos=0;
581  return 0;
582  }
583 
584  idIndex=(tableNum*entriesPerTable);
585 
586  for (idx=tableNum; idx<numTables; idx++) {
587  GWEN_IDTABLE64 *idt;
588 
589  idt=GWEN_IdList64_GetTableAt(idl, idx);
590  if (idt) {
591  int i;
592  uint64_t id;
593 
594  if (idx==tableNum) {
595  for (i=tableIdx; i<entriesPerTable; i++) {
596  if (idt->ptrEntries[i]!=0) {
597  id=idt->ptrEntries[i];
598  *pos=idIndex+i+1;
599  return id;
600  }
601  }
602  }
603  else {
604  for (i=0; i<entriesPerTable; i++) {
605  if (idt->ptrEntries[i]!=0) {
606  id=idt->ptrEntries[i];
607  *pos=idIndex+i+1;
608  return id;
609  }
610  }
611  }
612  }
613  idIndex+=entriesPerTable;
614  }
615  *pos=0;
616  }
617 
618  return 0;
619 }
620 
621 
622 
623 int GWEN_IdList64__Sort(GWEN_IDLIST64 *idl, int ascending)
624 {
625  uint64_t entryCount;
626 
627  assert(idl);
628 
629  entryCount=GWEN_IdList64_GetEntryCount(idl);
630 
631  if (entryCount) {
633  uint64_t *ptr;
634  unsigned int i;
635 
636  assert(idl);
637 
638  /* move ids to a temporary list */
639  ptr=(uint64_t *)malloc(sizeof(uint64_t)*entryCount);
640  assert(ptr);
641 
643  for (i=0; i<entryCount; i++) {
644  uint64_t id;
645 
646  if (i==0)
648  else
650  assert(id);
651  ptr[i]=id;
652  } /* for */
654 
655  /* remove all tables (we will add sorted tables later) */
656  GWEN_IdList64_Clear(idl);
657 
658  if (ascending)
659  qsort(ptr, entryCount, sizeof(uint64_t), __compAscending);
660  else
661  qsort(ptr, entryCount, sizeof(uint64_t), __compDescending);
662 
663  /* move back sorted list of ids from temporary list */
664  for (i=0; i<entryCount; i++) {
665  GWEN_IdList64_AddId(idl, ptr[i]);
666  }
667  free(ptr);
668  }
669  return 0;
670 }
671 
672 
673 
675 {
676  return GWEN_IdList64__Sort(idl, 1);
677 }
678 
679 
680 
682 {
683  return GWEN_IdList64__Sort(idl, 0);
684 }
685 
686 
687 
688 int __compAscending(const void *pa, const void *pb)
689 {
690  uint64_t a=*((const uint64_t *)pa);
691  uint64_t b=*((const uint64_t *)pb);
692 
693  if (a<b)
694  return -1;
695  else if (a>b)
696  return 1;
697  else
698  return 0;
699 }
700 
701 
702 
703 int __compDescending(const void *pa, const void *pb)
704 {
705  uint64_t a=*((const uint64_t *)pa);
706  uint64_t b=*((const uint64_t *)pb);
707 
708  if (a<b)
709  return 1;
710  else if (a>b)
711  return -1;
712  else
713  return 0;
714 }
715 
716 
717 
718 
719 
720 
721 
722 /* ------------------------------------------------------------------------------------------------
723  * GWEN_IdList64_Iterator
724  * ------------------------------------------------------------------------------------------------
725  */
726 
727 
729 {
731 
732  assert(idl);
734 
735  it->list=idl;
736 
737  return it;
738 }
739 
740 
741 
743 {
744  if (it) {
745  GWEN_FREE_OBJECT(it);
746  }
747 }
748 
749 
750 
752 {
753  return GWEN_IdList64__GetFirstId(it->list, &(it->nextIndex));
754 }
755 
756 
757 
759 {
760  return GWEN_IdList64__GetNextId(it->list, &(it->nextIndex));
761 }
762 
763 
764 
765 
766 
767 
768 /* ------------------------------------------------------------------------------------------------
769  * GWEN_IdTable64
770  * ------------------------------------------------------------------------------------------------
771  */
772 
773 
774 
775 GWEN_IDTABLE64 *GWEN_IdTable64_new()
776 {
777  GWEN_IDTABLE64 *ft;
778 
779  GWEN_NEW_OBJECT(GWEN_IDTABLE64, ft);
780  ft->refCount=1;
781 
782  return ft;
783 }
784 
785 
786 
787 void GWEN_IdTable64_Attach(GWEN_IDTABLE64 *ft)
788 {
789  assert(ft && ft->refCount);
790  if (ft && ft->refCount) {
791  ft->refCount++;
792  }
793 }
794 
795 
796 
797 void GWEN_IdTable64_free(GWEN_IDTABLE64 *ft)
798 {
799  if (ft) {
800  assert(ft->refCount);
801  if (ft->refCount==1) {
802  ft->refCount=0;
803  free(ft->ptrEntries);
804  GWEN_FREE_OBJECT(ft);
805  }
806  else {
807  ft->refCount--;
808  }
809  }
810 }
811 
812 
813 
814 int GWEN_IdTable64_GetRefCounter(const GWEN_IDTABLE64 *ft)
815 {
816  assert(ft);
817  return ft->refCount;
818 }
819 
820 
821 
822 GWEN_IDTABLE64 *GWEN_IdTable64_dup(const GWEN_IDTABLE64 *ftOrig)
823 {
824  GWEN_IDTABLE64 *ft;
825 
826  assert(ftOrig);
827  assert(ftOrig->refCount);
828  ft=GWEN_IdTable64_new();
829  ft->maxEntries=ftOrig->maxEntries;
830  ft->freeEntries=ftOrig->freeEntries;
831  ft->highestEntry=ftOrig->highestEntry;
832  ft->runtimeFlags=ftOrig->runtimeFlags;
833 
834  /* copy offset entries */
835  if (ftOrig->maxEntries && ftOrig->ptrEntries) {
836  uint64_t offsetArraySize;
837 
838  offsetArraySize=ftOrig->maxEntries*sizeof(uint64_t);
839  ft->ptrEntries=(uint64_t *) malloc(offsetArraySize);
840  assert(ft->ptrEntries);
841  memmove(ft->ptrEntries, ftOrig->ptrEntries, offsetArraySize);
842  }
843 
844  return ft;
845 }
846 
847 
848 
849 GWEN_IDTABLE64 *GWEN_IdTable64_Create(uint64_t maxEntries)
850 {
851  GWEN_IDTABLE64 *ft;
852  uint64_t offsetArraySize;
853  uint64_t *ptr;
854 
855  ft=GWEN_IdTable64_new();
856  ft->maxEntries=maxEntries;
857  ft->freeEntries=maxEntries;
858 
859  offsetArraySize=ft->maxEntries*sizeof(uint64_t);
860 
861  ptr=(uint64_t *) malloc(offsetArraySize);
862  assert(ptr);
863  memset(ptr, 0, offsetArraySize);
865 
866  return ft;
867 }
868 
869 
870 
871 uint64_t GWEN_IdTable64_GetMaxEntries(const GWEN_IDTABLE64 *ft)
872 {
873  assert(ft);
874  assert(ft->refCount);
875  return ft->maxEntries;
876 }
877 
878 
879 
880 uint64_t GWEN_IdTable64_GetFreeEntries(const GWEN_IDTABLE64 *ft)
881 {
882  assert(ft);
883  assert(ft->refCount);
884  return ft->freeEntries;
885 }
886 
887 
888 
889 void GWEN_IdTable64_DecFreeEntries(GWEN_IDTABLE64 *ft)
890 {
891  assert(ft);
892  assert(ft->refCount);
893  if (ft->freeEntries>0)
894  ft->freeEntries--;
895 }
896 
897 
898 
899 uint64_t GWEN_IdTable64_GetHighestEntry(const GWEN_IDTABLE64 *ft)
900 {
901  assert(ft);
902  assert(ft->refCount);
903  return ft->highestEntry;
904 }
905 
906 
907 
908 void GWEN_IdTable64_CheckAndSetHighestEntry(GWEN_IDTABLE64 *ft, uint64_t i)
909 {
910  assert(ft);
911  assert(ft->refCount);
912  if (i>ft->highestEntry)
913  ft->highestEntry=i;
914 }
915 
916 
917 
918 uint64_t *GWEN_IdTable64_GetPtrEntries(const GWEN_IDTABLE64 *ft)
919 {
920  assert(ft);
921  assert(ft->refCount);
922  return ft->ptrEntries;
923 }
924 
925 
926 
927 void GWEN_IdTable64_SetPtrEntries(GWEN_IDTABLE64 *ft, uint64_t *ptr)
928 {
929  assert(ft);
930  assert(ft->refCount);
931  if (ft->ptrEntries && ft->ptrEntries!=ptr)
932  free(ft->ptrEntries);
933  ft->ptrEntries=ptr;
934 }
935 
936 
937 
938 uint32_t GWEN_IdTable64_GetRuntimeFlags(const GWEN_IDTABLE64 *ft)
939 {
940  assert(ft);
941  return ft->runtimeFlags;
942 }
943 
944 
945 
946 void GWEN_IdTable64_AddRuntimeFlags(GWEN_IDTABLE64 *ft, uint32_t i)
947 {
948  assert(ft);
949  ft->runtimeFlags|=i;
950 }
951 
952 
953 
954 /* include tests */
955 #include "idlist64-t.c"
956 
static GWENHYWFAR_CB void _attachToTable(GWEN_SIMPLEPTRLIST *pl, void *p)
static GWEN_IDTABLE64 * GWEN_IdTable64_dup(const GWEN_IDTABLE64 *ftOrig)
Definition: idlist64.c:822
static int __compAscending(const void *pa, const void *pb)
Definition: idlist64.c:688
void * GWEN_SimplePtrList_GetPtrAt(const GWEN_SIMPLEPTRLIST *pl, uint64_t idx)
static void GWEN_IdTable64_SetPtrEntries(GWEN_IDTABLE64 *ft, uint64_t *ptr)
Definition: idlist64.c:927
void GWEN_IdList64_IncIdCounter(GWEN_SIMPLEPTRLIST *pl)
Definition: idlist64.c:168
int GWEN_SimplePtrList_DecUserCounter(GWEN_SIMPLEPTRLIST *pl)
#define GWEN_ERROR_INVALID
Definition: error.h:67
int GWEN_IdList64_HasId(const GWEN_IDLIST64 *idl, uint64_t wantedId)
Definition: idlist64.c:459
static uint64_t GWEN_IdTable64_GetHighestEntry(const GWEN_IDTABLE64 *ft)
Definition: idlist64.c:899
static uint32_t GWEN_IdTable64_GetRuntimeFlags(const GWEN_IDTABLE64 *ft)
Definition: idlist64.c:938
int GWEN_IdList64_DecIdCounter(GWEN_SIMPLEPTRLIST *pl)
Definition: idlist64.c:175
void GWEN_SimplePtrList_SetUserCounter(GWEN_SIMPLEPTRLIST *pl, uint64_t i)
void GWEN_SimplePtrList_IncUserCounter(GWEN_SIMPLEPTRLIST *pl)
GWEN_IDLIST64 * GWEN_IdList64_dup(const GWEN_IDLIST64 *oldList)
Definition: idlist64.c:111
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
static uint64_t GWEN_IdTable64_GetFreeEntries(const GWEN_IDTABLE64 *ft)
Definition: idlist64.c:880
#define GWEN_LOGDOMAIN
Definition: logger.h:35
static int GWEN_IdList64__Sort(GWEN_IDLIST64 *idl, int ascending)
Definition: idlist64.c:623
int GWEN_IdList64_DelId(GWEN_IDLIST64 *idl, uint64_t wantedId)
Definition: idlist64.c:484
#define GWEN_ERROR_BUFFER_OVERFLOW
Definition: error.h:79
int GWEN_IdList64_Sort(GWEN_IDLIST64 *idl)
Definition: idlist64.c:674
void GWEN_IdList64_free(GWEN_IDLIST64 *idl)
Definition: idlist64.c:153
static GWEN_IDTABLE64 * GWEN_IdList64_GetTableAt(const GWEN_IDLIST64 *tl, uint64_t idx)
Definition: idlist64.c:204
void GWEN_IdList64_Iterator_free(GWEN_IDLIST64_ITERATOR *it)
Definition: idlist64.c:742
GWEN_IDLIST64 * GWEN_IdList64_newWithSteps(uint64_t steps)
Definition: idlist64.c:95
int GWEN_SimplePtrList_SetPtrAt(GWEN_SIMPLEPTRLIST *pl, uint64_t idx, void *p)
int64_t GWEN_IdList64_GetLastTablePos(const GWEN_IDLIST64 *idl)
Definition: idlist64.c:232
uint64_t GWEN_IdList64_GetEntryCount(const GWEN_SIMPLEPTRLIST *pl)
Definition: idlist64.c:182
int GWEN_IdList64_SetTableAt(GWEN_IDLIST64 *idl, uint64_t idx, GWEN_IDTABLE64 *t)
Definition: idlist64.c:211
uint64_t GWEN_SimplePtrList_GetUserCounter(const GWEN_SIMPLEPTRLIST *pl)
static int __compDescending(const void *pa, const void *pb)
Definition: idlist64.c:703
GWEN_SIMPLEPTRLIST GWEN_IDLIST64
Definition: idlist64.h:42
static uint64_t GWEN_IdList64__GetNextId(const GWEN_IDLIST64 *idl, uint64_t *pos)
Definition: idlist64.c:565
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
int64_t GWEN_IdList64_GetIdAt(const GWEN_IDLIST64 *idl, uint64_t idx)
Definition: idlist64.c:244
uint64_t GWEN_IdList64_Iterator_GetFirstId(GWEN_IDLIST64_ITERATOR *it)
Definition: idlist64.c:751
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
static uint64_t GWEN_IdTable64_GetMaxEntries(const GWEN_IDTABLE64 *ft)
Definition: idlist64.c:871
GWEN_SIMPLEPTRLIST * GWEN_SimplePtrList_LazyCopy(GWEN_SIMPLEPTRLIST *oldList)
Definition: simpleptrlist.c:88
static GWENHYWFAR_CB void _detachFromTable(GWEN_SIMPLEPTRLIST *pl, void *p)
static void GWEN_IdTable64_free(GWEN_IDTABLE64 *ft)
Definition: idlist64.c:797
void GWEN_SimplePtrList_Clear(GWEN_SIMPLEPTRLIST *pl)
static void GWEN_IdTable64_DecFreeEntries(GWEN_IDTABLE64 *ft)
Definition: idlist64.c:889
static GWEN_IDTABLE64 * GWEN_IdTable64_new()
Definition: idlist64.c:775
struct GWEN_SIMPLEPTRLIST GWEN_SIMPLEPTRLIST
Definition: simpleptrlist.h:38
int GWEN_SimplePtrList_EnsureWritability(GWEN_SIMPLEPTRLIST *pl)
GWEN_IDLIST64_ITERATOR * GWEN_IdList64_Iterator_new(const GWEN_IDLIST64 *idl)
Definition: idlist64.c:728
static void GWEN_IdTable64_Attach(GWEN_IDTABLE64 *ft)
Definition: idlist64.c:787
int GWEN_SimplePtrList_GetUserIntData(const GWEN_SIMPLEPTRLIST *pl)
#define GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS
Definition: simpleptrlist.h:33
static GWEN_IDTABLE64 * GWEN_IdTable64_Create(uint64_t maxEntries)
Definition: idlist64.c:849
void GWEN_SimplePtrList_Attach(GWEN_SIMPLEPTRLIST *pl)
static int64_t GWEN_IdList64_AddTable(GWEN_IDLIST64 *idl, GWEN_IDTABLE64 *t)
Definition: idlist64.c:218
static void GWEN_IdTable64_CheckAndSetHighestEntry(GWEN_IDTABLE64 *ft, uint64_t i)
Definition: idlist64.c:908
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
int GWEN_IdList64_GetTableMaxEntries(const GWEN_IDLIST64 *idl)
Definition: idlist64.c:190
void GWEN_SimplePtrList_SetUserIntData(GWEN_SIMPLEPTRLIST *pl, int i)
static uint64_t * GWEN_IdTable64_GetPtrEntries(const GWEN_IDTABLE64 *ft)
Definition: idlist64.c:918
void GWEN_SimplePtrList_AddFlags(GWEN_SIMPLEPTRLIST *pl, uint32_t f)
GWEN_IDLIST64 * GWEN_IdList64_LazyCopy(GWEN_IDLIST64 *oldList)
Definition: idlist64.c:197
GWEN_SIMPLEPTRLIST * GWEN_SimplePtrList_new(uint64_t startEntries, uint64_t steps)
Definition: simpleptrlist.c:71
GWEN_SIMPLEPTRLIST_FREEOBJECT_FN GWEN_SimplePtrList_SetFreeObjectFn(GWEN_SIMPLEPTRLIST *pl, GWEN_SIMPLEPTRLIST_FREEOBJECT_FN fn)
void GWEN_IdList64_Clear(GWEN_IDLIST64 *idl)
Definition: idlist64.c:160
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
int GWEN_IdTable64_GetRefCounter(const GWEN_IDTABLE64 *ft)
Definition: idlist64.c:814
uint64_t GWEN_SimplePtrList_GetUsedEntries(const GWEN_SIMPLEPTRLIST *pl)
void GWEN_IdList64_Attach(GWEN_IDLIST64 *idl)
Definition: idlist64.c:146
GWEN_IDLIST64 * GWEN_IdList64_new()
Definition: idlist64.c:88
GWEN_SIMPLEPTRLIST_ATTACHOBJECT_FN GWEN_SimplePtrList_SetAttachObjectFn(GWEN_SIMPLEPTRLIST *pl, GWEN_SIMPLEPTRLIST_ATTACHOBJECT_FN fn)
uint64_t GWEN_IdList64_Iterator_GetNextId(GWEN_IDLIST64_ITERATOR *it)
Definition: idlist64.c:758
#define GWEN_ERROR_INTERNAL
Definition: error.h:125
int64_t GWEN_SimplePtrList_AddPtr(GWEN_SIMPLEPTRLIST *pl, void *p)
static uint64_t GWEN_IdList64__GetFirstId(const GWEN_IDLIST64 *idl, uint64_t *pos)
Definition: idlist64.c:533
#define GWEN_ERROR_NO_DATA
Definition: error.h:94
#define GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS
Definition: simpleptrlist.h:34
uint64_t GWEN_IdList64_GetUsedTables(const GWEN_IDLIST64 *idl)
Definition: idlist64.c:225
struct GWEN_IDLIST64_ITERATOR GWEN_IDLIST64_ITERATOR
Definition: idlist64.h:43
int64_t GWEN_IdList64_AddId(GWEN_IDLIST64 *idl, uint64_t entry)
Definition: idlist64.c:335
#define GWEN_UNUSED
void GWEN_SimplePtrList_free(GWEN_SIMPLEPTRLIST *pl)
int GWEN_IdList64_ReverseSort(GWEN_IDLIST64 *idl)
Definition: idlist64.c:681
static void GWEN_IdTable64_AddRuntimeFlags(GWEN_IDTABLE64 *ft, uint32_t i)
Definition: idlist64.c:946