69 fprintf(stderr,
"FATAL ERROR> %s\n",msg);
78 const unsigned char *
d=(
const unsigned char *)keyData;
80 for (
unsigned int i=0;
i<keyLen;
i++) {
81 int shift1=((5*
i)%16)+0;
82 int shift2=((6*
i)%16)+8;
83 ret+=((0xa5^d[
i])<<shift2)+(d[
i]<<shift1);
85 DEBUGF((
" hashing %d-byte key to %08x\n",keyLen,ret))
90 const char *
d=*(
const char **)keyData;
92 for (
int i=0;d[
i]!=0;
i++) {
93 int shift1=((5*
i)%16)+0;
94 int shift2=((6*
i)%16)+8;
95 ret+=((0xa5^d[
i])<<shift2)+(d[
i]<<shift1);
97 DEBUGF((
" hashed key '%s' to %08x\n",d,ret))
104 DEBUGF((
" comparing %d-byte keys--",keyLen))
105 const char *a=(
const char *)key1;
106 const char *b=(
const char *)key2;
107 for (
unsigned int i=0;
i<keyLen;
i++)
108 if (a[
i]!=b[
i]) {
DEBUGF((
"different\n"))
return 0;}
114 const char *a=*(
const char **)key1;
115 const char *b=*(
const char **)key2;
116 DEBUGF((
" comparing '%s' and '%s'--",a,b))
118 if (*a++!=*b++) {
DEBUGF((
"different\n"))
return 0;}
126 #define copyKey(dest,src) memcpy(dest,src,layout.keySize())
127 #define copyObj(dest,src) memcpy(dest,src,layout.objectSize())
128 #define copyEntry(dest,src) memcpy(dest,src,layout.entrySize())
133 char *CkHashtable::findKey(
const void *
key)
const
135 DEBUGF((
" Finding key in table of %d--\n",len))
136 int i=hash(key,layout.keySize())%len;
140 if (layout.isEmpty(cur))
return NULL;
141 char *curKey=layout.getKey(cur);
142 if (
compare(key,curKey,layout.keySize()))
return curKey;
143 DEBUGF((
" still looking for key (at %d)\n",i))
144 }
while (inc(i)!=startSpot);
145 DEBUGF((
" No key found!\n"))
150 char *CkHashtable::findEntry(
const void *
key)
const
152 DEBUGF((
" Finding spot in table of %d--\n",len))
153 int
i=hash(key,layout.keySize())%len;
157 if (layout.isEmpty(cur))
return cur;
158 char *curKey=layout.getKey(cur);
159 if (
compare(key,curKey,layout.keySize()))
return cur;
160 DEBUGF((
" still looking for spot (at %d)\n",i))
161 }
while (inc(i)!=startSpot);
167 void CkHashtable::buildTable(
int newLen)
170 resizeAt=(int)(len*loadFactor);
171 DEBUGF((
"Building table of %d (resize at %d)\n",len,resizeAt))
172 table=new
char[layout.entrySize()*len];
173 for (
int i=0;i<len;i++) layout.
empty(entry(i));
177 void CkHashtable::rehash(
int newLen)
179 DEBUGF((
"Beginning rehash from %d to %d--\n",len,newLen))
180 char *oldTable=table;
183 for (
int i=0;i<oldLen;i++) {
184 char *src=oldTable+i*layout.entrySize();
185 if (!layout.isEmpty(src)) {
187 char *dest=findEntry(layout.getKey(src));
192 DEBUGF((
"Rehash complete\n"))
198 CkHashtable::CkHashtable(
const CkHashtableLayout &layout_,
199 int initLen,
float NloadFactor,
200 CkHashFunction Nhash,
201 CkHashCompare Ncompare)
207 loadFactor=NloadFactor;
212 CkHashtable::~CkHashtable()
214 DEBUGF((
"Deleting table of %d\n",len))
221 void CkHashtable::
empty(
void)
223 for (
int i=0;i<len;i++) {
233 void *CkHashtable::put(
const void *key)
239 for (
int i=0;i<len;i++)
240 if (!layout.isEmpty(entry(i)))
242 if (nActualObj!=nObj)
CmiAbort(
"Table corruption!\n");
245 char *ent=findEntry(key);
246 if (layout.isEmpty(ent))
252 return layout.getObject(ent);
256 void CkHashtable::remove(
const void *key)
258 DEBUGF((
"Asked to remove key\n"))
259 char *doomedKey=findKey(key);
260 if (doomedKey==NULL) return;
262 char *doomed=layout.entryFromKey(doomedKey);
263 layout.
empty(doomed);
265 #define e2i(entry) (((entry)-table)/layout.entrySize())
267 DEBUGF((
"Remove-rehashing later keys\n"))
271 if (layout.isEmpty(src))
273 DEBUGF((
"Remove-rehash complete\n"))
277 char *dest=findEntry(layout.getKey(src));
279 DEBUGF((
"Remove-rehashing %d to %d\n",
e2i(src),
e2i(dest)))
283 DEBUGF((
"Remove-rehashing not needed for %d\n",
e2i(src)))
289 CkHashtableIterator *CkHashtable::iterator(
void)
291 DEBUGF((
"Building iterator\n"))
292 return new CkHashtableIterator(table,len,layout);
300 void CkHashtableIterator::seekStart(
void) {curNo=0;}
303 void CkHashtableIterator::seek(
int n)
306 if (curNo<0) curNo=0;
307 if (curNo>len) curNo=len;
311 int CkHashtableIterator::hasNext(
void)
314 if (!layout.isEmpty(entry(curNo)))
324 void *CkHashtableIterator::next(
void **retKey)
327 char *cur=entry(curNo++);
328 if (!layout.isEmpty(cur)) {
330 if (retKey) *retKey=layout.getKey(cur);
331 return layout.getObject(cur);
412 while (doublingPrimes[i]<=x)
414 return doublingPrimes[
i];
418 #define CDECL extern "C"
423 int objStart=2*
sizeof(int);
424 CkHashtableLayout layout(
sizeof(
int),
sizeof(
int),
425 objStart,objBytes,objStart+objBytes);
427 CkHashFunction_int,CkHashCompare_int);
432 int objStart=2*
sizeof(
char *);
433 CkHashtableLayout layout(
sizeof(
char *),
sizeof(
char *),
434 objStart,objBytes,objStart+objBytes);
440 delete (CkHashtable *)h;
445 return ((CkHashtable *)h)->put(atKey);
451 return ((CkHashtable *)h)->get(fromKey);
456 ((CkHashtable *)h)->remove(doomedKey);
CDECL CkHashtable_c CkCreateHashtable_string(int objBytes, int initSize)
CDECL void * CkHashtablePut(CkHashtable_c h, const void *atKey)
CDECL CkHashtable_c CkCreateHashtable_int(int objBytes, int initSize)
boolean empty(T_VertexSet s)
int CkHashCompare_string(const void *key1, const void *key2, size_t keyLen)
void CmiAbort(const char *msg)
#define copyEntry(dest, src)
CkHashCode CkHashFunction_string(const void *keyData, size_t keyLen)
static const unsigned int doublingPrimes[]
#define copyKey(dest, src)
int CkHashCompare_default(const void *key1, const void *key2, size_t keyLen)
CkHashCode CkHashFunction_default(const void *keyData, size_t keyLen)
CDECL void CkDeleteHashtable(CkHashtable_c h)
CGAL_KERNEL_INLINE Comparison_result compare(const NT &n1, const NT &n2)
CDECL void CkHashtableRemove(CkHashtable_c h, const void *doomedKey)
static unsigned int primeLargerThan(unsigned int x)
CDECL void * CkHashtableGet(CkHashtable_c h, const void *fromKey)