コード例 #1
0
ファイル: pblhash.c プロジェクト: rafaelkonrath/tuxguardian
/**
 * create a new hash table
 *
 * @return pblHashTable_t * retptr != NULL: pointer to new hash table
 * @return pblHashTable_t * retptr == NULL: OUT OF MEMORY
 */
pblHashTable_t * pblHtCreate( void )
{
    pbl_hashtable_t * ht;

    ht = pbl_malloc0( "pblHtCreate hashtable", sizeof( pbl_hashtable_t ) );
    if( !ht )
    {
        return( 0 );
    }

    ht->buckets = pbl_malloc0( "pblHtCreate buckets",
                               sizeof( pbl_hashbucket_t ) * PBL_HASHTABLE_SIZE);
    if( !ht->buckets )
    {
        PBL_FREE( ht );
        return( 0 );
    }

    /*
     * set the magic marker of the hashtable
     */
    ht->magic = rcsid;

    return( ( pblHashTable_t * )ht );
}
コード例 #2
0
ファイル: pblhash.c プロジェクト: rafaelkonrath/tuxguardian
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 );
}
コード例 #3
0
/**
 * Removes the mapping for this key from this map if it is present.
 *
 * More formally, if this map contains a mapping from a key k to a value v such that
 * (key==null ? k==null : memcmp( key, k, keyLength ) == 0,
 * that mapping is removed.
 * (The map can contain at most one such mapping.)
 *
 * Returns the previous value associated with key,
 * NULL if there was no mapping for key
 * or (void*)-1 in case of an error.
 *
 * Note: If a valid pointer to a value is returned, the value returned is
 * malloced on the heap. It is the caller's responsibility to free that memory
 * once it is no longer needed.
 *
 * For hash maps this method has a time complexity of O(1).
 * For tree maps this method has a time complexity of O(Log N).
 *
 * @return void * retptr != (void*)-1: The previously associated value.
 * @return void * retptr == (void*)-1: An error, see pbl_errno:
 *
 * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory.
 */
void * pblMapRemove( /*                                             */
PblMap * map, /**                            The map to remove from */
void * key, /**                    Key whose association is removed */
size_t keyLength, /**                             Length of the key */
size_t * valueLengthPtr /**       Out: Length of the value returned */
)
{
    PblMapEntry * mapEntry;
    void * retptr = NULL;
    PblMapKey mapKey;

    mapKey.tag = PBL_MAP_KEY_TAG;
    mapKey.keyLength = keyLength;
    mapKey.key = key;

    mapEntry = (PblMapEntry *)pblSetGetElement( map->entrySet, &mapKey );
    if( !mapEntry )
    {
        if( valueLengthPtr )
        {
            *valueLengthPtr = 0;
        }
        return NULL;
    }

    if( mapEntry->valueLength > 0 )
    {
        retptr = pbl_memdup( "pblMapRemove", mapEntry->buffer
                + mapEntry->keyLength, mapEntry->valueLength );
    }
    else
    {
        retptr = pbl_malloc0( "pblMapRemove0", 1 );
    }
    if( !retptr )
    {
        if( valueLengthPtr )
        {
            *valueLengthPtr = 0;
        }
        return (void*)-1;
    }

    if( valueLengthPtr )
    {
        *valueLengthPtr = mapEntry->valueLength;
    }

    pblSetRemoveElement( map->entrySet, mapEntry );

    PBL_FREE( mapEntry );

    return retptr;
}
コード例 #4
0
/**
 * Creates a new hash map.
 *
 * This method has a time complexity of O(1).
 *
 * @return PblMap * retPtr != NULL: A pointer to the new map.
 * @return PblMap * retPtr == NULL: An error, see pbl_errno:
 *
 * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory.
 */
PblMap * pblMapNewHashMap( void )
{
    PblMap * pblMap = (PblMap *)pbl_malloc0( "pblMapNewHashMap", sizeof(PblMap) );
    if( !pblMap )
    {
        return NULL;
    }

    pblMap->entrySet = pblSetNewHashSet();
    if( !pblMap->entrySet )
    {
        PBL_FREE( pblMap );
        return NULL;
    }

    pblSetSetCompareFunction( pblMap->entrySet, pblMapEntryCompareFunction );
    pblSetSetHashValueFunction( pblMap->entrySet, pblMapEntryHashValue );

    return pblMap;
}
コード例 #5
0
/**
 * Associates the specified value with the specified key in this map.
 *
 * If the map previously contained a mapping for the key, the old value is replaced by the specified value.
 * (A map m is said to contain a mapping for a key k if and only if pblMapContainsKey(k) would return true.)
 *
 * Returns the previous value associated with key, NULL if there was no mapping for key
 * or (void*)-1 in case of an error.
 *
 * Note: If a valid pointer to a value is returned, the value returned is
 * malloced on the heap. It is the caller's responsibility to free that memory
 * once it is no longer needed.
 *
 * For hash maps this method has a time complexity of O(1).
 * For tree maps this method has a time complexity of O(Log N).
 *
 * @return void * retptr != (void*)-1: The previously associated value.
 * @return void * retptr == NULL: There was no previously associated value.
 * @return void * retptr == (void*)-1: An error, see pbl_errno:
 *
 * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory.
 * <BR>PBL_ERROR_OUT_OF_BOUNDS - Maximum capacity of the hash set exceeded.
 */
void * pblMapPut( /*                                                   */
PblMap * map, /**                                    The map to add to */
void * key, /**                               Key to add a mapping for */
size_t keyLength, /**                                Length of the key */
void * value, /**                             Value of the new mapping */
size_t valueLength, /**                            Length of the value */
size_t * valueLengthPtr /**          Out: Length of the value returned */
)
{
    int rc;
    PblMapEntry * mapEntry;
    PblMapEntry * newEntry =
            pblMapEntryNew( key, keyLength, value, valueLength );
    if( !newEntry )
    {
        return (void*)-1;
    }

    mapEntry = (PblMapEntry *)pblSetReplaceElement( map->entrySet, newEntry );
    if( mapEntry )
    {
        void * retptr;

        if( mapEntry->valueLength > 0 )
        {
            retptr = pbl_memdup( "pblMapPut", mapEntry->buffer
                    + mapEntry->keyLength, mapEntry->valueLength );
        }
        else
        {
            retptr = pbl_malloc0( "pblMapPut0", 1 );
        }
        if( !retptr )
        {
            if( valueLengthPtr )
            {
                *valueLengthPtr = 0;
            }
            pblSetReplaceElement( map->entrySet, mapEntry );
            PBL_FREE( newEntry );
            return (void*)-1;
        }

        if( valueLengthPtr )
        {
            *valueLengthPtr = mapEntry->valueLength;
        }
        PBL_FREE( mapEntry );
        return retptr;
    }

    if( valueLengthPtr )
    {
        *valueLengthPtr = 0;
    }

    rc = pblSetAdd( map->entrySet, newEntry );
    if( rc < 0 )
    {
        PBL_FREE(newEntry);
        return (void*)-1;
    }

    return NULL;
}