int hashtab_insert(struct hashtable *s,const unsigned char* key,const size_t len,const element_data data) { struct element* element; struct element* deleted_element = NULL; size_t tries = 1; size_t idx; if(!s) return CL_ENULLARG; do { PROFILE_CALC_HASH(s); idx = hash(key, len, s->capacity); element = &s->htable[idx]; do { if(!element->key) { unsigned char* thekey; /* element not found, place is empty, insert*/ if(deleted_element) { /* reuse deleted elements*/ element = deleted_element; PROFILE_DELETED_REUSE(s, tries); } else { PROFILE_INSERT(s, tries); } thekey = cli_malloc(len+1); if(!thekey) return CL_EMEM; strncpy((char*)thekey,(const char*)key,len+1); element->key = thekey; element->data = data; s->used++; if(s->used > s->maxfill) { cli_dbgmsg("hashtab.c:Growing hashtable %p, because it has exceeded maxfill, old size:%ld\n",(void*)s,s->capacity); hashtab_grow(s); } return 0; } else if(element->key == DELETED_KEY) { deleted_element = element; } else if(strncmp((const char*)key,(const char*)element->key,len)==0) { PROFILE_DATA_UPDATE(s, tries); element->data = data;/* key found, update */ return 0; } else { idx = (idx + tries++) % s->capacity; element = &s->htable[idx]; } } while (tries <= s->capacity); /* no free place found*/ PROFILE_HASH_EXHAUSTED(s); cli_dbgmsg("hashtab.c: Growing hashtable %p, because its full, old size:%ld.\n",(void*)s,s->capacity); } while( hashtab_grow(s) >= 0 ); cli_warnmsg("hashtab.c: Unable to grow hashtable\n"); return CL_EMEM; }
int hashtab_insert(struct hashtab *hashtab, struct hashnode *hashnode) { unsigned int i, size; i = hashnode->hashval & hashtab->mask; hashnode->next = hashtab->bucket[i]; hashtab->bucket[i] = hashnode; hashtab->used += 1; size = 1 << hashtab->log2size; if (hashtab->used > (4 * size) / 5) /* rehash at 80% */ return hashtab_grow(hashtab); return 0; }