1da2e3ebdSchin /*********************************************************************** 2da2e3ebdSchin * * 3da2e3ebdSchin * This software is part of the ast package * 4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property * 5da2e3ebdSchin * and is licensed under the * 6da2e3ebdSchin * Common Public License, Version 1.0 * 77c2fbfb3SApril Chin * by AT&T Intellectual Property * 8da2e3ebdSchin * * 9da2e3ebdSchin * A copy of the License is available at * 10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt * 11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12da2e3ebdSchin * * 13da2e3ebdSchin * Information and Software Systems Research * 14da2e3ebdSchin * AT&T Research * 15da2e3ebdSchin * Florham Park NJ * 16da2e3ebdSchin * * 17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18da2e3ebdSchin * David Korn <dgk@research.att.com> * 19da2e3ebdSchin * Phong Vo <kpv@research.att.com> * 20da2e3ebdSchin * * 21da2e3ebdSchin ***********************************************************************/ 22da2e3ebdSchin #ifndef _CDT_H 23da2e3ebdSchin #define _CDT_H 1 24da2e3ebdSchin 25da2e3ebdSchin /* Public interface for the dictionary library 26da2e3ebdSchin ** 27da2e3ebdSchin ** Written by Kiem-Phong Vo 28da2e3ebdSchin */ 29da2e3ebdSchin 30da2e3ebdSchin #define CDT_VERSION 20050420L 31da2e3ebdSchin 32da2e3ebdSchin #if _PACKAGE_ast 33da2e3ebdSchin #include <ast_std.h> 34da2e3ebdSchin #else 35da2e3ebdSchin #include <ast_common.h> 36da2e3ebdSchin #endif 37da2e3ebdSchin 38da2e3ebdSchin typedef struct _dtlink_s Dtlink_t; 39da2e3ebdSchin typedef struct _dthold_s Dthold_t; 40da2e3ebdSchin typedef struct _dtdisc_s Dtdisc_t; 41da2e3ebdSchin typedef struct _dtmethod_s Dtmethod_t; 42da2e3ebdSchin typedef struct _dtdata_s Dtdata_t; 43da2e3ebdSchin typedef struct _dt_s Dt_t; 44da2e3ebdSchin typedef struct _dt_s Dict_t; /* for libdict compatibility */ 45da2e3ebdSchin typedef struct _dtstat_s Dtstat_t; 46da2e3ebdSchin typedef Void_t* (*Dtsearch_f)_ARG_((Dt_t*,Void_t*,int)); 47da2e3ebdSchin typedef Void_t* (*Dtmake_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*)); 48da2e3ebdSchin typedef void (*Dtfree_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*)); 49da2e3ebdSchin typedef int (*Dtcompar_f)_ARG_((Dt_t*,Void_t*,Void_t*,Dtdisc_t*)); 50da2e3ebdSchin typedef unsigned int (*Dthash_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*)); 51da2e3ebdSchin typedef Void_t* (*Dtmemory_f)_ARG_((Dt_t*,Void_t*,size_t,Dtdisc_t*)); 52da2e3ebdSchin typedef int (*Dtevent_f)_ARG_((Dt_t*,int,Void_t*,Dtdisc_t*)); 53da2e3ebdSchin 54da2e3ebdSchin struct _dtlink_s 55da2e3ebdSchin { Dtlink_t* right; /* right child */ 56da2e3ebdSchin union 57da2e3ebdSchin { unsigned int _hash; /* hash value */ 58da2e3ebdSchin Dtlink_t* _left; /* left child */ 59da2e3ebdSchin } hl; 60da2e3ebdSchin }; 61da2e3ebdSchin 62da2e3ebdSchin /* private structure to hold an object */ 63da2e3ebdSchin struct _dthold_s 64da2e3ebdSchin { Dtlink_t hdr; /* header */ 65da2e3ebdSchin Void_t* obj; /* user object */ 66da2e3ebdSchin }; 67da2e3ebdSchin 68da2e3ebdSchin /* method to manipulate dictionary structure */ 69da2e3ebdSchin struct _dtmethod_s 70da2e3ebdSchin { Dtsearch_f searchf; /* search function */ 71da2e3ebdSchin int type; /* type of operation */ 72da2e3ebdSchin }; 73da2e3ebdSchin 74da2e3ebdSchin /* stuff that may be in shared memory */ 75da2e3ebdSchin struct _dtdata_s 76da2e3ebdSchin { int type; /* type of dictionary */ 77da2e3ebdSchin Dtlink_t* here; /* finger to last search element */ 78da2e3ebdSchin union 79da2e3ebdSchin { Dtlink_t** _htab; /* hash table */ 80da2e3ebdSchin Dtlink_t* _head; /* linked list */ 81da2e3ebdSchin } hh; 82da2e3ebdSchin int ntab; /* number of hash slots */ 83da2e3ebdSchin int size; /* number of objects */ 84da2e3ebdSchin int loop; /* number of nested loops */ 85da2e3ebdSchin int minp; /* min path before splay, always even */ 86da2e3ebdSchin /* for hash dt, > 0: fixed table size */ 87da2e3ebdSchin }; 88da2e3ebdSchin 89da2e3ebdSchin /* structure to hold methods that manipulate an object */ 90da2e3ebdSchin struct _dtdisc_s 91da2e3ebdSchin { int key; /* where the key begins in an object */ 92da2e3ebdSchin int size; /* key size and type */ 93da2e3ebdSchin int link; /* offset to Dtlink_t field */ 94da2e3ebdSchin Dtmake_f makef; /* object constructor */ 95da2e3ebdSchin Dtfree_f freef; /* object destructor */ 96da2e3ebdSchin Dtcompar_f comparf;/* to compare two objects */ 97da2e3ebdSchin Dthash_f hashf; /* to compute hash value of an object */ 98da2e3ebdSchin Dtmemory_f memoryf;/* to allocate/free memory */ 99da2e3ebdSchin Dtevent_f eventf; /* to process events */ 100da2e3ebdSchin }; 101da2e3ebdSchin 102da2e3ebdSchin #define DTDISC(dc,ky,sz,lk,mkf,frf,cmpf,hshf,memf,evf) \ 103da2e3ebdSchin ( (dc)->key = (ky), (dc)->size = (sz), (dc)->link = (lk), \ 104da2e3ebdSchin (dc)->makef = (mkf), (dc)->freef = (frf), \ 105da2e3ebdSchin (dc)->comparf = (cmpf), (dc)->hashf = (hshf), \ 106da2e3ebdSchin (dc)->memoryf = (memf), (dc)->eventf = (evf) ) 107da2e3ebdSchin 108da2e3ebdSchin #ifdef offsetof 109da2e3ebdSchin #define DTOFFSET(struct_s, member) offsetof(struct_s, member) 110da2e3ebdSchin #else 111da2e3ebdSchin #define DTOFFSET(struct_s, member) ((int)(&((struct_s*)0)->member)) 112da2e3ebdSchin #endif 113da2e3ebdSchin 114da2e3ebdSchin /* the dictionary structure itself */ 115da2e3ebdSchin struct _dt_s 116da2e3ebdSchin { Dtsearch_f searchf;/* search function */ 117da2e3ebdSchin Dtdisc_t* disc; /* method to manipulate objs */ 118da2e3ebdSchin Dtdata_t* data; /* sharable data */ 119da2e3ebdSchin Dtmemory_f memoryf;/* function to alloc/free memory */ 120da2e3ebdSchin Dtmethod_t* meth; /* dictionary method */ 121da2e3ebdSchin int type; /* type information */ 122da2e3ebdSchin int nview; /* number of parent view dictionaries */ 123da2e3ebdSchin Dt_t* view; /* next on viewpath */ 124da2e3ebdSchin Dt_t* walk; /* dictionary being walked */ 125da2e3ebdSchin Void_t* user; /* for user's usage */ 126da2e3ebdSchin }; 127da2e3ebdSchin 128da2e3ebdSchin /* structure to get status of a dictionary */ 129da2e3ebdSchin struct _dtstat_s 130da2e3ebdSchin { int dt_meth; /* method type */ 131da2e3ebdSchin int dt_size; /* number of elements */ 132da2e3ebdSchin int dt_n; /* number of chains or levels */ 133da2e3ebdSchin int dt_max; /* max size of a chain or a level */ 134da2e3ebdSchin int* dt_count; /* counts of chains or levels by size */ 135da2e3ebdSchin }; 136da2e3ebdSchin 137da2e3ebdSchin /* flag set if the last search operation actually found the object */ 138da2e3ebdSchin #define DT_FOUND 0100000 139da2e3ebdSchin 140da2e3ebdSchin /* supported storage methods */ 141da2e3ebdSchin #define DT_SET 0000001 /* set with unique elements */ 142da2e3ebdSchin #define DT_BAG 0000002 /* multiset */ 143da2e3ebdSchin #define DT_OSET 0000004 /* ordered set (self-adjusting tree) */ 144da2e3ebdSchin #define DT_OBAG 0000010 /* ordered multiset */ 145da2e3ebdSchin #define DT_LIST 0000020 /* linked list */ 146da2e3ebdSchin #define DT_STACK 0000040 /* stack */ 147da2e3ebdSchin #define DT_QUEUE 0000100 /* queue */ 148da2e3ebdSchin #define DT_METHODS 0000177 /* all currently supported methods */ 149da2e3ebdSchin 150da2e3ebdSchin /* asserts to dtdisc() */ 151da2e3ebdSchin #define DT_SAMECMP 0000001 /* compare methods equivalent */ 152da2e3ebdSchin #define DT_SAMEHASH 0000002 /* hash methods equivalent */ 153da2e3ebdSchin 154da2e3ebdSchin /* types of search */ 155da2e3ebdSchin #define DT_INSERT 0000001 /* insert object if not found */ 156da2e3ebdSchin #define DT_DELETE 0000002 /* delete object if found */ 157da2e3ebdSchin #define DT_SEARCH 0000004 /* look for an object */ 158da2e3ebdSchin #define DT_NEXT 0000010 /* look for next element */ 159da2e3ebdSchin #define DT_PREV 0000020 /* find previous element */ 160da2e3ebdSchin #define DT_RENEW 0000040 /* renewing an object */ 161da2e3ebdSchin #define DT_CLEAR 0000100 /* clearing all objects */ 162da2e3ebdSchin #define DT_FIRST 0000200 /* get first object */ 163da2e3ebdSchin #define DT_LAST 0000400 /* get last object */ 164da2e3ebdSchin #define DT_MATCH 0001000 /* find object matching key */ 165da2e3ebdSchin #define DT_VSEARCH 0002000 /* search using internal representation */ 166da2e3ebdSchin #define DT_ATTACH 0004000 /* attach an object to the dictionary */ 167da2e3ebdSchin #define DT_DETACH 0010000 /* detach an object from the dictionary */ 168da2e3ebdSchin 169da2e3ebdSchin /* events */ 170da2e3ebdSchin #define DT_OPEN 1 /* a dictionary is being opened */ 171da2e3ebdSchin #define DT_CLOSE 2 /* a dictionary is being closed */ 172da2e3ebdSchin #define DT_DISC 3 /* discipline is about to be changed */ 173da2e3ebdSchin #define DT_METH 4 /* method is about to be changed */ 174da2e3ebdSchin #define DT_ENDOPEN 5 /* dtopen() is done */ 175da2e3ebdSchin #define DT_ENDCLOSE 6 /* dtclose() is done */ 176da2e3ebdSchin #define DT_HASHSIZE 7 /* setting hash table size */ 177da2e3ebdSchin 178da2e3ebdSchin _BEGIN_EXTERNS_ /* public data */ 179da2e3ebdSchin #if _BLD_cdt && defined(__EXPORT__) 180da2e3ebdSchin #define extern __EXPORT__ 181da2e3ebdSchin #endif 182da2e3ebdSchin #if !_BLD_cdt && defined(__IMPORT__) 183da2e3ebdSchin #define extern __IMPORT__ 184da2e3ebdSchin #endif 185da2e3ebdSchin 186da2e3ebdSchin extern Dtmethod_t* Dtset; 187da2e3ebdSchin extern Dtmethod_t* Dtbag; 188da2e3ebdSchin extern Dtmethod_t* Dtoset; 189da2e3ebdSchin extern Dtmethod_t* Dtobag; 190da2e3ebdSchin extern Dtmethod_t* Dtlist; 191da2e3ebdSchin extern Dtmethod_t* Dtstack; 192da2e3ebdSchin extern Dtmethod_t* Dtqueue; 193da2e3ebdSchin 194da2e3ebdSchin /* compatibility stuff; will go away */ 195da2e3ebdSchin #ifndef KPVDEL 196da2e3ebdSchin extern Dtmethod_t* Dtorder; 197da2e3ebdSchin extern Dtmethod_t* Dttree; 198da2e3ebdSchin extern Dtmethod_t* Dthash; 199da2e3ebdSchin extern Dtmethod_t _Dttree; 200da2e3ebdSchin extern Dtmethod_t _Dthash; 201da2e3ebdSchin extern Dtmethod_t _Dtlist; 202da2e3ebdSchin extern Dtmethod_t _Dtqueue; 203da2e3ebdSchin extern Dtmethod_t _Dtstack; 204da2e3ebdSchin #endif 205da2e3ebdSchin 206da2e3ebdSchin #undef extern 207da2e3ebdSchin _END_EXTERNS_ 208da2e3ebdSchin 209da2e3ebdSchin _BEGIN_EXTERNS_ /* public functions */ 210da2e3ebdSchin #if _BLD_cdt && defined(__EXPORT__) 211da2e3ebdSchin #define extern __EXPORT__ 212da2e3ebdSchin #endif 213da2e3ebdSchin 214da2e3ebdSchin extern Dt_t* dtopen _ARG_((Dtdisc_t*, Dtmethod_t*)); 215da2e3ebdSchin extern int dtclose _ARG_((Dt_t*)); 216da2e3ebdSchin extern Dt_t* dtview _ARG_((Dt_t*, Dt_t*)); 217da2e3ebdSchin extern Dtdisc_t* dtdisc _ARG_((Dt_t* dt, Dtdisc_t*, int)); 218da2e3ebdSchin extern Dtmethod_t* dtmethod _ARG_((Dt_t*, Dtmethod_t*)); 219da2e3ebdSchin 220da2e3ebdSchin extern Dtlink_t* dtflatten _ARG_((Dt_t*)); 221da2e3ebdSchin extern Dtlink_t* dtextract _ARG_((Dt_t*)); 222da2e3ebdSchin extern int dtrestore _ARG_((Dt_t*, Dtlink_t*)); 223da2e3ebdSchin 224da2e3ebdSchin extern int dttreeset _ARG_((Dt_t*, int, int)); 225da2e3ebdSchin 226da2e3ebdSchin extern int dtwalk _ARG_((Dt_t*, int(*)(Dt_t*,Void_t*,Void_t*), Void_t*)); 227da2e3ebdSchin 228da2e3ebdSchin extern Void_t* dtrenew _ARG_((Dt_t*, Void_t*)); 229da2e3ebdSchin 230da2e3ebdSchin extern int dtsize _ARG_((Dt_t*)); 231da2e3ebdSchin extern int dtstat _ARG_((Dt_t*, Dtstat_t*, int)); 232da2e3ebdSchin extern unsigned int dtstrhash _ARG_((unsigned int, Void_t*, int)); 233da2e3ebdSchin 234da2e3ebdSchin #if !_PACKAGE_ast 235da2e3ebdSchin extern int memcmp _ARG_((const Void_t*, const Void_t*, size_t)); 236da2e3ebdSchin extern int strcmp _ARG_((const char*, const char*)); 237da2e3ebdSchin #endif 238da2e3ebdSchin 239da2e3ebdSchin #undef extern 240da2e3ebdSchin _END_EXTERNS_ 241da2e3ebdSchin 242da2e3ebdSchin /* internal functions for translating among holder, object and key */ 243da2e3ebdSchin #define _DT(dt) ((Dt_t*)(dt)) 244da2e3ebdSchin #define _DTDSC(dc,ky,sz,lk,cmpf) \ 245da2e3ebdSchin (ky = (dc)->key, sz = (dc)->size, lk = (dc)->link, cmpf = (dc)->comparf) 246da2e3ebdSchin #define _DTLNK(o,lk) ((Dtlink_t*)((char*)(o) + lk) ) 247da2e3ebdSchin #define _DTOBJ(e,lk) ((lk) < 0 ? ((Dthold_t*)(e))->obj : (Void_t*)((char*)(e) - (lk)) ) 248da2e3ebdSchin #define _DTKEY(o,ky,sz) (Void_t*)((sz) < 0 ? *((char**)((char*)(o)+(ky))) : ((char*)(o)+(ky))) 249da2e3ebdSchin 250da2e3ebdSchin #define _DTCMP(dt,k1,k2,dc,cmpf,sz) \ 251da2e3ebdSchin ((cmpf) ? (*cmpf)(dt,k1,k2,dc) : \ 252da2e3ebdSchin ((sz) <= 0 ? strcmp(k1,k2) : memcmp(k1,k2,sz)) ) 253da2e3ebdSchin #define _DTHSH(dt,ky,dc,sz) ((dc)->hashf ? (*(dc)->hashf)(dt,ky,dc) : dtstrhash(0,ky,sz) ) 254da2e3ebdSchin 255da2e3ebdSchin /* special search function for tree structure only */ 256da2e3ebdSchin #define _DTMTCH(dt,key,action) \ 257da2e3ebdSchin do { Dtlink_t* _e; Void_t *_o, *_k, *_key; Dtdisc_t* _dc; \ 258da2e3ebdSchin int _ky, _sz, _lk, _cmp; Dtcompar_f _cmpf; \ 259da2e3ebdSchin _dc = (dt)->disc; _DTDSC(_dc, _ky, _sz, _lk, _cmpf); \ 260da2e3ebdSchin _key = (key); \ 261da2e3ebdSchin for(_e = (dt)->data->here; _e; _e = _cmp < 0 ? _e->hl._left : _e->right) \ 262da2e3ebdSchin { _o = _DTOBJ(_e, _lk); _k = _DTKEY(_o, _ky, _sz); \ 263da2e3ebdSchin if((_cmp = _DTCMP((dt), _key, _k, _dc, _cmpf, _sz)) == 0) \ 264da2e3ebdSchin break; \ 265da2e3ebdSchin } \ 266da2e3ebdSchin action (_e ? _o : (Void_t*)0); \ 267da2e3ebdSchin } while(0) 268da2e3ebdSchin 269da2e3ebdSchin #define _DTSRCH(dt,obj,action) \ 270da2e3ebdSchin do { Dtlink_t* _e; Void_t *_o, *_k, *_key; Dtdisc_t* _dc; \ 271da2e3ebdSchin int _ky, _sz, _lk, _cmp; Dtcompar_f _cmpf; \ 272da2e3ebdSchin _dc = (dt)->disc; _DTDSC(_dc, _ky, _sz, _lk, _cmpf); \ 273da2e3ebdSchin _key = _DTKEY(obj, _ky, _sz); \ 274da2e3ebdSchin for(_e = (dt)->data->here; _e; _e = _cmp < 0 ? _e->hl._left : _e->right) \ 275da2e3ebdSchin { _o = _DTOBJ(_e, _lk); _k = _DTKEY(_o, _ky, _sz); \ 276da2e3ebdSchin if((_cmp = _DTCMP((dt), _key, _k, _dc, _cmpf, _sz)) == 0) \ 277da2e3ebdSchin break; \ 278da2e3ebdSchin } \ 279da2e3ebdSchin action (_e ? _o : (Void_t*)0); \ 280da2e3ebdSchin } while(0) 281da2e3ebdSchin 282da2e3ebdSchin #define DTTREEMATCH(dt,key,action) _DTMTCH(_DT(dt),(Void_t*)(key),action) 283da2e3ebdSchin #define DTTREESEARCH(dt,obj,action) _DTSRCH(_DT(dt),(Void_t*)(obj),action) 284da2e3ebdSchin 285da2e3ebdSchin #define dtvnext(d) (_DT(d)->view) 286da2e3ebdSchin #define dtvcount(d) (_DT(d)->nview) 287da2e3ebdSchin #define dtvhere(d) (_DT(d)->walk) 288da2e3ebdSchin 289da2e3ebdSchin #define dtlink(d,e) (((Dtlink_t*)(e))->right) 290da2e3ebdSchin #define dtobj(d,e) _DTOBJ((e), _DT(d)->disc->link) 291da2e3ebdSchin #define dtfinger(d) (_DT(d)->data->here ? dtobj((d),_DT(d)->data->here):(Void_t*)(0)) 292da2e3ebdSchin 293da2e3ebdSchin #define dtfirst(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_FIRST) 294da2e3ebdSchin #define dtnext(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_NEXT) 295da2e3ebdSchin #define dtleast(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH|DT_NEXT) 296da2e3ebdSchin #define dtlast(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_LAST) 297da2e3ebdSchin #define dtprev(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_PREV) 298da2e3ebdSchin #define dtmost(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH|DT_PREV) 299da2e3ebdSchin #define dtsearch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH) 300da2e3ebdSchin #define dtmatch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_MATCH) 301da2e3ebdSchin #define dtinsert(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_INSERT) 302da2e3ebdSchin #define dtdelete(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DELETE) 303da2e3ebdSchin #define dtattach(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_ATTACH) 304da2e3ebdSchin #define dtdetach(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DETACH) 305da2e3ebdSchin #define dtclear(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_CLEAR) 306da2e3ebdSchin #define dtfound(d) (_DT(d)->type & DT_FOUND) 307da2e3ebdSchin 308da2e3ebdSchin #define DT_PRIME 17109811 /* 2#00000001 00000101 00010011 00110011 */ 309da2e3ebdSchin #define dtcharhash(h,c) (((unsigned int)(h) + (unsigned int)(c)) * DT_PRIME ) 310da2e3ebdSchin 311da2e3ebdSchin #endif /* _CDT_H */ 312