/* Add (k,v) to fm. */ void addToFM ( WordFM* fm, Word k, Word v ) { MaybeWord oldV; AvlNode* node; node = fm->alloc_nofail( sizeof(struct _AvlNode) ); node->key = k; node->val = v; oldV.b = False; oldV.w = 0; avl_insert_wrk( &fm->root, &oldV, node, fm->kCmp ); //if (oldV.b && fm->vFin) // fm->vFin( oldV.w ); if (oldV.b) free(node); }
/* Add (k,v) to fm. */ Bool VG_(addToFM) ( WordFM* fm, UWord k, UWord v ) { MaybeWord oldV; AvlNode* node; node = fm->alloc_nofail( fm->cc, sizeof(AvlNode) ); node->key = k; node->val = v; oldV.b = False; oldV.w = 0; avl_insert_wrk( &fm->root, &oldV, node, fm->kCmp ); //if (oldV.b && fm->vFin) // fm->vFin( oldV.w ); if (oldV.b) fm->dealloc(node); return oldV.b; }
/* Insert element a into the AVL tree t. Returns True if the depth of the tree has grown. If element with that key is already present, just copy a->val to existing node, first returning old ->val field of existing node in *oldV, so that the caller can finalize it however it wants. */ static Bool avl_insert_wrk ( AvlNode** rootp, /*OUT*/MaybeWord* oldV, AvlNode* a, Word (*kCmp)(Word,Word) ) { Word cmpres; /* initialize */ a->left = 0; a->right = 0; a->balance = 0; oldV->b = False; /* insert into an empty tree? */ if (!(*rootp)) { (*rootp) = a; return True; } cmpres = kCmp( (*rootp)->key, a->key ); if (cmpres > 0) { /* insert into the left subtree */ if ((*rootp)->left) { AvlNode* left_subtree = (*rootp)->left; if (avl_insert_wrk(&left_subtree, oldV, a, kCmp)) { switch ((*rootp)->balance--) { case 1: return False; case 0: return True; case -1: break; default: assert(0); } if ((*rootp)->left->balance < 0) { avl_swr( rootp ); (*rootp)->balance = 0; (*rootp)->right->balance = 0; } else { avl_swl( &((*rootp)->left) ); avl_swr( rootp ); avl_nasty( *rootp ); } } else { (*rootp)->left = left_subtree; } return False; } else { (*rootp)->left = a; if ((*rootp)->balance--) return False; return True; } assert(0);/*NOTREACHED*/ } else if (cmpres < 0) { /* insert into the right subtree */ if ((*rootp)->right) { AvlNode* right_subtree = (*rootp)->right; if (avl_insert_wrk(&right_subtree, oldV, a, kCmp)) { switch((*rootp)->balance++) { case -1: return False; case 0: return True; case 1: break; default: assert(0); } if ((*rootp)->right->balance > 0) { avl_swl( rootp ); (*rootp)->balance = 0; (*rootp)->left->balance = 0; } else { avl_swr( &((*rootp)->right) ); avl_swl( rootp ); avl_nasty( *rootp ); } } else { (*rootp)->right = right_subtree; } return False; } else { (*rootp)->right = a; if ((*rootp)->balance++) return False; return True; } assert(0);/*NOTREACHED*/ } else { /* cmpres == 0, a duplicate - replace the val, but don't incorporate the node in the tree */ oldV->b = True; oldV->w = (*rootp)->val; (*rootp)->val = a->val; return False; } }