Beispiel #1
0
_WPRTLINK void WCHashBase::base_construct( const WCHashBase * orig ) {
    WCExcept::base_construct( orig );
    num_buckets = orig->num_buckets;
    if( num_buckets <= 0 ) return;
    num_entries = 0;
    if( !hash_array ) {
        // hash_array must be allocated or NULL before
        // base_construct is called
        num_buckets = 0;
        base_throw_out_of_memory();
    } else {
        WCIsvSListIter<BaseHashLink> iter;
        BaseHashLink * link;
        BaseHashLink * new_link;
        // copy elements, making sure num_entries is always correct
        for( int i = 0; i < num_buckets; i++ ) {
            iter.reset( orig->hash_array[ i ] );
            for( ;; ) {
                link = ++iter;
                if( link == 0 ) break;
                new_link = base_copy_link( link );
                if( new_link == 0 ) {
                    base_throw_out_of_memory();
                    return;
                }
                hash_array[ i ].append( new_link );
                num_entries++;
            }
        }
    }
};
Beispiel #2
0
_WPRTLINK WCbool WCHashBase::insert( TTypePtr elem ) {
    if( num_buckets == 0 ) {
        base_throw_out_of_memory();
        return( false );
    }
    BaseHashLink * link = WCHashNew( elem );
    if( link == 0 ) {
        base_throw_out_of_memory();
        return( false );
    }
    hash_array[ base_get_bucket( elem ) ].append( link );
    num_entries++;
    return( true );
}
Beispiel #3
0
_WPRTLINK void WCHashBase::resize( unsigned buckets ) {
    if( buckets <= 0 ) {
        base_throw_zero_buckets();
        return;
    }
    WCIsvSList<BaseHashLink> * new_hash_array;
    new_hash_array = new WCIsvSList<BaseHashLink>[ buckets ];
    if( new_hash_array == 0 ) {
        base_throw_out_of_memory();
        return;
    }
    unsigned old_buckets = num_buckets;
    num_buckets = buckets;
    BaseHashLink * link;
    // we need to rehash all the values on a resize
    for( int i = 0; i < old_buckets; i++ ) {
        for( ;; ) {
            link = hash_array[ i ].get();
            if( link == 0 ) break;
            new_hash_array[ base_get_bucket_for_link( link ) ].append( link );
        }
    }
    delete [] hash_array;
    hash_array = new_hash_array;
}
Beispiel #4
0
_WPRTLINK WCSLink * WCHashBase::base_set_insert( TTypePtr elem ) {
    unsigned bucket = 0;
    unsigned index = 0;
    if( base_find( elem, &bucket, &index, FIND_FIRST ) == 0 ) {
        if( num_buckets == 0 ) {
            base_throw_out_of_memory();
            return( 0 );
        }
        BaseHashLink * link = WCHashNew( elem );
        if( link == 0 ) {
            base_throw_out_of_memory();
            return( 0 );
        }
        hash_array[ bucket ].append( link );
        num_entries++;
        return( link );
    }
    // find succeeded: an equivalent element was previously in the hash set
    base_throw_not_unique();
    return( 0 );
};
Beispiel #5
0
_WPRTLINK WCSkipListPtrs * WCSkipNonTempBase::base_insert( TTypePtr elem ) {
    int k;
    node_ptr curr;
    node_ptr found;
    node_ptr new_node;
    node_ptr update[ WCSKIPLIST_MAX_PTRS ];

    // find where to insert elem
    found = base_find_with_update( elem, update );

    if( !allowDuplicates && found != 0 ) {
        // duplicates are not allowed for sets and dictionaries
        base_throw_not_unique();
        return( 0 );
    }

    // insert elem after all elements less than elem
    k = base_random_level();
    if( k > level ) {
        // Make sure the new node has a maximum level more than one than the
        // current maximum level in the skip list.
        k = ++level;
        update[ k ] = header;
    }

    // allocate a new node, initailized with elem
    new_node = base_new_node( elem, k );
    if( new_node == 0 ) {
        base_throw_out_of_memory();
        return( 0 );
    }

    // link new_node into the skip list
    do {
        curr = update[ k ];
        new_node->forward[ k ] = curr->forward[ k ];
        curr->forward[ k ] = new_node;
    } while( --k >= 0 );
    num_entries++;
    return( new_node );
}