int dttreeprint(Dt_t* dt, Dtlink_t* here, int lev, char* (*objprintf)(Void_t*) ) { int k, rv; char *obj, *endb, buf[1024]; Dtdisc_t *disc = dt->disc; Dttree_t *tree = (Dttree_t*)dt->data; if(!here && !(here = tree->root) ) return -1; endb = buf; /* indentation */ for(k = 0; k < lev; ++k) { *endb++ = ' '; *endb++ = ' '; } *endb++ = '('; obj = (*objprintf)(_DTOBJ(disc, here)); k = strlen(obj); memcpy(endb, obj, k); endb += k; *endb++ = ')'; *endb++ = ':'; *endb++ = ' '; *endb++ = '<'; if(here->_left) obj = (*objprintf)(_DTOBJ(disc,here->_left)); else obj = "NIL"; k = strlen(obj); memcpy(endb, obj, k); endb += k; *endb++ = '>'; *endb++ = ' '; *endb++ = '<'; if(here->_rght) obj = (*objprintf)(_DTOBJ(disc,here->_rght)); else obj = "NIL"; k = strlen(obj); memcpy(endb, obj, k); endb += k; *endb++ = '>'; *endb++ = '\n'; write(2, buf, endb-buf); if(here->_left) dttreeprint(dt, here->_left, lev+1, objprintf); if(here->_rght) dttreeprint(dt, here->_rght, lev+1, objprintf); return 0; }
static void* dttree(Dt_t* dt, void* obj, int type) { Dtlink_t *root, *t; int cmp, lk, sz, ky; void *o, *k, *key; Dtlink_t *l, *r, *me = NULL, link; int n, minp, turn[DT_MINP]; Dtcompar_f cmpf; Dtdisc_t* disc; UNFLATTEN(dt); disc = dt->disc; _DTDSC(disc,ky,sz,lk,cmpf); dt->type &= ~DT_FOUND; root = dt->data->here; if(!obj) { if(!root || !(type&(DT_CLEAR|DT_FIRST|DT_LAST)) ) return NIL(void*); if(type&DT_CLEAR) /* delete all objects */ { if(disc->freef || disc->link < 0) { do { while((t = root->left) ) RROTATE(root,t); t = root->right; if(disc->freef) (*disc->freef)(dt,_DTOBJ(root,lk),disc); if(disc->link < 0) (*dt->memoryf)(dt,(void*)root,0,disc); } while((root = t) ); } dt->data->size = 0; dt->data->here = NIL(Dtlink_t*); return NIL(void*); } else /* computing largest/smallest element */ { if(type&DT_LAST) { while((t = root->right) ) LROTATE(root,t); } else /* type&DT_FIRST */ { while((t = root->left) ) RROTATE(root,t); } dt->data->here = root; return _DTOBJ(root,lk); } }
static Void_t* hfirst(Dt_t* dt) { Dtlink_t **tbl, **endt, *lnk; Dthash_t *hash = (Dthash_t*)dt->data; lnk = NIL(Dtlink_t*); for(endt = (tbl = hash->htbl) + hash->tblz; tbl < endt; ++tbl) if((lnk = *tbl) ) break; hash->here = lnk; return lnk ? _DTOBJ(dt->disc, lnk) : NIL(Void_t*); }
static Void_t* hnext(Dt_t* dt, Dtlink_t* l) { Dtlink_t **t, **endt, *next; Dthash_t *hash = (Dthash_t*)dt->data; if((next = l->_rght) ) { hash->here = next; return _DTOBJ(dt->disc, next); } else { t = hash->htbl + (l->_hash & (hash->tblz-1)) + 1; endt = hash->htbl + hash->tblz; for(; t < endt; ++t) { if(!(l = *t) ) continue; hash->here = l; return _DTOBJ(dt->disc, l); } return NIL(Void_t*); } }
static Void_t* hfirst(Dt_t* dt) { Dtlink_t **t, **endt, *l; Dthash_t *hash = (Dthash_t*)dt->data; for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t) { if(!(l = *t) ) continue; hash->here = l; return _DTOBJ(dt->disc, l); } return NIL(Void_t*); }
static Void_t* hnext(Dt_t* dt, Dtlink_t* lnk) { Dtlink_t **tbl, **endt, *next; Dthash_t *hash = (Dthash_t*)dt->data; if(!(next = lnk->_rght) ) /* search for next object */ { tbl = hash->htbl + (lnk->_hash & (hash->tblz-1)) + 1; endt = hash->htbl + hash->tblz; for(; tbl < endt; ++tbl) if((next = *tbl) ) break; } hash->here = next; return next ? _DTOBJ(dt->disc, next) : NIL(Void_t*); }