示例#1
0
/* 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);
}
示例#2
0
/* 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;
}
示例#3
0
/* 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;
    }
}