示例#1
0
void *ht_remove_fa(hashtable *ht, const void *key,
        void (*free_key)(void*),
        const void *hash_arg, const void *cmp_arg)
{
    hash_t k;
    int res;
    void *data;

    if (!ht || !key)
        return NULL;

    k = ht->hash(key, hash_arg) % ht->n_buckets;
    res = htbucket_remove(ht->buckets + k, &data, key, ht->cmp, cmp_arg, free_key);

    if (res == HT_OK)
    {
        ht->n_items--;
        /* items < buckets/4 -> resize */
        if (ht->n_items * 4 < ht->n_buckets)
            ht_resize(ht, 0);
        return data;
    }

    return NULL;
}
示例#2
0
文件: sexp.c 项目: cansou/minimallisp
SExp make_hash_table(void) {
	SHash* p = smalloc(sizeof(*p), FALSE);
	p->typeinfo = &TSHash;
	ht_init(&p->ht, &SHashVTbl);
	ht_resize(&p->ht, 129);
	return ptr2s(p);
}
示例#3
0
文件: gr_hash.c 项目: NosicLin/Codger
int GrHash_MapWithNewKey(GrHash* h,GrObject* key,GrObject* value)
{
	assert(value);
	ssize_t code=GrObject_Hash(key);
	ssize_t used=h->h_used;
	int ret=0;
	GrHashEntry* p=h->h_look_up(h,key,code);
	if(p==NULL)
	{
		return -1;
	}
	if(p->e_key==NULL)
	{
		h->h_fill++;
		h->h_used++;
	}
	if(p->e_key==Gr_Hash_Dummy)
	{
		h->h_used++;
	}
	p->e_key=key;
	p->e_value=value;
	p->e_code=code;

	/* check space, make sure 1/3 free slot */
	if(used<h->h_used &&  h->h_fill*3 >h->h_mask*2)
	{
		ret=ht_resize(h,(h->h_used>50000?2:4)*h->h_used);
	}
	GrGc_Intercept(h,key);
	GrGc_Intercept(h,value);
	return ret;
}
示例#4
0
/**
 * ht_insert(htable *table, ht_entry *entry)
 *
 * Insert entry into table.
 * Returns the inserted entry.
 **/
