1LIBCDT(3)                  Library Functions Manual                  LIBCDT(3)
2
3
4

NAME

6       Cdt - container data types
7

SYNOPSIS

9       #include <cdt.h>
10
11   DICTIONARY TYPES
12       Void_t*;
13       Dt_t;
14       Dtdisc_t;
15       Dtmethod_t;
16       Dtlink_t;
17       Dtstat_t;
18
19   DICTIONARY CONTROL
20       Dt_t*       dtopen(const Dtdisc_t* disc, const Dtmethod_t* meth);
21       int         dtclose(Dt_t* dt);
22       void        dtclear(dt);
23       Dtmethod_t* dtmethod(Dt_t* dt, const Dtmethod_t* meth);
24       Dtdisc_t*   dtdisc(Dt_t* dt, const Dtdisc_t* disc, int type);
25       Dt_t*       dtview(Dt_t* dt, Dt_t* view);
26       int         dttreeset(Dt_t* dt, int minp, int balance);
27
28   STORAGE METHODS
29       Dtmethod_t* Dtset;
30       Dtmethod_t* Dtbag;
31       Dtmethod_t* Dtoset;
32       Dtmethod_t* Dtobag;
33       Dtmethod_t* Dtlist;
34       Dtmethod_t* Dtstack;
35       Dtmethod_t* Dtqueue;
36       Dtmethod_t* Dtdeque;
37
38   DISCIPLINE
39       #define DTOFFSET(struct_s,member)
40       #define DTDISC(disc,key,size,link,makef,freef,comparf,hashf,memoryf,eventf)
41       typedef Void_t*      (*Dtmake_f)(Dt_t*, Void_t*, Dtdisc_t*);
42       typedef void         (*Dtfree_f)(Dt_t*, Void_t*, Dtdisc_t*);
43       typedef int          (*Dtcompar_f)(Dt_t*, Void_t*, Void_t*, Dtdisc_t*);
44       typedef unsigned int (*Dthash_f)(Dt_t*, Void_t*, Dtdisc_t*);
45       typedef Void_t*      (*Dtmemory_f)(Dt_t*, Void_t*, size_t, Dtdisc_t*);
46       typedef int          (*Dtevent_f)(Dt_t*, int, Void_t*, Dtdisc_t*);
47
48   OBJECT OPERATIONS
49       Void_t*   dtinsert(Dt_t* dt, Void_t* obj);
50       Void_t*   dtappend(Dt_t* dt, Void_t* obj);
51       Void_t*   dtdelete(Dt_t* dt, Void_t* obj);
52       Void_t*   dtattach(Dt_t* dt, Void_t* obj);
53       Void_t*   dtdetach(Dt_t* dt, Void_t* obj);
54       Void_t*   dtsearch(Dt_t* dt, Void_t* obj);
55       Void_t*   dtmatch(Dt_t* dt, Void_t* key);
56       Void_t*   dtfirst(Dt_t* dt);
57       Void_t*   dtnext(Dt_t* dt, Void_t* obj);
58       Void_t*   dtlast(Dt_t* dt);
59       Void_t*   dtprev(Dt_t* dt, Void_t* obj);
60       Void_t*   dtfinger(Dt_t* dt);
61       Void_t*   dtrenew(Dt_t* dt, Void_t* obj);
62       int       dtwalk(Dt_t* dt, int (*userf)(Dt_t*, Void_t*, Void_t*), Void_t*);
63       Dtlink_t* dtflatten(Dt_t* dt);
64       Dtlink_t* dtlink(Dt_t*, Dtlink_t* link);
65       Void_t*   dtobj(Dt_t* dt, Dtlink_t* link);
66       Dtlink_t* dtextract(Dt_t* dt);
67       int       dtrestore(Dt_t* dt, Dtlink_t* link);
68
69       #define   DTTREESEARCH(Dt_t* dt, Void_t* obj, action)
70       #define   DTTREEMATCH(Dt_t* dt, Void_t* key, action)
71
72   DICTIONARY STATUS
73       Dt_t*     dtvnext(Dt_t* dt);
74       int       dtvcount(Dt_t* dt);
75       Dt_t*     dtvhere(Dt_t* dt);
76       int       dtsize(Dt_t* dt);
77       int       dtstat(Dt_t* dt, Dtstat_t*, int all);
78
79   HASH FUNCTIONS
80       unsigned int dtstrhash(unsigned int h, char* str, int n);
81       unsigned int dtcharhash(unsigned int h, unsigned char c);
82

