void * avl_find (avl_tree *tree, const void *item) { const avl_node *p; p = NULL; assert (tree != NULL); internal_lock_mutex(&tree->mutex); for (p = tree->root.link[0]; p; ) { int diff = tree->cmp (item, p->data, tree->param); if (diff < 0) p = p->link[0]; else if (diff > 0) p = p->link[1]; else { internal_unlock_mutex(&tree->mutex); return p->data; } } internal_unlock_mutex(&tree->mutex); return NULL; }
void avl_destroy(avl_tree *tree, avl_node_func free_func) { assert(tree != NULL); internal_lock_mutex(&tree->mutex); #if PSPP if (free_func || tree->owner == NULL) #endif { avl_node *an[AVL_MAX_HEIGHT]; unsigned long ab = 0; int ap = 0; avl_node *p = tree->root.link[0]; for (;;) { /* T2. */ while (p != NULL) { /* T3. */ ab &= ~(1ul << ap); an[ap++] = p; p = p->link[0]; } /* T4. */ for (;;) { if (ap == 0) goto done; p = an[--ap]; if ((ab & (1ul << ap)) == 0) { ab |= (1ul << ap++); p = p->link[1]; break; } if (free_func) free_func (p->data, tree->param); #if PSPP if (tree->owner == NULL) #endif free (p); } } } done: internal_unlock_mutex(&tree->mutex); thread_mutex_destroy(&tree->mutex); #if PSPP if (tree->owner == NULL) #endif free (tree); }
void * avl_traverse (avl_tree *tree, avl_traverser *trav) { assert (tree && trav); internal_lock_mutex(&tree->mutex); if (trav->init == 0) { trav->init = 1; trav->nstack = 0; trav->p = tree->root.link[0]; } else trav->p = trav->p->link[1]; for (;;) { while (trav->p != NULL) { trav->stack[trav->nstack++] = trav->p; trav->p = trav->p->link[0]; } if (trav->nstack == 0) { trav->init = 0; internal_unlock_mutex(&tree->mutex); return NULL; } trav->p = trav->stack[--trav->nstack]; internal_unlock_mutex(&tree->mutex); return trav->p->data; } internal_unlock_mutex(&tree->mutex); }
void pool_unlock_write () { assert (pool_mutex.thread_id != MUTEX_STATE_UNINIT); internal_unlock_mutex (&pool_mutex); }
void * avl_delete (avl_tree *tree, const void *item) { avl_node *pa[AVL_MAX_HEIGHT]; char a[AVL_MAX_HEIGHT]; int k = 1; avl_node **q; avl_node *p; assert (tree != NULL); internal_lock_mutex(&tree->mutex); a[0] = 0; pa[0] = &tree->root; p = tree->root.link[0]; for (;;) { int diff = tree->cmp (item, p->data, tree->param); if (diff == 0) break; pa[k] = p; if (diff < 0) p = p->link[0], a[k] = 0; else if (diff > 0) p = p->link[1], a[k] = 1; k++; if (p == NULL) { internal_unlock_mutex(&tree->mutex); return NULL; } } tree->count--; item = p->data; q = &pa[k - 1]->link[(int) a[k - 1]]; if (p->link[1] == NULL) { *q = p->link[0]; if (*q) (*q)->bal = 0; } else { avl_node *r = p->link[1]; if (r->link[0] == NULL) { r->link[0] = p->link[0]; *q = r; r->bal = p->bal; a[k] = 1; pa[k++] = r; } else { avl_node *s = r->link[0]; int l = k++; a[k] = 0; pa[k++] = r; while (s->link[0] != NULL) { r = s; s = r->link[0]; a[k] = 0; pa[k++] = r; } a[l] = 1; pa[l] = s; s->link[0] = p->link[0]; r->link[0] = s->link[1]; s->link[1] = p->link[1]; s->bal = p->bal; *q = s; } } #if PSPP if (tree->owner == NULL) #endif free (p); assert (k > 0); while (--k) { avl_node *s = pa[k], *r; if (a[k] == 0) { if (s->bal == -1) { s->bal = 0; continue; } else if (s->bal == 0) { s->bal = 1; break; } assert (s->bal == +1); r = s->link[1]; assert (r != NULL); if (r->bal == 0) { s->link[1] = r->link[0]; r->link[0] = s; r->bal = -1; pa[k - 1]->link[(int) a[k - 1]] = r; break; } else if (r->bal == +1) { s->link[1] = r->link[0]; r->link[0] = s; s->bal = r->bal = 0; pa[k - 1]->link[(int) a[k - 1]] = r; } else { assert (r->bal == -1); p = r->link[0]; r->link[0] = p->link[1]; p->link[1] = r; s->link[1] = p->link[0]; p->link[0] = s; if (p->bal == +1) s->bal = -1, r->bal = 0; else if (p->bal == 0) s->bal = r->bal = 0; else { assert (p->bal == -1); s->bal = 0, r->bal = +1; } p->bal = 0; pa[k - 1]->link[(int) a[k - 1]] = p; } } else { assert (a[k] == 1); if (s->bal == +1) { s->bal = 0; continue; } else if (s->bal == 0) { s->bal = -1; break; } assert (s->bal == -1); r = s->link[0]; if (r == NULL || r->bal == 0) { s->link[0] = r->link[1]; r->link[1] = s; r->bal = 1; pa[k - 1]->link[(int) a[k - 1]] = r; break; } else if (r->bal == -1) { s->link[0] = r->link[1]; r->link[1] = s; s->bal = r->bal = 0; pa[k - 1]->link[(int) a[k - 1]] = r; } else if (r->bal == +1) { p = r->link[1]; r->link[1] = p->link[0]; p->link[0] = r; s->link[0] = p->link[1]; p->link[1] = s; if (p->bal == -1) s->bal = 1, r->bal = 0; else if (p->bal == 0) s->bal = r->bal = 0; else { assert (p->bal == 1); s->bal = 0, r->bal = -1; } p->bal = 0; pa[k - 1]->link[(int) a[k - 1]] = p; } } } internal_unlock_mutex(&tree->mutex); return (void *) item; }