PropPtr next_node(PropPtr ptr, char *name) { PropPtr from; int cmpval; if (!ptr) return NULL; if (!name || !*name) return (PropPtr) NULL; cmpval = Comparator(name, PropName(ptr)); if (cmpval < 0) { from = next_node(AVL_LF(ptr), name); if (from) return from; return ptr; } else if (cmpval > 0) { return next_node(AVL_RT(ptr), name); } else if (AVL_RT(ptr)) { from = AVL_RT(ptr); while (AVL_LF(from)) from = AVL_LF(from); return from; } else { return NULL; } }
static array_tree * array_tree_getmax(array_tree *avl) { if (avl && AVL_RT(avl)) return array_tree_getmax(AVL_RT(avl)); return avl; }
static PropPtr getmax(PropPtr avl) { if (avl && AVL_RT(avl)) return getmax(AVL_RT(avl)); return avl; }
array_tree * array_tree_next_node(array_tree *ptr, array_iter *key) { array_tree *from; int cmpval; if (!ptr) return NULL; if (!key) return NULL; cmpval = AVL_COMPARE(key, AVL_KEY(ptr)); if (cmpval < 0) { from = array_tree_next_node(AVL_LF(ptr), key); if (from) return from; return ptr; } else if (cmpval > 0) { return array_tree_next_node(AVL_RT(ptr), key); } else if (AVL_RT(ptr)) { from = AVL_RT(ptr); while (AVL_LF(from)) from = AVL_LF(from); return from; } else { return NULL; } }
void array_tree_delete_all(array_tree *p) { if (!p) return; array_tree_delete_all(AVL_LF(p)); array_tree_delete_all(AVL_RT(p)); AVL_LF(p) = NULL; AVL_RT(p) = NULL; array_tree_free_node(p); }
array_tree * array_tree_last_node(array_tree *list) { if (!list) return NULL; while (AVL_RT(list)) list = AVL_RT(list); return (list); }
static array_tree * array_tree_rotate_right_single(array_tree *a) { array_tree *b = AVL_LF(a); AVL_LF(a) = AVL_RT(b); AVL_RT(b) = a; array_tree_fixup_height(a); array_tree_fixup_height(b); return (b); }
static PropPtr rotate_right_single(PropPtr a) { PropPtr b = AVL_LF(a); AVL_LF(a) = AVL_RT(b); AVL_RT(b) = a; fixup_height(a); fixup_height(b); return (b); }
static PropPtr insert(char *key, PropPtr * avl) { PropPtr ret; register PropPtr p = *avl; register int cmp; static short balancep; if (p) { cmp = Comparator(key, PropName(p)); if (cmp > 0) { ret = insert(key, &(AVL_RT(p))); } else if (cmp < 0) { ret = insert(key, &(AVL_LF(p))); } else { balancep = 0; return (p); } if (balancep) { *avl = balance_node(p); } return ret; } else { p = *avl = alloc_propnode(key); balancep = 1; return (p); } }
long size_proplist(PropPtr avl) { long bytes = 0; if (!avl) return 0; bytes += sizeof(struct plist); bytes += strlen(PropName(avl)); if (!(PropFlags(avl) & PROP_ISUNLOADED)) { switch (PropType(avl)) { case PROP_STRTYP: bytes += strlen(PropDataStr(avl)) + 1; break; case PROP_LOKTYP: bytes += size_boolexp(PropDataLok(avl)); break; default: break; } } bytes += size_proplist(AVL_LF(avl)); bytes += size_proplist(AVL_RT(avl)); bytes += size_proplist(PropDir(avl)); return bytes; }
static PropPtr rotate_left_double(PropPtr a) { PropPtr b = AVL_RT(a), c = AVL_LF(b); AVL_RT(a) = AVL_LF(c); AVL_LF(b) = AVL_RT(c); AVL_LF(c) = a; AVL_RT(c) = b; fixup_height(a); fixup_height(b); fixup_height(c); return c; }
array_tree * array_tree_insert(array_tree **avl, array_iter *key) { array_tree *ret; register array_tree *p = *avl; register int cmp; static int balancep; if (p) { cmp = AVL_COMPARE(key, AVL_KEY(p)); if (cmp > 0) { ret = array_tree_insert(&(AVL_RT(p)), key); } else if (cmp < 0) { ret = array_tree_insert(&(AVL_LF(p)), key); } else { balancep = 0; return (p); } if (balancep) { *avl = array_tree_balance_node(p); } return ret; } else { p = *avl = array_tree_alloc_node(key); balancep = 1; return (p); } }
static array_tree * array_tree_rotate_right_double(array_tree *a) { array_tree *b = AVL_LF(a); array_tree *c = AVL_RT(b); AVL_LF(a) = AVL_RT(c); AVL_RT(b) = AVL_LF(c); AVL_RT(c) = a; AVL_LF(c) = b; array_tree_fixup_height(a); array_tree_fixup_height(b); array_tree_fixup_height(c); return c; }
static void array_tree_fixup_height(array_tree *node) { if (node) node->height = (int) 1 + max(array_tree_height_of(AVL_LF(node)), array_tree_height_of(AVL_RT(node))); }
static int height_diff(PropPtr node) { if (node) return (height_of(AVL_RT(node)) - height_of(AVL_LF(node))); else return 0; }
static int array_tree_height_diff(array_tree *node) { if (node != NULL) return (array_tree_height_of(AVL_RT(node)) - array_tree_height_of(AVL_LF(node))); else return 0; }
void array_tree_free_node(array_tree *p) { assert(AVL_LF(p) == NULL); assert(AVL_RT(p) == NULL); CLEAR(AVL_KEY(p)); CLEAR(&p->data); free(p); }
void delete_proplist(PropPtr p) { if (!p) return; delete_proplist(AVL_LF(p)); delete_proplist(PropDir(p)); delete_proplist(AVL_RT(p)); free_propnode(p); }
void untouchprop_rec(PropPtr p) { if (!p) return; SetPFlags(p, (PropFlags(p) & ~PROP_TOUCHED)); untouchprop_rec(AVL_LF(p)); untouchprop_rec(AVL_RT(p)); untouchprop_rec(PropDir(p)); }
/* copies properties */ void copy_proplist(dbref obj, PropPtr * nu, PropPtr old) { PropPtr p; if (old) { #ifdef DISKBASE propfetch(obj, old); #endif p = new_prop(nu, PropName(old)); SetPFlagsRaw(p, PropFlagsRaw(old)); switch (PropType(old)) { case PROP_STRTYP: SetPDataStr(p, alloc_string(PropDataStr(old))); break; case PROP_LOKTYP: if (PropFlags(old) & PROP_ISUNLOADED) { SetPDataLok(p, TRUE_BOOLEXP); SetPFlags(p, (PropFlags(p) & ~PROP_ISUNLOADED)); } else { SetPDataLok(p, copy_bool(PropDataLok(old))); } break; case PROP_DIRTYP: SetPDataVal(p, 0); break; case PROP_FLTTYP: SetPDataFVal(p, PropDataFVal(old)); break; default: SetPDataVal(p, PropDataVal(old)); break; } copy_proplist(obj, &PropDir(p), PropDir(old)); copy_proplist(obj, &AVL_LF(p), AVL_LF(old)); copy_proplist(obj, &AVL_RT(p), AVL_RT(old)); /* copy_proplist(obj, nu, AVL_LF(old)); copy_proplist(obj, nu, AVL_RT(old)); */ } }
static PropPtr remove_propnode(char *key, PropPtr * root) { PropPtr save; PropPtr tmp; PropPtr avl = *root; int cmpval; save = avl; if (avl) { cmpval = Comparator(key, PropName(avl)); if (cmpval < 0) { save = remove_propnode(key, &AVL_LF(avl)); } else if (cmpval > 0) { save = remove_propnode(key, &AVL_RT(avl)); } else if (!(AVL_LF(avl))) { avl = AVL_RT(avl); } else if (!(AVL_RT(avl))) { avl = AVL_LF(avl); } else { tmp = remove_propnode(PropName(getmax(AVL_LF(avl))), &AVL_LF(avl)); if (!tmp) abort(); /* this shouldn't be possible. */ AVL_LF(tmp) = AVL_LF(avl); AVL_RT(tmp) = AVL_RT(avl); avl = tmp; } if (save) { AVL_LF(save) = NULL; AVL_RT(save) = NULL; } *root = balance_node(avl); } return save; }
static PropPtr find(char *key, PropPtr avl) { int cmpval; while (avl) { cmpval = Comparator(key, PropName(avl)); if (cmpval > 0) { avl = AVL_RT(avl); } else if (cmpval < 0) { avl = AVL_LF(avl); } else { break; } } return avl; }
static array_tree * array_tree_find(array_tree *avl, array_iter *key) { int cmpval; while (avl) { cmpval = AVL_COMPARE(key, AVL_KEY(avl)); if (cmpval > 0) { avl = AVL_RT(avl); } else if (cmpval < 0) { avl = AVL_LF(avl); } else { break; } } return avl; }
static PropPtr balance_node(PropPtr a) { int dh = height_diff(a); if (abs(dh) < 2) { fixup_height(a); } else { if (dh == 2) if (height_diff(AVL_RT(a)) >= 0) a = rotate_left_single(a); else a = rotate_left_double(a); else if (height_diff(AVL_LF(a)) <= 0) a = rotate_right_single(a); else a = rotate_right_double(a); } return a; }
/* cake */ array_tree * array_tree_alloc_node(array_iter *key) { array_tree *new_node; new_node = (array_tree *) malloc(sizeof(array_tree)); if (!new_node) { fprintf(stderr, "array_tree_alloc_node(): Out of Memory!\n"); abort(); } AVL_LF(new_node) = NULL; AVL_RT(new_node) = NULL; new_node->height = 1; copyinst(key, AVL_KEY(new_node)); new_node->data.type = PROG_INTEGER; new_node->data.data.number = 0; return new_node; }
void db_dump_props_rec(dbref obj, FILE * f, const char *dir, PropPtr p) { char buf[BUFFER_LEN]; #ifdef DISKBASE int tpos = 0; int flg; short wastouched = 0; #endif if (!p) return; db_dump_props_rec(obj, f, dir, AVL_LF(p)); #ifdef DISKBASE if (tp_diskbase_propvals) { tpos = ftell(f); wastouched = (PropFlags(p) & PROP_TOUCHED); } if (propfetch(obj, p)) { fseek(f, 0L, 2); } #endif db_putprop(f, dir, p); #ifdef DISKBASE if (tp_diskbase_propvals && !wastouched) { if (PropType(p) == PROP_STRTYP || PropType(p) == PROP_LOKTYP) { flg = PropFlagsRaw(p) | PROP_ISUNLOADED; clear_propnode(p); SetPFlagsRaw(p, flg); SetPDataVal(p, tpos); } } #endif if (PropDir(p)) { sprintf(buf, "%s%s%c", dir, PropName(p), PROPDIR_DELIMITER); db_dump_props_rec(obj, f, buf, PropDir(p)); } db_dump_props_rec(obj, f, dir, AVL_RT(p)); }
static array_tree * array_tree_balance_node(array_tree *a) { int dh = array_tree_height_diff(a); if (abs(dh) < 2) { array_tree_fixup_height(a); } else { if (dh == 2) { if (array_tree_height_diff(AVL_RT(a)) >= 0) { a = array_tree_rotate_left_single(a); } else { a = array_tree_rotate_left_double(a); } } else if (array_tree_height_diff(AVL_LF(a)) <= 0) { a = array_tree_rotate_right_single(a); } else { a = array_tree_rotate_right_double(a); } } return a; }
PropPtr alloc_propnode(const char *name) { PropPtr new_node; int nlen = strlen(name); new_node = (PropPtr) malloc(sizeof(struct plist) + nlen); if (!new_node) { fprintf(stderr, "alloc_propnode(): Out of Memory!\n"); abort(); } AVL_LF(new_node) = NULL; AVL_RT(new_node) = NULL; new_node->height = 1; strcpyn(PropName(new_node), nlen+1, name); SetPFlagsRaw(new_node, PROP_DIRTYP); SetPDataVal(new_node, 0); SetPDir(new_node, NULL); return new_node; }
static array_tree * array_tree_remove_node(array_iter *key, array_tree **root) { array_tree *save; array_tree *tmp; array_tree *avl = *root; int cmpval; save = avl; if (avl) { cmpval = AVL_COMPARE(key, AVL_KEY(avl)); if (cmpval < 0) { save = array_tree_remove_node(key, &AVL_LF(avl)); } else if (cmpval > 0) { save = array_tree_remove_node(key, &AVL_RT(avl)); } else if (!(AVL_LF(avl))) { avl = AVL_RT(avl); } else if (!(AVL_RT(avl))) { avl = AVL_LF(avl); } else { tmp = array_tree_remove_node(AVL_KEY(array_tree_getmax(AVL_LF(avl))), &AVL_LF(avl)); if (!tmp) abort(); /* this shouldn't be possible. */ AVL_LF(tmp) = AVL_LF(avl); AVL_RT(tmp) = AVL_RT(avl); avl = tmp; } if (save) { AVL_LF(save) = NULL; AVL_RT(save) = NULL; } *root = array_tree_balance_node(avl); } return save; }
static void fixup_height(PropPtr node) { if (node) node->height = 1 + max(height_of(AVL_LF(node)), height_of(AVL_RT(node))); }