Esempio n. 1
0
void* hashFind(
	Hashtable         tbl, 
    void*             key)
{
	HashItem* itemPtr = hashFindInternal(tbl, key);
    HashItem  item = *itemPtr;

	if (item != NULL)
       return GET_HASH_KEY(item);

    return NULL;
}
Esempio n. 2
0
//-----------------------------------------------------------------------------------------------------------------------
CResourceBase* EAssetMgr::CreateResource( eRESOURCE_TYPE type, const char* name)
{
	if( GetResource(type , name) != NULL )
	{
		assert(0);
		return NULL;
	}

	CResourceBase* pResource = MemGetNew(type);

	pResource->loadState = RESOURCE_MEMORY_CREATED;
	pResource->RID = GET_HASH_KEY( name );
	strcpy_s( pResource->name, name);
	m_ResourceMap[type].SetAt( pResource->RID, pResource );

	return pResource;
}
Esempio n. 3
0
TEST(insert_many_ids_into_same_list, then_hash_list_must_be_filled)
{
	int      listId   = 11111111 & tbl->lowMask;
	int      sNum     = listId >> tbl->segmShift; 
	int      sInd     = listId & (tbl->segmSize - 1);
	HashItem listPtr  = tbl->segments[sNum][sInd];
    int      numItems = 0;
	int      key      = -1;

    while (listPtr != NULL)
	{
        key = *(int*)GET_HASH_KEY(listPtr);
        TEST_ASSERT_EQUAL_UINT32(key, numItems++);
        listPtr = listPtr->next;
	}

    TEST_ASSERT_EQUAL_UINT32(numItems, 1000);
}
Esempio n. 4
0
HashItem* hashFindInternal(
	Hashtable         tbl, 
    void*             key)
{
	HashSegment       segm;
	HashItem*         itemPtr;
	HashItem          item;
    uint              keyLen  = tbl->keyLen;
	hashCmpFunc       cmpFunc = tbl->hashCmp;
    uint              hash    = tbl->hashFunc(key, keyLen);
    uint              listId, sNum, sInd;

	listId = convertHashToListNumber(tbl, hash);

	/* Segment size always is a power of 2: 2^n.
	 * SegmentSize  is 2^n.
	 * SegmentShift is n.
	 * listId we can represent: listId = segmSize * sNum + sInd;
	 * So sNum = listId/segmSize, sInd = listId mod segmSize;
	 * When we operate with powers of 2, we can compute these operations
	 * using only bitwise operations
	 */
	sNum = listId >> tbl->segmShift; 
	sInd = listId & (tbl->segmSize - 1);

	segm    = tbl->segments[sNum];
    itemPtr = &segm[sInd];
    item    = *itemPtr;

	while (item != NULL)
	{
		if (item->hash == hash && cmpFunc(GET_HASH_KEY(item), key, keyLen) == 0)
			break;

		itemPtr = &(item->next);
		item    = *itemPtr;
	}

	return itemPtr;
}
Esempio n. 5
0
void* hashRemove(
	void*             self,
    Hashtable         tbl, 
    void*             key)
{
    IHashtableManager _       = (IHashtableManager)self;
    ISpinLockManager  slog    = (ISpinLockManager)_->spinLockHelper; 

	HashItem*    itemPtr;
    HashItem     item;
    HashItem     newElem = tbl->freeList;

	uint         keyLen  = tbl->keyLen;
    uint         hash    = tbl->hashFunc(key, keyLen); 

	/* We need to explain why we use volatile keyword.
	 * We need to pass along volatile long* parameter 
     * to spinlockmanager spinLockAcquire method.
	 * When we declare volatile Hashtable tblLocal
	 * we receive the following declaration:
	 *   
	 *   typedef struct SHashtable
     *   {
	 *       HANDLE   mutex;
	 *       ...
	 *   };
	 *   
	 *   volatile SHashtable tbl;  will be converted to:
     *        
	 *   typedef struct SHashtable
	 *   {   
	 *       volatile HANDLE mutex 
	 *       ...
	 *   };
	 *
	 * So that we can put &(tbl->mutex) into SPIN_LOCK_ACQUIRE.
	 */
	volatile Hashtable tblLocal = tbl; 

    itemPtr = hashFindInternal(tblLocal, key);
    item    = *itemPtr;

	if (item == NULL)
		return NULL;

	if (IS_TABLE_PARTITIONED(tblLocal))
		SPIN_LOCK_ACQUIRE(slog, &(tblLocal->mutex));

    tblLocal->numItems--;

	/* Remove the item from a cache's list. */
	*itemPtr = item->next;

	/* Add the item to the free list. */
	item->next         = tblLocal->freeList;
	tblLocal->freeList = item;
    
	if (IS_TABLE_PARTITIONED(tblLocal))
        SPIN_LOCK_RELEASE(slog, &(tblLocal->mutex));

	return GET_HASH_KEY(item);
}
Esempio n. 6
0
void* hashInsert(
	void*             self,
    Hashtable         tbl, 
    void*             key)
{
	IHashtableManager _    = (IHashtableManager)self;
	ISpinLockManager  slog = (ISpinLockManager)_->spinLockHelper; 

    HashItem*    itemPtr;
    HashItem     item;
    HashItem     newElem;
	uint         keyLen       = tbl->keyLen;
    uint         hash         = tbl->hashFunc(key, keyLen);
    Bool         needToExtend = tbl->numItems > tbl->hashListSize * tbl->numHashLists;

	/* We assume that our hash function produces completely 
	 * uniformly distributed data. We can compute the average
	 * amount of items in each hash list.
	 * tbl->hashListSize is expected average hash list size.
	 * If we exceed this number, we need to add a new hash list */
	if (!IS_TABLE_PARTITIONED(tbl) && needToExtend && !tbl->isWithoutExtention)
	   extendHashTable(self, tbl);

	itemPtr = hashFindInternal(tbl, key);
    item    = *itemPtr;

	if (item != NULL)
        return GET_HASH_KEY(item);

	CYCLE
	{
        if (IS_TABLE_PARTITIONED(tbl))
	        SPIN_LOCK_ACQUIRE(slog, &(tbl->mutex)); 
   
        newElem = tbl->freeList;             

		if (newElem != NULL)
			break;

        if (IS_TABLE_PARTITIONED(tbl))
            SPIN_LOCK_RELEASE(slog, &(tbl->mutex));
        
		if (!allocNewItems(_, tbl->numItemsToAlloc))
            return NULL;
	}

	/* Remove the first entry from freeList */
	tbl->freeList = newElem->next;
	tbl->numItems++;

    if (IS_TABLE_PARTITIONED(tbl))
        SPIN_LOCK_RELEASE(slog, &(tbl->mutex));

	*itemPtr = newElem;

	newElem->next = NULL;
	newElem->hash = hash;
            
    /* SHashItem is a struct with wo fileds: next and hash.
     * There are no other fields. We want to attach the whole key
     * to the end of the memory the pointer to SHashItem points to.
     * Before we need to align already allocated memory.
     * Memory will look like here:
     * 
     * [...next...][...hash....][..aligned..][....aligned..key.......][..aligned..value....] 
     * |<------ SHashItem ---->|            |
     * |<--------- aligned SHashItem ------>|
     */
	tbl->hashCpy(GET_HASH_KEY(newElem), key, keyLen);

	return GET_HASH_KEY(newElem);
}