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; }