ht_entry *ht_insert(htable *table, ht_entry *entry) {
  // Get the bucket that the entry hashes to.
  long bucket = (*table->hash)(entry->key) % table->length;

  // Get the chain for that bucket.
  ht_entry *chain = table->array[bucket].datum;

  // Put our new entry at the head of the chain.
  // If the chain does not yet exist, then create
  // it starting with our new entry.
  if (! chain) {
    chain = entry;
    entry->next = NULL;
    entry->prev = NULL;
    table->array[bucket].datum = chain;
  }
  else {
    entry->next = chain;
    entry->prev = NULL;
    chain->prev = entry;
    table->array[bucket].datum = entry;
    chain = entry;
  }

  table->size++;
  table->array[bucket].length++;

  // Check to see if the table should be resized.
  ht_resize(table);

  // Return the head of the chain.
  return chain;
}
示例#5
0
// Insert htelem struct into hash table
int ht_ins_htelem(hashtab *ht, htelem *htelem)
{
    unsigned hash = ht->hash(htelem->key);
    hash = hash % ht->asize;

    struct htelem *p;
    struct htelem *start = ht->array[hash];
    for(p = start; p != NULL; p = p->next)
    {
        if(ht->keyEqual(p->key, htelem->key))
        {
            ht->freeElem(p->elem);
            ht->freeKey(htelem->key);
            p->elem = htelem->elem;
            free(htelem);
            return 0;
        }
    }

    // Not found in hash table, add to front of linked list
    p = start;
    ht->array[hash] = htelem;
    htelem->next = p;
    ht->members++;

    if((float)ht->members / (float)ht->asize > MAX_LOAD_FACTOR)
        if(ht_resize(ht) < 0)
            return -1;
    
    return 0;
}
示例#6
0
//~~~~~~~~~~~~~~~~~MAIN~~~~~~~~~~~~~~~~~~~~~~~
int main(int argc, char* argv[]){
  int debug = 0, flag = 1, arg, numRead = 0;
  char command, *stream;
  Line line = line_init( stdin);
  gen_parse_args( argc, argv, &debug);
  Htable htable = ht_init( ht_mod_hash);

  while(flag){
    arg = -1;
    fprintf( stdout, "\ncommand: ");
    line_read_line( line);
    stream = get_line( line);
    sscanf( stream, " %c%n", &command, &numRead);
    switch( command){
      case 'q': flag = 0; break;
      case 'i': sscanf( stream+numRead, "%d", &arg);
                if( arg < 0) fprintf( stderr, "MUST BE >= 0\n");
                else ht_add( htable, arg, arg, debug);
                break;
      case 'd': sscanf( stream+numRead, "%d", &arg);
                if( arg < 0) fprintf( stderr, "MUST BE >= 0\n");
                else{
                  int pos = ht_mod_hash( htable, arg);
                  node_delete( &((htable->table)[pos]), arg, arg, debug); 
                }
                break;
      case 'c': sscanf( stream+numRead, "%d", &arg);
                if( arg < 0) fprintf( stderr, "MUST BE >= 0\n");
                else{
                  if( ht_exists( htable, arg, debug) )
                    fprintf( stdout, "The value, %d, exists!\n", arg);
                  else
                    fprintf( stdout, "The value, %d, does NOT exist\n", arg);
                }
                break;
      case 'e': ht_erase( htable); break;
      case 'r': sscanf( stream+numRead, "%d", &arg);
                if( arg >= 1) ht_resize( htable, arg, debug);
                else fprintf( stderr, "Error, size must be >= 1\n");
                break;
      case 'l': ht_list( htable); break;
      case '\n': break;
      default: fprintf( stdout, "Sorry, Invalid command\n"); break;
    }
    free(stream);
  }
  line_free( line);
  ht_free( htable);
  return 0;
}
示例#7
0
文件: evidence.c 项目: gaibo/C
int main(void) {
    printf("*****testing hash table*****\n\n");
    htbl* t = ht_new(&good_hash, 10);
    
    FILE* cnets2015 = fopen("cnets2015", "r");
    while (!feof(cnets2015)) {
        char* s = alloc_str(256);
        fgets(s, 256, cnets2015);
        char* l = trim_newline(s);
        free(s);
        if (strlen(l) > 0) {
            ht_ins(l, t);
        }
        free(l);
    }
    fclose(cnets2015);
    
    ht_show(t);
    printf("The hash table has %u buckets with %u entries (load factor %lg).\n\n",
        t->n_buckets, 
        ht_n_entries(t),
        ht_load_factor(t));
    printf("The bucket with the most items in it contains %u items.\n\n",
        ht_max_bucket(t));
    printf("ht_member:\n");
    printf("membership of cnet \"aardvark\" : %i\n", ht_member("aardvark", t));
    printf("membership of cnet \"borja\"    : %i\n", ht_member("borja", t));
    printf("\n");
    
    // resize
    printf("***now resizing***\n");
    ht_resize(&t);
    printf("***resizing complete***\n\n");
    
    // do everything again
    ht_show(t);
    printf("The hash table has %u buckets with %u entries (load factor %lg).\n\n",
        t->n_buckets, 
        ht_n_entries(t),
        ht_load_factor(t));
    printf("The bucket with the most items in it contains %u items.\n\n",
        ht_max_bucket(t));
    printf("ht_member:\n");
    printf("membership of cnet \"aardvark\" : %i\n", ht_member("aardvark", t));
    printf("membership of cnet \"borja\"    : %i\n", ht_member("borja", t));
    printf("\n");
    
    ht_free(t);
    return 0;
}
示例#8
0
t_value *ht_update(t_hash_table *h, t_key key) {
    int hash = ht_hash(key, h->size);
    t_bucket *b = ht_find_bucket(h, key, hash);
    t_value value;
    value.ull = 0ULL;

    if (b == NULL) {
        if (h->num_keys == h->size) {
            ht_resize(h);
            hash = ht_hash(key, h->size);
        }
        b = ht_create_bucket(h, key, value, h->bucket_ptrs[hash]);
        h->bucket_ptrs[hash] = b;
    }
    return &(b->value);
}
示例#9
0
int ht_insert_a(hashtable *ht, void *key, void *data,
        const void *hash_arg, const void *cmp_arg)
{
    int res;
    hash_t k;

    if (!ht || !key)
        return HT_ERROR;

    k = ht->hash(key, hash_arg) % ht->n_buckets;

    res = htbucket_insert(ht->buckets + k, key, data, ht->cmp, cmp_arg);

    if (res == HT_OK)
    {
        ht->n_items++;
        if (ht->n_items > ht->n_buckets)
            ht_resize(ht, 1);
    }

    return res;
}
示例#10
0
void ht_insert(smb_ht *table, DATA key, DATA value)
{
  unsigned int index;
  if (ht_load_factor(table) >= HASH_TABLE_MAX_LOAD_FACTOR) {
    ht_resize(table);
  }

  // First, probe for the key as if we're trying to return it.  If we find it,
  // we update the existing key.
  index = ht_find_retrieve(table, key);
  if (table->table[index].mark == HT_FULL) {
    table->table[index].value = value;
    return;
  }

  // If we don't find the key, then we find the first open slot or gravestone.
  index = ht_find_insert(table, key);
  table->table[index].key = key;
  table->table[index].value = value;
  table->table[index].mark = HT_FULL;
  table->length++;
}
示例#11
0
/*
doc:	<routine name="ht_safe_force" return_type="int" export="shared">
doc:		<summary>Put value `val' associated with key `key' in table `ht'. If `ht' is full, we will resize `ht' and try again. If `resizing' failed or if we cannot find a suitable position, a negative value is returned.</summary>
doc:		<param name="ht" type="struct htable *">Table to initialize.</param>
doc:		<param name="key" type="rt_uint_ptr">Key to insert in `ht'.</param>
doc:		<param name="val" type="void *">Value to insert in `ht'.</param>
doc:		<return>0 upon successful insertion, -1 if cannot resize, -2 if cannot insert.</return>
doc:		<thread_safety>Not Safe</thread_safety>
doc:		<synchronization>None</synchronization>
doc:	</routine>
*/
rt_shared int ht_safe_force (struct htable *ht, rt_uint_ptr key, void * val)
{
	REQUIRE("ht not null", ht);
	REQUIRE("key not null", key);

	if (!(ht_put(ht, key, val))) {		/* Insertion failed => H table full */
			/* Resize the hash table */
		if (ht_resize(ht, ht->h_capacity + (ht->h_capacity / 2))) {
				/* Cannot resize. */
			return -1;
		} else {
				/* Something (...) was rotten, don't know what */
				/* Insertion failed again => Bailing out */
			if (!(ht_put(ht, key, val))) {
					/* Cannot insert. */
				return -2;
			}
		}
	}
		/* Success. */
	return 0;
}
示例#12
0
// this was separated out of the regular ht_insert
// for ease of copying hash entries around
void ht_insert_he(hash_table *table, hash_entry *entry){
    hash_entry *tmp;
    unsigned int index;

    entry->next = NULL;
    index = ht_index(table, entry->key, entry->key_size);
    tmp = table->array[index];

    // if true, no collision
    if(tmp == NULL)
    {
        table->array[index] = entry;
        table->key_count++;
        return;
    }

    // walk down the chain until we either hit the end
    // or find an identical key (in which case we replace
    // the value)
    
    int count = 1;
    
    while(tmp->next != NULL)
    {
        count++;
        
        if(he_key_compare(tmp, entry))
            break;
        else
            tmp = tmp->next;
    }

    if(he_key_compare(tmp, entry))
    {
        // if the keys are identical, throw away the old entry
        // and stick the new one into the table
        he_set_value(table->flags, tmp, entry->value, entry->value_size);
        he_destroy(table->flags, entry);
    }
    else
    {
        // else tack the new entry onto the end of the chain
        tmp->next = entry;
        table->collisions += 1;
        table->key_count ++;
        table->current_load_factor = (double)table->collisions / table->array_size;
        
        //保存哈希表中发生冲突最多的下标和数目, 便于观察和修改resize的策略
        if (count > table->max_collisions)
        {
            table->max_collisions = count;
            table->max_collisions_index = index;
        }

        // double the size of the table if autoresize is on and the
        // load factor has gone too high
        // add max_collisions condition ?
        if (!(table->flags & HT_NO_AUTORESIZE) && (table->current_load_factor > table->max_load_factor) && (table->max_collisions > 10))
        //if (!(table->flags & HT_NO_AUTORESIZE) && (table->current_load_factor > table->max_load_factor))
        {
            debug("max_index is %d, max_collisions is %d \n", table->max_collisions_index, table->collisions);
            
            ht_resize(table, table->array_size * 2);
            table->current_load_factor = (double)table->collisions / table->array_size;
        }
    }
}
示例#13
0
void ht_term(HashTable* ht) {
	ht_resize(ht, 0);
}
示例#14
0
void *test_hash_rw_thr_writer(void *_count)
{
	struct lfht_test_node *node;
	struct cds_lfht_node *ret_node;
	struct cds_lfht_iter iter;
	struct wr_count *count = _count;
	int ret;

	printf_verbose("thread_begin %s, tid %lu\n",
			"writer", urcu_get_thread_id());

	URCU_TLS(rand_lookup) = urcu_get_thread_id() ^ time(NULL);

	set_affinity();

	rcu_register_thread();

	while (!test_go)
	{
	}
	cmm_smp_mb();

	for (;;) {
		if ((addremove == AR_ADD || add_only)
				|| (addremove == AR_RANDOM && rand_r(&URCU_TLS(rand_lookup)) & 1)) {
			node = malloc(sizeof(struct lfht_test_node));
			lfht_test_node_init(node,
				(void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset),
				sizeof(void *));
			rcu_read_lock();
			if (add_unique) {
				ret_node = cds_lfht_add_unique(test_ht,
					test_hash(node->key, node->key_len, TEST_HASH_SEED),
					test_match, node->key, &node->node);
			} else {
				if (add_replace)
					ret_node = cds_lfht_add_replace(test_ht,
							test_hash(node->key, node->key_len, TEST_HASH_SEED),
							test_match, node->key, &node->node);
				else
					cds_lfht_add(test_ht,
						test_hash(node->key, node->key_len, TEST_HASH_SEED),
						&node->node);
			}
			rcu_read_unlock();
			if (add_unique && ret_node != &node->node) {
				free(node);
				URCU_TLS(nr_addexist)++;
			} else {
				if (add_replace && ret_node) {
					call_rcu(&to_test_node(ret_node)->head,
							free_node_cb);
					URCU_TLS(nr_addexist)++;
				} else {
					URCU_TLS(nr_add)++;
				}
			}
		} else {
			/* May delete */
			rcu_read_lock();
			cds_lfht_test_lookup(test_ht,
				(void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset),
				sizeof(void *), &iter);
			ret = cds_lfht_del(test_ht, cds_lfht_iter_get_node(&iter));
			rcu_read_unlock();
			if (ret == 0) {
				node = cds_lfht_iter_get_test_node(&iter);
				call_rcu(&node->head, free_node_cb);
				URCU_TLS(nr_del)++;
			} else
				URCU_TLS(nr_delnoent)++;
		}
#if 0
		//if (URCU_TLS(nr_writes) % 100000 == 0) {
		if (URCU_TLS(nr_writes) % 1000 == 0) {
			rcu_read_lock();
			if (rand_r(&URCU_TLS(rand_lookup)) & 1) {
				ht_resize(test_ht, 1);
			} else {
				ht_resize(test_ht, -1);
			}
			rcu_read_unlock();
		}
#endif //0
		URCU_TLS(nr_writes)++;
		if (caa_unlikely(!test_duration_write()))
			break;
		if (caa_unlikely(wdelay))
			loop_sleep(wdelay);
		if (caa_unlikely((URCU_TLS(nr_writes) & ((1 << 10) - 1)) == 0))
			rcu_quiescent_state();
	}

	rcu_unregister_thread();

	printf_verbose("thread_end %s, tid %lu\n",
			"writer", urcu_get_thread_id());
	printf_verbose("info tid %lu: nr_add %lu, nr_addexist %lu, nr_del %lu, "
			"nr_delnoent %lu\n", urcu_get_thread_id(),
			URCU_TLS(nr_add),
			URCU_TLS(nr_addexist),
			URCU_TLS(nr_del),
			URCU_TLS(nr_delnoent));
	count->update_ops = URCU_TLS(nr_writes);
	count->add = URCU_TLS(nr_add);
	count->add_exist = URCU_TLS(nr_addexist);
	count->remove = URCU_TLS(nr_del);
	return ((void*)2);
}
示例#15
0
文件: sexp.c 项目: cansou/minimallisp
void init_symbol_table(void) {
	ht_init(&s_symbol_table, &SymbolHTVTbl);
	ht_resize(&s_symbol_table, 129);
}
示例#16
0
int main(int argc, char *argv[])
{
    (void) argc;
    (void) argv;

    hash_table ht;
    ht_init(&ht, HT_KEY_CONST | HT_VALUE_CONST, 0.05);

    char *s1 = (char*)"teststring 1";
    char *s2 = (char*)"teststring 2";
    char *s3 = (char*)"teststring 3";

    ht_insert(&ht, s1, strlen(s1)+1, s2, strlen(s2)+1);

    int contains = ht_contains(&ht, s1, strlen(s1)+1);
    test(contains, "Checking for key \"%s\"", s1);

    size_t value_size;
    char *got = ht_get(&ht, s1, strlen(s1)+1, &value_size);

    fprintf(stderr, "Value size: %zu\n", value_size);
    fprintf(stderr, "Got: {\"%s\": -----\"%s\"}\n", s1, got);

    test(value_size == strlen(s2)+1,
            "Value size was %zu (desired %lu)",
            value_size, strlen(s2)+1);

    fprintf(stderr, "Replacing {\"%s\": \"%s\"} with {\"%s\": \"%s\"}\n", s1, s2, s1, s3);
    ht_insert(&ht, s1, strlen(s1)+1, s3, strlen(s3)+1);

    unsigned int num_keys;
    void **keys;

    keys = ht_keys(&ht, &num_keys);
    test(num_keys == 1, "HashTable has %d keys", num_keys);
    test(keys != NULL, "Keys is not null");
    if(keys)
      free(keys);
    got = ht_get(&ht, s1, strlen(s1)+1, &value_size);

    fprintf(stderr, "Value size: %zu\n", value_size);
    fprintf(stderr, "Got: {\"%s\": \"%s\"}\n", s1, got);

    test(value_size == strlen(s3)+1,
            "Value size was %zu (desired %lu)",
            value_size, strlen(s3)+1);

    fprintf(stderr, "Removing entry with key \"%s\"\n", s1);
    ht_remove(&ht, s1, strlen(s1)+1);

    contains = ht_contains(&ht, s1, strlen(s1)+1);
    test(!contains, "Checking for removal of key \"%s\"", s1);

    keys = ht_keys(&ht, &num_keys);
    test(num_keys == 0, "HashTable has %d keys", num_keys);
    if(keys)
      free(keys);

    fprintf(stderr, "Stress test");
    int key_count = 1000000;
    int i;
    int *many_keys = malloc(key_count * sizeof(*many_keys));
    int *many_values = malloc(key_count * sizeof(*many_values));

    srand(time(NULL));

    for(i = 0; i < key_count; i++)
    {
        many_keys[i] = i;
        many_values[i] = rand();
    }

    struct timespec t1;
    struct timespec t2;

    t1 = snap_time();

    for(i = 0; i < key_count; i++)
    {
        ht_insert(&ht, &(many_keys[i]), sizeof(many_keys[i]), &(many_values[i]), sizeof(many_values[i]));
    }

    t2 = snap_time();

    fprintf(stderr, "Inserting %d keys took %.2f seconds\n", key_count, get_elapsed(t1, t2));
    fprintf(stderr, "Checking inserted keys\n");

    int ok_flag = 1;
    for(i = 0; i < key_count; i++)
    {
        if(ht_contains(&ht, &(many_keys[i]), sizeof(many_keys[i])))
        {
            size_t value_size;
            int value;

            value = *(int*)ht_get(&ht, &(many_keys[i]), sizeof(many_keys[i]), &value_size);

            if(value != many_values[i])
            {
                fprintf(stderr, "Key value mismatch. Got {%d: %d} expected: {%d: %d}\n",
                        many_keys[i], value, many_keys[i], many_values[i]);
                ok_flag = 0;
                break;
            }
        }
        else
        {
            fprintf(stderr, "Missing key-value pair {%d: %d}\n", many_keys[i], many_values[i]);
            ok_flag = 0;
            break;
        }
    }


    test(ok_flag == 1, "Result was %d", ok_flag);
    ht_clear(&ht);
    ht_resize(&ht, 4194304);
    t1 = snap_time();

    for(i = 0; i < key_count; i++)
    {
        ht_insert(&ht, &(many_keys[i]), sizeof(many_keys[i]), &(many_values[i]), sizeof(many_values[i]));
    }

    t2 = snap_time();

    fprintf(stderr, "Inserting %d keys (on preallocated table) took %.2f seconds\n", key_count, get_elapsed(t1, t2));
    for(i = 0; i < key_count; i++)
    {
        ht_remove(&ht, &(many_keys[i]), sizeof(many_keys[i]));
    }
    test(ht_size(&ht) == 0, "%d keys remaining", ht_size(&ht));
    ht_destroy(&ht);
    free(many_keys);
    free(many_values);

    return report_results();
}