/* put_record given a key and its non-negative value, if the key does not yet exist in the hash table, adds a key-value record, if the key already exists in the hash table, increments the value associated with the key by the value passed as an argument param: char* key (key to add) uint64_t value (value to assign or update) hash_table_t* hash_table (the hash table to search) return: upon success, returns a pointer to the newly-created key-value record upon error returns NULL */ record_t* put_record(char* key, uint64_t value, hash_table_t* hash_table) { if(!key || !hash_table)return NULL; //calculate the hash value using the hash function //set for the current hash table, (save value in case of resize) uint64_t hash_val = (*(hash_table->hash_function))(key); //find the appropriate index in the hash table's lists array uint64_t table_index = hash_val%(hash_table->table_size); //set a double record pointer to the start of the correct list in //the hash table's lists array to begin traversing the list record_t** link_ptr = &(hash_table->lists[table_index]); //traverse the list until the chosen key is encountered or //the end of the list is reached while(*link_ptr && strcmp(key, ((*link_ptr)->key)) != 0) { //repoint the double pointer record to the next record pointer link_ptr = &(*link_ptr)->next_link; } //if the record does not exist, //add a new key-value record to the current list, //return a pointer to the key-value new record if(!(*link_ptr)) { //check whether load factor threshold will be exceeded after the next record is added //if so, resize table, rehash record keys and place them in the larger table, //then proceed to hash the new record, then place it in the appropriate list in the larger table if(NEEDTORESIZE) { if((resize_table(hash_table) != 0))return NULL; //now that the table should have been resized, //find the correct index for the new record based on the new size table_index = hash_val%(hash_table->table_size); } //add the new record to the hash table by //adding it to the front of the appropriate list in the lists array record_t* new_record = NULL; if(!(new_record = add_front(key, value, &(hash_table->lists[table_index]))))return NULL; { //update the total number of records in the hash table, //return a pointer to the new key-value record hash_table->num_records++; return new_record; } } //if the key already exists in the table, //update its old value (increment the old value by the new value), //return a pointer to the key-value record else { (*link_ptr)->value += value; return *link_ptr; } }
static void weak_table_put_x (scm_t_weak_table *table, unsigned long hash, scm_t_table_predicate_fn pred, void *closure, SCM key, SCM value) { unsigned long k, distance, size; scm_t_weak_entry *entries; size = table->size; entries = table->entries; hash = (hash << 1) | 0x1; k = hash_to_index (hash, size); for (distance = 0; ; distance++, k = (k + 1) % size) { unsigned long other_hash; retry: other_hash = entries[k].hash; if (!other_hash) /* Found an empty entry. */ break; if (other_hash == hash) { scm_t_weak_entry copy; copy_weak_entry (&entries[k], ©); if (!copy.key || !copy.value) /* Lost weak reference; reshuffle. */ { give_to_poor (table, k); table->n_items--; goto retry; } if (pred (SCM_PACK (copy.key), SCM_PACK (copy.value), closure)) /* Found an entry with this key. */ break; } if (table->n_items > table->upper) /* Full table, time to resize. */ { resize_table (table); return weak_table_put_x (table, hash >> 1, pred, closure, key, value); } /* Displace the entry if our distance is less, otherwise keep looking. */ if (entry_distance (other_hash, k, size) < distance) { rob_from_rich (table, k); break; } }
static void relayout_tables (AppResizer * widget, gint num_cols) { GtkTable *table; GList *table_list, *launcher_list; for (table_list = widget->cached_tables_list; table_list != NULL; table_list = g_list_next (table_list)) { table = GTK_TABLE (table_list->data); launcher_list = gtk_container_get_children (GTK_CONTAINER (table)); launcher_list = g_list_reverse (launcher_list); /* Fixme - ugly hack because table stores prepend */ resize_table (table, num_cols, launcher_list); relayout_table (table, launcher_list); g_list_free (launcher_list); } }
void hash_table_set(hash_table *table, const char *key, void *value) { bucket *bkt = get_bucket(table, key); if(bkt != NULL) { bkt->value = value; return; } if(table->occupied + 1 > table->size / 2) { resize_table(table); } bucket *new_bkt = malloc(sizeof(bucket)); new_bkt->key = key; new_bkt->value = value; new_bkt->hash = hash(key); int index = new_bkt->hash % table->size; new_bkt->next = table->table[index]; table->table[index] = new_bkt; table->occupied++; }
static SLang_Assoc_Array_Type *alloc_assoc_array (SLtype type, int has_default_value) { SLang_Assoc_Array_Type *a; a = (SLang_Assoc_Array_Type *)SLmalloc (sizeof (SLang_Assoc_Array_Type)); if (a == NULL) { if (has_default_value) SLdo_pop_n (1); return NULL; } memset ((char *) a, 0, sizeof (SLang_Assoc_Array_Type)); a->type = type; #if SLANG_OPTIMIZE_FOR_SPEED a->is_scalar_type = (SLANG_CLASS_TYPE_SCALAR == _pSLang_get_class_type (type)); #endif if (has_default_value) { if ( #if USE_NEW_ANYTYPE_CODE ((type != SLANG_ANY_TYPE) && (-1 == SLclass_typecast (type, 1, 0))) #else (-1 == SLclass_typecast (type, 1, 0)) #endif || (-1 == SLang_pop (&a->default_value))) { SLfree ((char *) a); return NULL; } a->flags |= HAS_DEFAULT_VALUE; } if (-1 == resize_table (a)) { delete_assoc_array (a); return NULL; } return a; }
void add_to_cache(cache_t cache, key_type key, val_type val, uint32_t val_size){ //adds in a new item in the location of the cache key_type key_copy = make_copy(key,strlen((char*)key)+1); key_val_s new_item; new_item.key = key_copy; new_item.val = make_copy(val,val_size); new_item.val_size = val_size; //give the policy the pointer to the key so that it can read the value of the key when //the policy teels it about evictions in ids_to_delete_if_added new_item.policy_info = create_info(cache->evic_policy,(void*)(key_copy),val_size); assign_to_link(querry_hash(cache,key),new_item); cache->mem_used += val_size; cache->num_elements++; //resizes table if load factor is over 0.5 if(cache->num_elements*2 > cache->table_size){ resize_table(cache,cache->table_size*2); } }
/* Inner search of the hash and synonym chains. */ static struct ts_entry * tsearch_inner( const void *key, struct hs_base* head, int (*compar)(const void *, const void *), const enum search_intent_t intent, int*inserted, /* owner_ptr used for delete. Only set if the to-be-deleted item is on a chain, not in the hashtab. Points to the item pointing to the to-be-deleted-item.*/ struct ts_entry **owner_ptr) { struct ts_entry *s =0; struct ts_entry *c =0; struct ts_entry *q =0; int kc = 0; unsigned long keyhash = 0; unsigned long hindx = 0; struct ts_entry *chain_parent = 0; if(! head->hashfunc_) { /* Not fully initialized. */ return NULL; } keyhash = head->hashfunc_(key); if (intent == want_insert) { if( head->record_count_ > head->allowed_fill_) { resize_table(head,compar); } } hindx = keyhash%head->tablesize_; s = &head->hashtab_[hindx]; if(!s->entryused) { /* Not found. */ if(intent != want_insert) { return NULL; } /* Insert in the base hash table in an empty slot. */ *inserted = 1; head->record_count_++; s->keyptr = (const void *)key; s->entryused = 1; s->next = 0; return s; } kc = compar(key,s->keyptr); if(kc == 0 ) { /* found! */ if(want_delete) { *owner_ptr = 0; } return (void *)&(s->keyptr); } chain_parent = s; for(c = s->next; c; c = c->next) { kc = compar(key,c->keyptr); if(kc == 0 ) { /* found! */ if(want_delete) { *owner_ptr = chain_parent; } return (void *)&(c->keyptr); } chain_parent = c; } if(intent != want_insert) { return NULL; } /* Insert following head record of the chain. */ q = allocate_ts_entry(key); if (!q) { return q; } q->next = s->next; s->next = q; head->record_count_++; *inserted = 1; return q; }
void app_resizer_layout_table_default (AppResizer * widget, GtkTable * table, GList * element_list) { resize_table (table, widget->cur_num_cols, element_list); relayout_table (table, element_list); }