cdt.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /**
  2. * @file
  3. * @brief container data types API
  4. * @ingroup public_apis
  5. *
  6. * **CDT** manages run-time dictionaries using standard container data types:
  7. * unordered set/multiset, ordered set/multiset, list, stack, and queue.
  8. *
  9. * [man 3 cdt](https://graphviz.org/pdf/cdt.3.pdf)
  10. *
  11. */
  12. #pragma once
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. /* Public interface for the dictionary library
  17. **
  18. ** Written by Kiem-Phong Vo
  19. */
  20. #define CDT_VERSION 20050420L
  21. #include <stddef.h> /* size_t */
  22. #include <string.h>
  23. #ifdef GVDLL
  24. #ifdef EXPORT_CDT
  25. #define CDT_API __declspec(dllexport)
  26. #else
  27. #define CDT_API __declspec(dllimport)
  28. #endif
  29. #endif
  30. #ifndef CDT_API
  31. #define CDT_API /* nothing */
  32. #endif
  33. typedef struct _dtlink_s Dtlink_t;
  34. typedef struct _dthold_s Dthold_t;
  35. typedef struct _dtdisc_s Dtdisc_t;
  36. typedef struct _dtmethod_s Dtmethod_t;
  37. typedef struct _dtdata_s Dtdata_t;
  38. typedef struct _dt_s Dt_t;
  39. typedef struct _dt_s Dict_t; /* for libdict compatibility */
  40. typedef struct _dtstat_s Dtstat_t;
  41. typedef void* (*Dtsearch_f)(Dt_t*,void*,int);
  42. typedef void* (*Dtmake_f)(void*,Dtdisc_t*);
  43. typedef void (*Dtfree_f)(void *);
  44. typedef int (*Dtcompar_f)(void *,void *);
  45. struct _dtlink_s
  46. { Dtlink_t* right; /* right child */
  47. union
  48. { unsigned int _hash; /* hash value */
  49. Dtlink_t* _left; /* left child */
  50. } hl;
  51. };
  52. /* private structure to hold an object */
  53. struct _dthold_s
  54. { Dtlink_t hdr; /* header */
  55. void* obj; /* user object */
  56. };
  57. /* method to manipulate dictionary structure */
  58. struct _dtmethod_s
  59. { Dtsearch_f searchf; /* search function */
  60. int type; /* type of operation */
  61. };
  62. /* stuff that may be in shared memory */
  63. struct _dtdata_s
  64. { int type; /* type of dictionary */
  65. Dtlink_t* here; /* finger to last search element */
  66. union
  67. { Dtlink_t** _htab; /* hash table */
  68. Dtlink_t* _head; /* linked list */
  69. } hh;
  70. int ntab; /* number of hash slots */
  71. int size; /* number of objects */
  72. int loop; /* number of nested loops */
  73. };
  74. /* structure to hold methods that manipulate an object */
  75. struct _dtdisc_s
  76. { int key; /* where the key begins in an object */
  77. int size; /* key size and type */
  78. int link; /* offset to Dtlink_t field */
  79. Dtmake_f makef; /* object constructor */
  80. Dtfree_f freef; /* object destructor */
  81. Dtcompar_f comparf;/* to compare two objects */
  82. };
  83. #define DTDISC(dc, ky, sz, lk, mkf, frf, cmpf) \
  84. ( (dc)->key = (ky), (dc)->size = (sz), (dc)->link = (lk), \
  85. (dc)->makef = (mkf), (dc)->freef = (frf), \
  86. (dc)->comparf = (cmpf) )
  87. /* the dictionary structure itself */
  88. struct _dt_s
  89. { Dtsearch_f searchf;/* search function */
  90. Dtdisc_t* disc; /* method to manipulate objs */
  91. Dtdata_t* data; /* sharable data */
  92. Dtmethod_t* meth; /* dictionary method */
  93. int nview; /* number of parent view dictionaries */
  94. Dt_t* view; /* next on viewpath */
  95. Dt_t* walk; /* dictionary being walked */
  96. void* user; /* for user's usage */
  97. };
  98. /* structure to get status of a dictionary */
  99. struct _dtstat_s
  100. { int dt_meth; /* method type */
  101. int dt_size; /* number of elements */
  102. size_t dt_n; // number of chains or levels
  103. size_t dt_max; // max size of a chain or a level
  104. size_t* dt_count; // counts of chains or levels by size
  105. };
  106. /* supported storage methods */
  107. #define DT_SET 0000001 /* set with unique elements */
  108. #define DT_OSET 0000004 /* ordered set (self-adjusting tree) */
  109. #define DT_OBAG 0000010 /* ordered multiset */
  110. #define DT_QUEUE 0000100 /* queue: insert at top, delete at tail */
  111. #define DT_METHODS 0000377 /* all currently supported methods */
  112. /* types of search */
  113. #define DT_INSERT 0000001 /* insert object if not found */
  114. #define DT_DELETE 0000002 /* delete object if found */
  115. #define DT_SEARCH 0000004 /* look for an object */
  116. #define DT_NEXT 0000010 /* look for next element */
  117. #define DT_PREV 0000020 /* find previous element */
  118. #define DT_RENEW 0000040 /* renewing an object */
  119. #define DT_CLEAR 0000100 /* clearing all objects */
  120. #define DT_FIRST 0000200 /* get first object */
  121. #define DT_LAST 0000400 /* get last object */
  122. #define DT_MATCH 0001000 /* find object matching key */
  123. #define DT_VSEARCH 0002000 /* search using internal representation */
  124. #define DT_DETACH 0010000 /* detach an object from the dictionary */
  125. CDT_API extern Dtmethod_t* Dtset; ///< set with unique elements
  126. CDT_API extern Dtmethod_t* Dtoset; ///< ordered set (self-adjusting tree)
  127. CDT_API extern Dtmethod_t* Dtobag; ///< ordered multiset
  128. CDT_API extern Dtmethod_t* Dtqueue; ///< queue: insert at top, delete at tail
  129. CDT_API extern Dtmethod_t* Dttree;
  130. CDT_API extern Dtmethod_t _Dttree;
  131. CDT_API extern Dtmethod_t _Dtqueue;
  132. CDT_API Dt_t* dtopen(Dtdisc_t*, Dtmethod_t*);
  133. CDT_API int dtclose(Dt_t*);
  134. CDT_API Dt_t* dtview(Dt_t*, Dt_t*);
  135. CDT_API Dtdisc_t* dtdisc(Dt_t *dt, Dtdisc_t*);
  136. CDT_API Dtmethod_t* dtmethod(Dt_t*, Dtmethod_t*);
  137. CDT_API Dtlink_t* dtflatten(Dt_t*);
  138. CDT_API Dtlink_t* dtextract(Dt_t*);
  139. CDT_API int dtrestore(Dt_t*, Dtlink_t*);
  140. CDT_API int dtwalk(Dt_t*, int(*)(void*,void*), void*);
  141. CDT_API void* dtrenew(Dt_t*, void*);
  142. CDT_API int dtsize(Dt_t*);
  143. CDT_API int dtstat(Dt_t*, Dtstat_t*, int);
  144. CDT_API unsigned int dtstrhash(void*, int);
  145. /* internal functions for translating among holder, object and key */
  146. #define _DT(dt) ((Dt_t*)(dt))
  147. #define _DTDSC(dc,ky,sz,lk,cmpf) \
  148. (ky = dc->key, sz = dc->size, lk = dc->link, cmpf = dc->comparf)
  149. #define _DTLNK(o,lk) ((Dtlink_t*)((char*)(o) + lk) )
  150. #define _DTOBJ(e,lk) (lk < 0 ? ((Dthold_t*)(e))->obj : (void*)((char*)(e) - lk) )
  151. #define _DTKEY(o,ky,sz) (void*)(sz < 0 ? *((char**)((char*)(o)+ky)) : ((char*)(o)+ky))
  152. #define _DTCMP(k1, k2, cmpf, sz) \
  153. (cmpf ? (cmpf)(k1, k2) : \
  154. (sz <= 0 ? strcmp(k1,k2) : memcmp(k1,k2,(size_t)sz)) )
  155. #define dtlink(d,e) (((Dtlink_t*)(e))->right)
  156. #define dtobj(d,e) _DTOBJ((e), _DT(d)->disc->link)
  157. #define dtfinger(d) (_DT(d)->data->here ? dtobj((d),_DT(d)->data->here):(void*)(0))
  158. #define dtfirst(d) (*(_DT(d)->searchf))((d),(void*)(0),DT_FIRST)
  159. #define dtnext(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_NEXT)
  160. #define dtlast(d) (*(_DT(d)->searchf))((d),(void*)(0),DT_LAST)
  161. #define dtprev(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_PREV)
  162. #define dtsearch(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_SEARCH)
  163. #define dtmatch(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_MATCH)
  164. #define dtinsert(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_INSERT)
  165. #define dtdelete(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_DELETE)
  166. #define dtdetach(d,o) (*(_DT(d)->searchf))((d),(void*)(o),DT_DETACH)
  167. #define dtclear(d) (*(_DT(d)->searchf))((d),(void*)(0),DT_CLEAR)
  168. #define DT_PRIME 17109811 /* 2#00000001 00000101 00010011 00110011 */
  169. /**
  170. * @dir lib/cdt
  171. * @brief container data types, API cdt.h
  172. *
  173. * [man 3 cdt](https://graphviz.org/pdf/cdt.3.pdf)
  174. *
  175. */
  176. #ifdef __cplusplus
  177. }
  178. #endif