示例#1
0
int pblHtRemove(
pblHashTable_t            * h,     /** hash table to remove from           */
void                      * key,   /** OPT: key to remove                  */
size_t                      keylen /** OPT: length of that key             */
)
{
    pbl_hashtable_t  * ht = ( pbl_hashtable_t * )h;
    pbl_hashbucket_t * bucket = 0;
    pbl_hashitem_t   * item = 0;

    int                hashval = 0;

    if( keylen && key )
    {
        hashval = hash( key, keylen );
        bucket = ht->buckets + hashval;

        for( item = bucket->head; item; item = item->bucketnext )
        {
            if(( item->keylen == keylen ) && !memcmp( item->key, key, keylen ))
            {
                break;
            }
        }
    }
    else
    {
        item = ht->current;

        if( item )
        {
            hashval = hash( item->key, item->keylen );
            bucket = ht->buckets + hashval;
        }
    }

    if( item )
    {
        if( item == ht->current )
        {
            ht->currentdeleted = 1;
            ht->current = item->next;
        }

        /*
         * unlink the item
         */
        PBL_LIST_UNLINK( bucket->head, bucket->tail, item,
                         bucketnext, bucketprev );
        PBL_LIST_UNLINK( ht->head, ht->tail, item, next, prev );

        PBL_FREE( item->key );
        PBL_FREE( item );
        return( 0 );
    }

    pbl_errno = PBL_ERROR_NOT_FOUND;
    return( -1 );
}
/**
 * Removes from the underlying list or tree set the last element returned by the iterator.
 *
 * This method can be called only once per call to next or previous.
 * It can be made only if pblIteratorAdd() has not been called after the last call to next or previous.
 *
 * For array lists this method has a time complexity of O(N),
 * with N being the number of elements in the underlying list.
 *
 * For linked lists and hash sets this method has a time complexity of O(1).
 *
 * For tree sets this method has a time complexity of O(Log N),
 * with N being the number of elements in the underlying collection.
 *
 * @return int rc >= 0: The size of the collection.
 * @return int rc <  0: An error, see pbl_errno:
 *
 * <BR>PBL_ERROR_NOT_ALLOWED - The the next or previous method has not yet been called,
 *                         or the remove method has already been called after the last call to the next or previous method.
 *
 * <BR>PBL_ERROR_CONCURRENT_MODIFICATION - The underlying list or tree set was modified concurrently.
 * <BR>PBL_ERROR_PARAM_LIST              - The underlying collection is neither a list nor a tree set.
 */
int pblIteratorRemove(
PblIterator * iterator /** The iterator to remove the next element from */
)
{
    if( iterator->changeCounter != iterator->collection->changeCounter )
    {
        pbl_errno = PBL_ERROR_CONCURRENT_MODIFICATION;
        return -1;
    }

    if( PBL_SET_IS_TREE_SET( iterator->collection ) )
    {
        PblTreeIterator * treeIterator = (PblTreeIterator *)iterator;

        if( !treeIterator->current )
        {
            pbl_errno = PBL_ERROR_NOT_ALLOWED;
            return -1;
        }
        else
        {
            if( treeIterator->next == treeIterator->current )
            {
                treeIterator->next = pblTreeNodeNext( treeIterator->next );
            }
            else if( treeIterator->prev == treeIterator->current )
            {
                treeIterator->prev = pblTreeNodePrevious( treeIterator->prev );
            }

            pblSetRemoveElement( (PblSet*)treeIterator->collection,
                                 treeIterator->current->element );
        }
    }
    else if( PBL_LIST_IS_LINKED_LIST( iterator->collection ) )
    {
        if( !iterator->current )
        {
            pbl_errno = PBL_ERROR_NOT_ALLOWED;
            return -1;
        }
        else
        {
            PblLinkedList * linkedList = (PblLinkedList *)iterator->collection;
            PblLinkedNode * nodeToFree = iterator->current;

            if( iterator->next == iterator->current )
            {
                iterator->next = iterator->next->next;
            }
            else if( iterator->prev == iterator->current )
            {
                iterator->prev = iterator->prev->prev;
            }

            PBL_LIST_UNLINK( linkedList->head, linkedList->tail, nodeToFree, next, prev );
            linkedList->genericList.size--;
            linkedList->genericList.changeCounter++;

            PBL_FREE( nodeToFree );
        }
    }
    else if( PBL_LIST_IS_ARRAY_LIST( iterator->collection ) )
    {
        if( iterator->lastIndexReturned < 0 )
        {
            pbl_errno = PBL_ERROR_NOT_ALLOWED;
            return -1;
        }

        if( pblArrayListRemoveAt( (PblArrayList*)iterator->collection,
                                  iterator->lastIndexReturned ) == (void*)-1 )
        {
            return -1;
        }
    }
    else
    {
        pbl_errno = PBL_ERROR_PARAM_LIST;
        return -1;
    }

    if( iterator->lastIndexReturned < iterator->index )
    {
        iterator->index--;
    }

    iterator->current = NULL;
    iterator->lastIndexReturned = -1;

    iterator->changeCounter = iterator->collection->changeCounter;

    return iterator->collection->size;
}