2 Copyright © 1997-98, The AROS Development Team. All rights reserved.
5 Desc: Demo of new OOP system - General hashing functions.
16 #define UB(x) ((UBYTE *)x)
22 /* Allocates a hashtable for given number of entries,
23 ** so that hash table is no more than 50% full.
24 ** Initializes table as empty.
27 struct Bucket
**NewHash(ULONG entries
)
30 /* Calulates hashsize as 2^n - 1 so that htsize >= 2*initial */
34 struct Bucket
**ht
= NULL
;
36 EnterFunc(bug("NewHash(entries=%ld)\n", entries
));
38 /* Find the highest bit in 'initial' */
39 for (i
= 31; i
>= 0; i
--)
41 if ((temp
<< i
) & entries
)
47 /* Make sure table is never more than 50% full */
50 entries
= (temp
<< i
);
52 /* Calulate size in bytes. + 1 because we store the size of the hashtable */
53 size
= UB( &ht
[entries
+ 1] ) - UB( &ht
[0] );
64 entries
--; /* 2^n - 1 */
65 ((IPTR
*)ht
)[0] = entries
;
67 D(bug("ht: %p, mask: %ld\n", ht
, entries
));
70 ReturnPtr ("NewHash", struct Bucket
**, &ht
[1]);
72 ReturnPtr ("NewHash", struct Bucket
**, NULL
);
78 VOID
FreeHash(struct Bucket
**ht
, VOID (*freebucket
)())
82 EnterFunc(bug("FreeHash(ht=%p, freebucket=%p)\n", ht
, freebucket
));
84 D(bug("Hashsize: %ld\n", HashSize(ht
) ));
87 /* Free all buckets */
88 for (i
= 0; i
< HashSize(ht
); i
++)
90 struct Bucket
*b
, *next_b
;
91 D(bug("Freeing buckets at entry %ld\n", i
));
93 for (b
= ht
[i
]; b
; b
= next_b
)
95 D(bug("Freeing bucket %p of id %ld\n", b
, b
->ID
));
97 D(bug("Calling freebucket\n"));
99 D(bug("Freebucket called\n"));
104 ReturnVoid("FreeHash");
110 struct Bucket
*HashLookupULONG(struct Bucket
**ht
, IPTR id
)
114 for (b
= ht
[CalcHash(ht
, id
)]; b
; b
= b
->Next
)
123 struct Bucket
*HashLookupStr(struct Bucket
**ht
, IPTR id
)
126 EnterFunc(bug("HashLookupStr(ht=%p, id=%s)\n", ht
, (STRPTR
)id
));
127 for (b
= ht
[CalcHashStr(ht
, id
)]; b
; b
= b
->Next
)
129 D(bug("Bucket: %p\n", b
));
130 if (!strcmp((STRPTR
)b
->ID
, (STRPTR
)id
))
131 ReturnPtr ("HashLookupStr", struct Bucket
*, b
);
133 ReturnPtr ("HashLookupStr", struct Bucket
*, NULL
);
139 BOOL
CopyHash(struct Bucket
**dest_ht
140 ,struct Bucket
**src_ht
141 ,struct Bucket
* (*copybucket
)()
146 EnterFunc(bug("CopyHash(dest_ht=%p, src_ht=%p, copybucket=%p,data = %p)\n",
147 dest_ht
, src_ht
, copybucket
, data
));
149 for (i
= 0; i
< HashSize(src_ht
); i
++ )
153 D(bug("idx: %ld\n", i
));
155 for (b
= src_ht
[i
]; b
; b
= b
->Next
)
157 /* Rehash bucket into destination hashtable */
158 struct Bucket
*new_b
;
160 D(bug("Bucket: %p\n", b
));
162 new_b
= copybucket(b
);
164 ReturnBool ("CopyHash", FALSE
);
166 InsertBucket(dest_ht
, new_b
);
169 } /* For each bucket at current entry */
171 } /* For each entry in source hashtable */
173 ReturnBool ("CopyHash", TRUE
);
176 /*********************
178 *********************/
179 VOID
InsertBucket(struct Bucket
**ht
, struct Bucket
*b
)
181 /* Inserts bucket into hashtable accordibg to the ID */
184 EnterFunc(bug("InsertBucket(ht=%p, b=%p)\n", ht
, b
));
186 idx
= CalcHash(ht
, b
->ID
);
189 D(bug("b->Next=%p\n", b
->Next
));
192 ReturnVoid ("InsertBucket");
196 /* id is an interface ID */
197 ULONG
CalcHashULONG(struct Bucket
**ht
, IPTR id
)
199 return (HashMask(ht
) & id
);
202 /* id is a (interfaceid << NUM_METHOD_BITS) & methodID */
203 ULONG
CalcHashHM(struct Bucket
**ht
, IPTR id
)
205 return (HashMask(ht
) & (id
^ (id
>> NUM_METHOD_BITS
)));
208 /* id is a (interfaceid << NUM_METHOD_BITS) & methodID */
209 ULONG
CalcHashStr(struct Bucket
**ht
, IPTR id
)
211 STRPTR str
= (STRPTR
)id
;
213 for (i
= 0, val
= 0; (i
< MAX_HASH_CHARS
) && *str
; str
++)
214 {val
+= *str
; i
++; }
216 return (val
& HashMask(ht
));