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

    int                hashval = hash( key, keylen );
    
    bucket = ht->buckets + hashval;

    if( keylen < (size_t)1 )
    {
        /*
         * the length of the key can not be smaller than 1
         */
        pbl_errno = PBL_ERROR_EXISTS;
        return( -1 );
    }

    for( item = bucket->head; item; item = item->bucketnext )
    {
        if(( item->keylen == keylen ) && !memcmp( item->key, key, keylen ))
        {
            snprintf( pbl_errstr, PBL_ERRSTR_LEN,
                      "insert of duplicate item in hashtable\n" );
            pbl_errno = PBL_ERROR_EXISTS;
            return( -1 );
        }
    }

    item = pbl_malloc0( "pblHtInsert hashitem", sizeof( pbl_hashitem_t ) );
    if( !item )
    {
        return( -1 );
    }

    item->key = pbl_memdup( "pblHtInsert item->key", key, keylen );
    if( !item->key )
    {
        PBL_FREE( item );
        return( -1 );
    }
    item->keylen = keylen;
    item->data = dataptr;

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

    ht->current = item;
    return( 0 );
}
/**
 * Inserts the specified element into the underlying collection.
 *
 * The element is inserted immediately before the next element that would be returned by next,
 * if any, and after the next element that would be returned by previous, if any.
 *
 * If the list contains no elements, the new element becomes the sole element on the list.
 *
 * The new element is inserted before the implicit cursor:
 * a subsequent call to next would be unaffected,
 * and a subsequent call to previous would return the new element.
 * This call increases by one the value that would be returned by a
 * call to nextIndex or previousIndex.
 *
 * 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 this method has a time complexity of O(1).
 *
 * @return int rc >= 0: The size of the list.
 * @return int rc <  0: An error, see pbl_errno:
 *
 * <BR>PBL_ERROR_OUT_OF_MEMORY           - Out of memory.
 * <BR>PBL_ERROR_CONCURRENT_MODIFICATION - The underlying list was modified concurrently.
 * <BR>PBL_ERROR_PARAM_LIST              - The underlying collection is not a list.
 */
int pblIteratorAdd(
PblIterator * iterator, /** The iterator to add the element to */
void * element          /** Element to be added to this list   */
)
{
    PblList * list = (PblList*)iterator->collection;

    if( !PBL_LIST_IS_LIST( list ) )
    {
        pbl_errno = PBL_ERROR_PARAM_LIST;
        return -1;
    }

    if( iterator->changeCounter != list->changeCounter )
    {
        pbl_errno = PBL_ERROR_CONCURRENT_MODIFICATION;
        return -1;
    }

    if( list->size == 0 )
    {
        if( pblListAdd( (PblList*)list, element ) < 1 )
        {
            return -1;
        }

        iterator->index = 1;
        iterator->next = NULL;

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

        if( PBL_LIST_IS_LINKED_LIST( list ) )
        {
            PblLinkedList * linkedList = (PblLinkedList*)list;
            iterator->prev = linkedList->tail;
        }
        iterator->changeCounter = list->changeCounter;
        return 1;
    }

    if( PBL_LIST_IS_ARRAY_LIST( list ) )
    {
        int rc = pblListAddAt( (PblList*)list, iterator->index, element );
        if( rc < 0 )
        {
            return -1;
        }
    }
    else
    {
        PblLinkedList * linkedList = (PblLinkedList*)list;
        PblLinkedNode * newNode = pbl_malloc( "pblIteratorAdd",
                                              sizeof(PblLinkedNode) );
        if( !newNode )
        {
            return -1;
        }
        newNode->element = element;

        if( !iterator->next )
        {
            PBL_LIST_APPEND( linkedList->head, linkedList->tail, newNode, next, prev );
        }
        else
        {
            PBL_LIST_INSERT( linkedList->head, iterator->next, newNode, next, prev );
        }
        linkedList->genericList.size++;
        linkedList->genericList.changeCounter++;

        iterator->prev = newNode;
    }

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

    iterator->index++;

    iterator->changeCounter = list->changeCounter;
    return list->size;
}