DESCRIPTION

84       Cdt  manages run-time dictionaries using standard container data types:
85       unordered set/multiset, ordered set/multiset, list, stack, and queue.
86
87   DICTIONARY TYPES
88     Void_t*
89       This type is used to pass objects between  Cdt  and  application  code.
90       Void_t  is defined as void for ANSI-C and C++ and char for other compi‐
91       lation environments.
92
93     Dt_t
94       This is the type of a dictionary handle.
95
96     Dtdisc_t
97       This defines the type of a discipline structure which describes  object
98       lay-out and manipulation functions.
99
100     Dtmethod_t
101       This defines the type of a container method.
102
103     Dtlink_t
104       This is the type of a dictionary object holder (see dtdisc().)
105
106     Dtstat_t
107       This  is  the  type of a structure to return dictionary statistics (see
108       dtstat().)
109
110   DICTIONARY CONTROL
111     Dt_t* dtopen(const Dtdisc_t* disc, const Dtmethod_t* meth)
112       This creates a new dictionary.   disc  is  a  discipline  structure  to
113       describe   object   format.   meth  specifies  a  manipulation  method.
114       dtopen() returns the new dictionary or NULL on  error.   See  also  the
115       events DT_OPEN and DT_ENDOPEN below.
116
117     int dtclose(Dt_t* dt)
118       This  deletes  dt  and its objects.  Note that dtclose() fails if dt is
119       being viewed by some  other  dictionaries  (see  dtview()).   dtclose()
120       returns 0 on success and -1 on error.  See also the events DT_CLOSE and
121       DT_ENDCLOSE below.
122
123     void dtclear(Dt_t* dt)
124       This deletes all objects in dt without closing dt.
125
126     Dtmethod_t dtmethod(Dt_t* dt, const Dtmethod_t* meth)
127       If meth is NULL, dtmethod() returns the current method.  Otherwise,  it
128       changes  the  storage  method  of dt to meth.  Object order remains the
129       same during a method switch among Dtlist, Dtstack, Dtqueue and Dtdeque.
130       Switching  to  and from Dtset/Dtbag and Dtoset/Dtobag may cause objects
131       to be rehashed, reordered, or removed as the case requires.  dtmethod()
132       returns the previous method or NULL on error.
133
134     Dtdisc_t* dtdisc(Dt_t* dt, const Dtdisc_t* disc, int type)
135       If  disc  is NULL, dtdisc() returns the current discipline.  Otherwise,
136       it changes the discipline of dt to  disc.   Objects  may  be  rehashed,
137       reordered,  or removed as appropriate.  type can be any bit combination
138       of DT_SAMECMP and DT_SAMEHASH.  DT_SAMECMP means that objects will com‐
139       pare  exactly the same as before thus obviating the need for reordering
140       or removing new duplicates.  DT_SAMEHASH  means  that  hash  values  of
141       objects  remain  the  same thus obviating the need to rehash.  dtdisc()
142       returns the previous discipline on success and NULL on error.
143
144     Dt_t* dtview(Dt_t* dt, Dt_t* view)
145       A viewpath allows a search or walk starting from a dictionary  to  con‐
146       tinue  to  another.  dtview() first terminates any current view from dt
147       to another dictionary.  Then, if view is NULL, dtview returns the  ter‐
148       minated  view  dictionary.   If view is not NULL, a viewpath from dt to
149       view is established.  dtview() returns dt on success and NULL on error.
150
151       It is an error to have dictionaries on a viewpath with different  stor‐
152       age  methods.   In  addition, dictionaries on the same view path should
153       treat objects in a consistent manner  with  respect  to  comparison  or
154       hashing.  If not, undefined behaviors may result.
155
156     int dttreeset(Dt_t* dt, int minp, int balance)
157       This  function  only  applies to dictionaries operated under the method
158       Dtoset which uses top-down splay trees (see below).  It  returns  0  on
159       success and -1 on error.
160
161       minp:  This  parameter  defines the minimum path length before a search
162              path is adjusted.  For example, minp equal  0  would  mean  that
163              search paths are always adjusted.  If minp is negative, the min‐
164              imum search path is internally computed based on a  function  of
165              the current dictionary size. This computed value is such that if
166              the tree is balanced, it will never require adjusting.
167
168       balance:
169              If this is non-zero, the tree will be made balanced.
170
171   STORAGE METHODS
172       Storage methods are of type Dtmethod_t*.  Cdt  supports  the  following
173       methods:
174
175     Dtoset
176     Dtobag
177       Objects are ordered by comparisons.  Dtoset keeps unique objects.  Dto‐
178       bag allows repeatable objects.
179
180     Dtset
181     Dtbag
182       Objects are unordered.   Dtset  keeps  unique  objects.   Dtbag  allows
183       repeatable  objects  and always keeps them together (note the effect on
184       dictionary walking.)  These methods use a hash table with  chaining  to
185       manage  the  objects.   See  also the event DT_HASHSIZE below on how to
186       manage hash table resizing when objects are inserted.
187
188     Dtlist
189       Objects are kept in a list.  The call dtinsert() inserts a  new  object
190       in  front of the current object (see dtfinger()) if it is defined or at
191       list front if no current object is defined.  Similarly, the call  dtap‐
192       pend()  appends  a new object after the current object (see dtfinger())
193       if it is defined or at list end if no current object is defined.
194
195     Dtdeque
196       Objects are kept in a deque. This is  similar  to  Dtlist  except  that
197       objects  are  always  inserted at the front and appended at the tail of
198       the list.
199
200     Dtstack
201       Objects are kept in a stack,  i.e.,  in  reverse  order  of  insertion.
202       Thus, the last object inserted is at stack top and will be the first to
203       be deleted.
204
205     Dtqueue
206       Objects are kept in a queue, i.e., in order of  insertion.   Thus,  the
207       first  object  inserted  is  at  queue head and will be the first to be
208       deleted.
209
210   DISCIPLINE
211       Object format and associated management functions are  defined  in  the
212       type Dtdisc_t:
213           typedef struct
214           { int        key, size;
215             int        link;
216             Dtmake_f   makef;
217             Dtfree_f   freef;
218             Dtcompar_f comparf;
219             Dthash_f   hashf;
220             Dtmemory_f memoryf;
221             Dtevent_f  eventf;
222           } Dtdisc_t;
223
224     int key, size
225       Each  object  obj  is identified by a key used for object comparison or
226       hashing.  key should be non-negative and defines an  offset  into  obj.
227       If  size is negative, the key is a null-terminated string with starting
228       address *(Void_t**)((char*)obj+key).  If size is zero,  the  key  is  a
229       null-terminated string with starting address (Void_t*)((char*)obj+key).
230       Finally, if size is positive, the key is a byte array  of  length  size
231       starting at (Void_t*)((char*)obj+key).
232
233     int link
234       Let  obj  be  an  object to be inserted into dt as discussed below.  If
235       link is negative, an internally allocated object holder is used to hold
236       obj.  Otherwise,  obj  should  have  a Dtlink_t structure embedded link
237       bytes into it, i.e., at address (Dtlink_t*)((char*)obj+link).
238
239     Void_t* (*makef)(Dt_t* dt, Void_t* obj, Dtdisc_t* disc)
240       If makef is not NULL, dtinsert(dt,obj) or dtappend() will  call  it  to
241       make  a  copy of obj suitable for insertion into dt.  If makef is NULL,
242       obj itself will be inserted into dt.
243
244     void (*freef)(Dt_t* dt, Void_t* obj, Dtdisc_t* disc)
245       If not NULL, freef is used to destroy data associated with obj.
246
247   int (*comparf)(Dt_t* dt, Void_t* key1, Void_t* key2, Dtdisc_t* disc)
248       If not NULL, comparf is used to compare two  keys.   Its  return  value
249       should  be <0, =0, or >0 to indicate whether key1 is smaller, equal to,
250       or larger than key2.  All  three  values  are  significant  for  method
251       Dtoset  and Dtobag.  For other methods, a zero value indicates equality
252       and a non-zero value indicates inequality.  If (*comparf)() is NULL, an
253       internal  function  is  used  to  compare  the  keys  as defined by the
254       Dtdisc_t.size field.
255
256     unsigned int (*hashf)(Dt_t* dt, Void_t* key, Dtdisc_t* disc)
257       If not NULL, hashf is used to compute the hash value  of  key.   It  is
258       required  that keys compared equal will also have same hash values.  If
259       hashf is NULL, an internal function is used to hash the key as  defined
260       by the Dtdisc_t.size field.
261
262     Void_t* (*memoryf)(Dt_t* dt, Void_t* addr, size_t size, Dtdisc_t* disc)
263       If not NULL, memoryf is used to allocate and free memory.  When addr is
264       NULL, a memory segment of size size is requested.  If addr is not  NULL
265       and size is zero, addr is to be freed.  If addr is not NULL and size is
266       positive, addr is to be resized to the given size.  If memoryf is NULL,
267       malloc(3) is used.
268
269     int (*eventf)(Dt_t* dt, int type, Void_t* data, Dtdisc_t* disc)
270       If not NULL, eventf announces various events.  Each event may have par‐
271       ticular handling of the return values  from  eventf.   But  a  negative
272       return value typically means failure.  Following are the events:
273
274       DT_OPEN:
275              dt  is  being  opened.   If eventf returns negative, the opening
276              process terminates with failure.  If eventf  returns  zero,  the
277              opening process proceeds in a default manner.  A positive return
278              value indicates special treatment  of  memory  as  follows.   If
279              *(Void_t**)data  is  set to point to some memory segment as dis‐
280              cussed in memoryf, that segment of memory is used to  start  the
281              dictionary.  If  *(Void_t**)data  is  NULL, all memory including
282              that of the dictionary handle itself will be allocated via memo‐
283              ryf.
284
285       DT_ENDOPEN:
286              This  event  announces  that  dtopen() has successfully opened a
287              dictionary and is about to return. The data argument  of  eventf
288              should be the new dictionary handle itself.
289
290       DT_CLOSE:
291              dt  is about to be closed. If eventf returns negative, the clos‐
292              ing process stops immediately and dtclose() returns -1.  Objects
293              in  the dictionary are deleted only if eventf returns zero.  The
294              dictionary handle itself is processed as  follows.   If  it  was
295              allocated  via  malloc(), it will be freed.  If it was allocated
296              via memoryf (see dtopen()) and eventf returns 0, a call to memo‐
297              ryf  will  be  issued to attempt freeing the handle.  Otherwise,
298              nothing will be done to its memory.
299
300              As should be clear from their description,  the  events  DT_OPEN
301              and  DT_CLOSE are designed to be used along with memoryf to man‐
302              age the allocation and deallocation  of  dictionary  and  object
303              memory  across dictionaries. In fact, they can be used to manage
304              dictionaries based on shared and/or persistent memory.
305
306       DT_ENDCLOSE:
307              This event announces that dtclose() has  successfully  closed  a
308              dictionary and is about to return.
309
310       DT_DISC:
311              The  discipline  of  dt  is  being changed to a new one given in
312              (Dtdisc_t*)data.
313
314       DT_METH:
315              The method of dt  is  being  changed  to  a  new  one  given  in
316              (Dtmethod_t*)data.
317
318       DT_HASHSIZE:
319              The  hash table (for Dtset and Dtbag) is being resized.  In this
320              case, *(int*)data has the current size of the table.  The appli‐
321              cation  can set the new table size by first changing *(int*)data
322              to the desired size, then return a positive value.  The applica‐
323              tion can also fix the table size at the current value forever by
324              setting *(int*)data to a negative value,  then  again  return  a
325              positive  value. A non-positive return value from the event han‐
326              dling function means that Cdt will be responsible  for  choosing
327              the hash table size.
328
329   #define DTOFFSET(struct_s,member)
330       This  macro  function  computes  the offset of member from the start of
331       structure struct_s. It is useful for getting the offset of  a  Dtlink_t
332       embedded inside an object.
333
334   #define DTDISC(disc,key,size,link,makef,freef,comparf,hashf,memoryf,eventf)
335       This  macro function initializes the discipline pointed to by disc with
336       the given values.
337
338   OBJECT OPERATIONS
339     Void_t* dtinsert(Dt_t* dt, Void_t* obj)
340     Void_t* dtappend(Dt_t* dt, Void_t* obj)
341       These functions add an object prototyped by obj  into  dt.   dtinsert()
342       and  dtappend()  perform  the  same function for all methods except for
343       Dtlist. See Dtlist for details.  If there is an existing object  in  dt
344       matching  obj and the storage method is Dtset or Dtoset, dtinsert() and
345       dtappend() will simply return the matching object.   Otherwise,  a  new
346       object  is inserted according to the method in use.  See Dtdisc_t.makef
347       for object construction.  The new object or a matching object as  noted
348       will be returned on success while NULL is returned on error.
349
350     Void_t* dtdelete(Dt_t* dt, Void_t* obj)
351       If  obj  is NULL, methods Dtstack and Dtqueue delete respectively stack
352       top or queue head while other methods do nothing.  If obj is not  NULL,
353       there  are two cases.  If the method in use is not Dtbag or Dtobag, the
354       first object matching obj is deleted.  On the other hand, if the method
355       in  use  is  Dtbag or Dtobag, the library check to see if obj is in the
356       dictionary and delete it.  If obj is not in the dictionary, some object
357       matching  it  will  be deleted.  See Dtdisc_t.freef for object destruc‐
358       tion.  dtdelete() returns the deleted object (even if  it  was  deallo‐
359       cated) or NULL on error.
360
361     Void_t* dtattach(Dt_t* dt, Void_t* obj)
362       This  function is similar to dtinsert() but obj itself will be inserted
363       into dt even if a discipline function makef is defined.
364
365     Void_t* dtdetach(Dt_t* dt, Void_t* obj)
366       This function is similar to dtdelete() but the  object  to  be  deleted
367       from dt will not be freed (via the discipline freef function).
368
369     Void_t* dtsearch(Dt_t* dt, Void_t* obj)
370     Void_t* dtmatch(Dt_t* dt, Void_t* key)
371       These  functions  find  an object matching obj or key either from dt or
372       from some dictionary accessible from dt via a viewpath (see  dtview().)
373       dtsearch() and dtmatch() return the matching object or NULL on failure.
374
375     Void_t* dtfirst(Dt_t* dt)
376     Void_t* dtnext(Dt_t* dt, Void_t* obj)
377       dtfirst()  returns the first object in dt.  dtnext() returns the object
378       following obj.  Objects are ordered based on the storage method in use.
379       For  Dtoset and Dtobag, objects are ordered by object comparisons.  For
380       Dtstack, objects are  ordered  in  reverse  order  of  insertion.   For
381       Dtqueue,  objects  are  ordered  in  order  of  insertion.  For Dtlist,
382       objects are ordered by list position.  For Dtset and Dtbag, objects are
383       ordered  by  some internal order (more below).  Thus, objects in a dic‐
384       tionary or a viewpath can be walked using a for(;;) loop as below.
385           for(obj = dtfirst(dt); obj; obj = dtnext(dt,obj))
386       When a dictionary uses Dtset or Dtbag, the object order  is  determined
387       upon  a  call to dtfirst()/dtlast().  This order is frozen until a call
388       dtnext()/dtprev() returns NULL or when these same functions are  called
389       with a NULL object argument.  It is important that a dtfirst()/dtlast()
390       call be balanced by a  dtnext()/dtprev()  call  as  described.   Nested
391       loops  will require multiple balancing, once per loop.  If loop balanc‐
392       ing is not done carefully, either performance is degraded or unexpected
393       behaviors may result.
394
395     Void_t* dtlast(Dt_t* dt)
396     Void_t* dtprev(Dt_t* dt, Void_t* obj)
397       dtlast()  and  dtprev()  are  like  dtfirst()  and dtnext() but work in
398       reverse order.  Note that dictionaries on a viewpath are  still  walked
399       in order but objects in each dictionary are walked in reverse order.
400
401     Void_t* dtfinger(Dt_t* dt)
402       This  function  returns  the current object of dt, if any.  The current
403       object is defined  after  a  successful  call  to  one  of  dtsearch(),
404       dtmatch(),  dtinsert(), dtfirst(), dtnext(), dtlast(), or dtprev().  As
405       a side effect of this implementation of Cdt, when a dictionary is based
406       on  Dtoset  and Dtobag, the current object is always defined and is the
407       root of the tree.
408
409     Void_t* dtrenew(Dt_t* dt, Void_t* obj)
410       This function repositions and perhaps rehashes an object obj after  its
411       key  has  been  changed.   dtrenew()  only  works if obj is the current
412       object (see dtfinger()).
413
414     dtwalk(Dt_t* dt, int (*userf)(Dt_t*, Void_t*, Void_t*), Void_t* data)
415       This function calls (*userf)(walk,obj,data) on each object  in  dt  and
416       other dictionaries viewable from it.  walk is the dictionary containing
417       obj.  If userf() returns a <0 value, dtwalk()  terminates  and  returns
418       the same value.  dtwalk() returns 0 on completion.
419
420     Dtlink_t* dtflatten(Dt_t* dt)
421     Dtlink_t* dtlink(Dt_t* dt, Dtlink_t* link)
422     Void_t* dtobj(Dt_t* dt, Dtlink_t* link)
423       Using  dtfirst()/dtnext() or dtlast()/dtprev() to walk a single dictio‐
424       nary can incur significant cost due to function calls.   For  efficient
425       walking  of  a single directory (i.e., no viewpathing), dtflatten() and
426       dtlink() can be used.  Objects in dt are made into a  linked  list  and
427       walked as follows:
428           for(link = dtflatten(dt); link; link = dtlink(dt,link) )
429
430       Note  that  dtflatten()  returns a list of type Dtlink_t*, not Void_t*.
431       That is, it returns a dictionary holder  pointer,  not  a  user  object
432       pointer  (although  both  are  the same if the discipline field link is
433       zero.)  The macro  function  dtlink()  returns  the  dictionary  holder
434       object  following  link.  The macro function dtobj(dt,link) returns the
435       user object associated with link, Beware that the flattened object list
436       is unflattened on any dictionary operations other than dtlink().
437
438     Dtlink_t* dtextract(Dt_t* dt)
439     int dtrestore(Dt_t* dt, Dtlink_t* link)
440       dtextract()  extracts  all  objects  from dt and makes it appear empty.
441       dtrestore() repopulates dt with objects previously obtained  via  dtex‐
442       tract().   dtrestore()  will  fail if dt is not empty.  These functions
443       can be used to share a same dt handle among many sets of objects.  They
444       are useful to reduce dictionary overhead in an application that creates
445       many concurrent dictionaries.  It is important that the same discipline
446       and  method  are  in use at both extraction and restoration. Otherwise,
447       undefined behaviors may result.
448
449     #define   DTTREESEARCH(Dt_t* dt, Void_t* obj, action)
450     #define   DTTREEMATCH(Dt_t* dt, Void_t* key, action)
451       These macro functions are analogues of  dtsearch()  and  dtmatch()  but
452       they  can  only  be used on a dictionary based on a binary search tree,
453       i.e., Dtoset or Dtobag.
454
455       obj or key:
456              These are used to find a matching object. If there is no  match,
457              the result is NULL.
458
459       action:
460              The  matching  object o (which may be NULL) will be processed as
461              follow:
462
463                  action (o);
464
465              Since action is used verbatim, it can be  any  C  code  fragment
466              combinable with (o) to form a syntactically correct C statement.
467              For example, suppose that the matching object is an integer, the
468              below code accumulates the integer value in a variable total:
469
470                  DTTREEMATCH(dt, key, total += (int));
471
472
473   DICTIONARY INFORMATION
474     Dt_t* dtvnext(Dt_t* dt)
475       This returns the dictionary that dt is viewing, if any.
476
477     int dtvcount(Dt_t* dt)
478       This returns the number of dictionaries that view dt.
479
480     Dt_t* dtvhere(Dt_t* dt)
481       This  returns  the  dictionary  v  viewable from dt where an object was
482       found from the most recent search or walk operation.
483
484     int dtsize(Dt_t* dt)
485       This function returns the number of objects stored in dt.
486
487     int dtstat(Dt_t *dt, Dtstat_t* st, int all)
488       This function reports dictionary statistics.  If all is  non-zero,  all
489       fields  of  st  are  filled.   Otherwise,  only the dt_type and dt_size
490       fields are filled.  It returns 0 on success and -1 on error.
491
492       Dtstat_t contains the below fields:
493
494       int dt_type:
495              This is  one  of  DT_SET,  DT_BAG,  DT_OSET,  DT_OBAG,  DT_LIST,
496              DT_STACK, and DT_QUEUE.
497
498       int dt_size:
499              This contains the number of objects in the dictionary.
500
501       int dt_n:
502              For  Dtset  and Dtbag, this is the number of non-empty chains in
503              the hash table.  For Dtoset and  Dtobag,  this  is  the  deepest
504              level  in the tree (counting from zero.)  Each level in the tree
505              contains all nodes of equal distance from the root  node.   dt_n
506              and the below two fields are undefined for other methods.
507
508       int dt_max:
509              For  Dtbag  and Dtset, this is the size of a largest chain.  For
510              Dtoset and Dtobag, this is the size of a largest level.
511
512       int* dt_count:
513              For Dtset and Dtbag, this is the list of counts  for  chains  of
514              particular  sizes.   For  example,  dt_count[1] is the number of
515              chains of size 1.  For Dtoset and Dtobag, this is  the  list  of
516              sizes  of  the  levels.  For example, dt_count[1] is the size of
517              level 1.
518
519   HASH FUNCTIONS
520     unsigned int dtcharhash(unsigned int h, char c)
521     unsigned int dtstrhash(unsigned int h, char* str, int n)
522       These  functions  compute  hash   values   from   bytes   or   strings.
523       dtcharhash()  computes  a  new hash value from byte c and seed value h.
524       dtstrhash() computes a new hash value from string str and seed value h.
525       If  n is positive, str is a byte array of length n; otherwise, str is a
526       null-terminated string.
527

IMPLEMENTATION NOTES

529       Dtset and Dtbag are based on hash tables with  move-to-front  collision
530       chains.   Dtoset and Dtobag are based on top-down splay trees.  Dtlist,
531       Dtstack and Dtqueue are based on doubly linked list.
532

AUTHOR

534       Kiem-Phong Vo, kpv@research.att.com
535
536
537
538                                                                     LIBCDT(3)
Impressum