hash.c revision e0e0c19eefceaf5d4ec40f9466b58a771f50e799
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* Copyright (c) 2001, Stanford University
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * All rights reserved
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * See the file LICENSE.txt for information on redistributing this software.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_threads.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_hash.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_mem.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_error.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define CR_MAXUINT ((GLuint) 0xFFFFFFFF)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define CR_NUM_BUCKETS 1047
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynctypedef struct FreeElemRec {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint min;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint max;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync struct FreeElemRec *next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync struct FreeElemRec *prev;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync} FreeElem;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynctypedef struct CRHashIdPoolRec {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeElem *freeList;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync} CRHashIdPool;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynctypedef struct CRHashNode {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned long key;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync void *data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync struct CRHashNode *next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync} CRHashNode;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstruct CRHashTable {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int num_elements;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *buckets[CR_NUM_BUCKETS];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashIdPool *idPool;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRmutex mutex;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic CRHashIdPool *crAllocHashIdPool( void )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashIdPool *pool = (CRHashIdPool *) crCalloc(sizeof(CRHashIdPool));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList = (FreeElem *) crCalloc(sizeof(FreeElem));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList->min = 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList->max = CR_MAXUINT;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList->next = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList->prev = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return pool;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void crFreeHashIdPool( CRHashIdPool *pool )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeElem *i, *next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = pool->freeList; i; i = next)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync next = i->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree(i);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree(pool);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Allocate a block of <count> IDs. Return index of first one.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Return 0 if we fail.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic GLuint crHashIdPoolAllocBlock( CRHashIdPool *pool, GLuint count )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeElem *f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint ret;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(count > 0);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f = pool->freeList;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (f)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (f->max - f->min + 1 >= (GLuint) count)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* found a sufficiently large enough block */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ret = f->min;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f->min += count;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (f->min == f->max)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* remove this block from linked list */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (f == pool->freeList)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* remove from head */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList = pool->freeList->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList->prev = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* remove from elsewhere */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f->prev->next = f->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f->next->prev = f->prev;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree(f);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef DEBUG
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* make sure the IDs really are allocated */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0; i < count; i++)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync //CRASSERT(crHashIdPoolIsIdUsed(pool, ret + i));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return ret;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f = f->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* failed to find free block */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crDebug("crHashIdPoolAllocBlock failed");
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Free a block of <count> IDs starting at <first>.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void crHashIdPoolFreeBlock( CRHashIdPool *pool, GLuint first, GLuint count )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeElem *i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeElem *newelem;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /*********************************/
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Add the name to the freeList */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Find the bracketing sequences */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = pool->freeList; i && i->next && i->next->min < first; i = i->next)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* EMPTY BODY */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* j will always be valid */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!i) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!i->next && i->max == first) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Case: j:(~,first-1) */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i->max + 1 == first)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->max += count;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i->next && i->max+1 >= i->next->min)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Collapse */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->next->min = i->min;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->next->prev = i->prev;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i->prev)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->prev->next = i->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i == pool->freeList)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList = i->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree(i);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Case: j->next: (first+1, ~) */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i->next && i->next->min - count == first)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->next->min -= count;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i->max + 1 >= i->next->min)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Collapse */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->next->min = i->min;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->next->prev = i->prev;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i->prev)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->prev->next = i->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i == pool->freeList)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList = i->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree(i);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Case: j: (first+1, ~) j->next: null */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!i->next && i->min - count == first)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->min -= count;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* allocate a new FreeElem node */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem = (FreeElem *) crCalloc(sizeof(FreeElem));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->min = first;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->max = first + count - 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Case: j: (~,first-(2+)) j->next: (first+(2+), ~) or null */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (first > i->max)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->prev = i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->next = i->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i->next)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->next->prev = newelem;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->next = newelem;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Case: j: (first+(2+), ~) */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Can only happen if j = t->freeList! */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i == pool->freeList && i->min > first)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->next = i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->prev = i->prev;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync i->prev = newelem;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pool->freeList = newelem;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Mark the given Id as being allocated.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void crHashIdPoolAllocId( CRHashIdPool *pool, GLuint id )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeElem *f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f = pool->freeList;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (f)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (id >= f->min && id <= f->max)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* found the block */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (id == f->min)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f->min++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if (id == f->max)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f->max--;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* somewhere in the middle - split the block */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeElem *newelem = (FreeElem *) crCalloc(sizeof(FreeElem));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->min = id + 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->max = f->max;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f->max = id - 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->next = f->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (f->next)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f->next->prev = newelem;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync newelem->prev = f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f->next = newelem;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f = f->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* if we get here, the ID was already allocated - that's OK */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Determine if the given id is free. Return GL_TRUE if so.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic GLboolean crHashIdPoolIsIdFree( const CRHashIdPool *pool, GLuint id )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeElem *i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* First find which region it fits in */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = pool->freeList; i && !(i->min <= id && id <= i->max); i=i->next)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* EMPTY BODY */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (i)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return GL_TRUE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return GL_FALSE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncCRHashTable *crAllocHashtable( void )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashTable *hash = (CRHashTable *) crCalloc( sizeof( CRHashTable )) ;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync hash->num_elements = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0 ; i < CR_NUM_BUCKETS ; i++)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync hash->buckets[i] = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync hash->idPool = crAllocHashIdPool();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crInitMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return hash;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crFreeHashtable( CRHashTable *hash, CRHashtableCallback deleteFunc )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( !hash) return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( i = 0; i < CR_NUM_BUCKETS; i++ )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( hash->buckets[i] )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (hash->buckets[i]->data && deleteFunc) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Clear the key in case crHashtableDelete() is called
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * from this callback.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync hash->buckets[i]->key = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (*deleteFunc)( hash->buckets[i]->data );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree( hash->buckets[i] );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFreeHashIdPool( hash->idPool );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFreeMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree( hash );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crHashtableWalk( CRHashTable *hash, CRHashtableWalkCallback walkFunc , void *dataPtr2)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *entry, *next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!hash)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0; i < CR_NUM_BUCKETS; i++)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync entry = hash->buckets[i];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (entry)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* save next ptr here, in case walkFunc deletes this entry */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync next = entry->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (entry->data && walkFunc) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (*walkFunc)( entry->key, entry->data, dataPtr2 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync entry = next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic unsigned int crHash( unsigned long key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return key % CR_NUM_BUCKETS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crHashtableAdd( CRHashTable *h, unsigned long key, void *data )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *node = (CRHashNode *) crCalloc( sizeof( CRHashNode ) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync node->key = key;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync node->data = data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync node->next = h->buckets[crHash( key )];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync h->buckets[ crHash( key ) ] = node;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync h->num_elements++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crHashIdPoolAllocId (h->idPool, key);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncGLuint crHashtableAllocKeys( CRHashTable *h, GLsizei range)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint res;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync res = crHashIdPoolAllocBlock (h->idPool, range);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( i = 0; i < range; i++)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crHashtableAdd( h, i + res , NULL );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return res;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crHashtableDelete( CRHashTable *h, unsigned long key, CRHashtableCallback deleteFunc )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int index = crHash( key );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *temp, *beftemp = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( temp = h->buckets[index]; temp; temp = temp->next )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( temp->key == key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync beftemp = temp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( !temp ) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return; /* not an error */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( beftemp )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync beftemp->next = temp->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync h->buckets[index] = temp->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync h->num_elements--;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (temp->data && deleteFunc) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (*deleteFunc)( temp->data );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree( temp );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crHashIdPoolFreeBlock( h->idPool, key, 1 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crHashtableDeleteBlock( CRHashTable *h, unsigned long key, GLsizei range, CRHashtableCallback deleteFunc )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* XXX optimize someday */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0; i < (GLuint)range; i++) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crHashtableDelete( h, key, deleteFunc );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid *crHashtableSearch( const CRHashTable *h, unsigned long key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int index = crHash( key );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *temp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex((CRmutex *)&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( temp = h->buckets[index]; temp; temp = temp->next )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( temp->key == key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex((CRmutex *)&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( !temp )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return temp->data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crHashtableReplace( CRHashTable *h, unsigned long key, void *data,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashtableCallback deleteFunc)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int index = crHash( key );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *temp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( temp = h->buckets[index]; temp; temp = temp->next )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( temp->key == key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( !temp )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crHashtableAdd( h, key, data );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( temp->data && deleteFunc )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (*deleteFunc)( temp->data );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync temp->data = data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncunsigned int crHashtableNumElements( const CRHashTable *h)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (h)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return h->num_elements;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Determine if the given key is used. Return GL_TRUE if so.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncGLboolean crHashtableIsKeyUsed( const CRHashTable *h, GLuint id )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return (GLboolean) !crHashIdPoolIsIdFree( h->idPool, id);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncGLboolean crHashtableGetDataKey(CRHashTable *pHash, void *pData, unsigned long *pKey)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *entry;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLboolean rc = GL_FALSE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!pHash)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&pHash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0; i<CR_NUM_BUCKETS && !rc; i++)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync entry = pHash->buckets[i];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (entry)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (entry->data == pData) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pKey)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *pKey = entry->key;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = GL_TRUE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync entry = entry->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&pHash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}