114 void *
operator new(
size_t size, cc_memalloc * memhandler) {
116 cc_memalloc_allocate(memhandler);
117 entry->memhandler = memhandler;
118 return (
void*) entry;
120 void operator delete(
void * ptr) {
122 cc_memalloc_deallocate(entry->memhandler, ptr);
124 void operator delete(
void * ptr, cc_memalloc * memhandler) {
126 cc_memalloc_deallocate(entry->memhandler, ptr);
132 cc_memalloc * memhandler;
140 typedef uintptr_t SmHashFunc(
const Key & key);
141 typedef void SmHashApplyFunc(
const Key & key,
const Type & obj,
void * closure);
144 SmHash(
unsigned int sizearg = 256,
float loadfactorarg = 0.0f)
146 this->commonConstructor(sizearg, loadfactorarg);
151 this->commonConstructor(from.size, from.loadfactor);
152 this->operator=(from);
158 from.apply(SmHash::copy_data,
this);
165 cc_memalloc_destruct(this->memhandler);
166 delete [] this->buckets;
172 for ( i = 0; i < this->size; i++ ) {
173 while ( this->buckets[i] ) {
175 this->buckets[i] = entry->next;
183 SbBool put(
const Key & key,
const Type & obj)
185 unsigned int i = this->getIndex(key);
188 if ( entry->key == key ) {
202 entry->next = this->buckets[i];
203 this->buckets[i] = entry;
205 if ( this->elements++ >= this->threshold ) {
206 this->resize((
unsigned int) smhash_geq_prime_number(this->size + 1));
211 SbBool get(
const Key & key, Type & obj)
const
214 unsigned int i = this->getIndex(key);
215 entry = this->buckets[i];
217 if ( entry->key == key ) {
226 SbBool remove(
const Key & key)
228 unsigned int i = this->getIndex(key);
232 if ( entry->key == key ) {
235 this->buckets[i] = next;
249 void apply(SmHashApplyFunc * func,
void * closure)
const
253 for ( i = 0; i < this->size; i++ ) {
254 elem = this->buckets[i];
256 func(elem->key, elem->obj, closure);
264 this->apply(SmHash::add_to_list, &l);
267 unsigned int getNumElements(
void)
const {
return this->elements; }
269 void setHashFunc(SmHashFunc * func) { this->hashfunc = func; }
272 static uintptr_t default_hash_func(
const Key & key) {
273 return (uintptr_t) key;
276 unsigned int getIndex(
const Key & key)
const {
277 unsigned int idx = this->hashfunc(key);
278 return (idx % this->size);
281 void resize(
unsigned int newsize) {
283 if (this->size >= newsize)
return;
285 unsigned int oldsize = this->size;
288 this->size = newsize;
290 this->threshold = (
unsigned int) (newsize * this->loadfactor);
296 for ( i = 0; i < oldsize; i++ ) {
299 this->put(entry->key, entry->obj);
305 delete [] oldbuckets;
309 void commonConstructor(
unsigned int sizearg,
float loadfactorarg)
311 if ( loadfactorarg <= 0.0f ) { loadfactorarg = 0.75f; }
312 unsigned int s = smhash_geq_prime_number(sizearg);
316 this->threshold = (
unsigned int) (s * loadfactorarg);
317 this->loadfactor = loadfactorarg;
320 this->hashfunc = default_hash_func;
323 void getStats(
int & buckets_used,
int & buckets,
int & elements,
float & chain_length_avg,
int & chain_length_max)
326 buckets_used = 0, chain_length_max = 0;
327 for ( i = 0; i < this->size; i++ ) {
328 if ( this->buckets[i] ) {
329 unsigned int chain_l = 0;
336 if ( chain_l > chain_length_max ) { chain_length_max = chain_l; }
339 buckets = this->size;
340 elements = this->elements;
341 chain_length_avg = (float) this->elements / buckets_used;
344 static void copy_data(
const Key & key,
const Type & obj,
void * closure)
347 thisp->put(key, obj);
350 static void add_to_list(
const Key & key,
const Type & obj,
void * closure)
358 unsigned int elements;
359 unsigned int threshold;
362 SmHashFunc * hashfunc;
363 cc_memalloc * memhandler;