Пример #1
0
/*! Delete entries from the hash */
static void *hash_test_shrink(void *d)
{
	const struct hash_test *data = d;
	int i;

	for (i = 1; i < data->preload; ++i) {
		char *obj = ht_new(-i);
		char *from_hashtab;
		int deleted;

		if (obj == NULL) {
			return "Allocation failed";
		}
		from_hashtab = ast_hashtab_remove_object_via_lookup(data->to_be_thrashed, obj);
		deleted = from_hashtab != NULL;

		ht_delete(obj);
		ht_delete(from_hashtab);
		if (!deleted) {
			return "could not delete object";
		}
		if (is_timed_out(data)) {
			return "Shrink timed out";
		}
	}
	return NULL;
}
Пример #2
0
int
ht_resize(struct hashtable_s *ht, size_t size)
{
	struct hashtable_s htmp;
	size_t i;
	struct hashentry_s *entry, *next;

	htmp.size = size;
	htmp.nentries = 0;
	htmp.hashfunc = ht->hashfunc;

	htmp.list = calloc(size, sizeof(struct hashentry_s*));
	if (htmp.list == NULL)
		return (-1);

	for (i = 0; i < ht->size; i++) {
		for (entry = ht->list[i]; entry; entry = next) {
			next = entry->next;
			ht_insert(&htmp, entry->key, entry->data);
			ht_delete(ht, entry->key);
		}
	}

	free(ht->list);
	ht->size = htmp.size;
	ht->list = htmp.list;
	ht->nentries = htmp.nentries;
	ht_setloadfactor(ht);

	return (0);
}
Пример #3
0
int main(void)
{
	dict_h lh ;
	dict_iter iter ;
	int i ;
	int *ip ;
	struct ht_args args ;

	args.ht_bucket_entries = 2 ;
	args.ht_table_entries = 2 ;
	args.ht_objvalue = getval ;
	args.ht_keyvalue = getval ;

	lh = ht_create( int_comp, int_comp, 0, &args ) ;

	for ( i = 0 ; i < N ; i++ )
	{
		nums[ i ] = 10-i ;
		if ( ht_insert( lh, &nums[ i ] ) != DICT_OK )
		{
			printf( "Failed at %d\n", i ) ;
			exit( 1 ) ;
		}
	}

	printf( "Search/delete test\n" ) ;
	i = 7 ;
	ip = INTP( ht_search( lh, &i ) ) ;
	if ( ip == NULL )
		printf( "Search failed\n" ) ;
	else
		if ( ht_delete( lh, ip ) != DICT_OK )
		{
			printf( "Delete failed\n" ) ;
			exit( 0 ) ;
		}

	for ( i = 0 ; i < N ; i++ )
		if (( ip = INTP( ht_search( lh, &nums[ i ] ) ) ))
			printf( "%d found\n", nums[ i ] ) ;
		else
			printf( "%d not found\n", nums[ i ] ) ;

	iter = ht_iterate( lh , DICT_FROM_START ) ;
	while (( ip = INTP( ht_nextobj( lh, iter ) ) ))
		printf( "Object = %d\n", *ip ) ;

	for ( ip = INTP(ht_minimum( lh )) ; ip ; ip = INTP(ht_successor( lh, ip )) )
		printf( "Object = %d\n", *ip ) ;

	for ( ip=INTP(ht_maximum( lh )) ; ip ; ip=INTP(ht_predecessor( lh, ip )) )
		printf( "Object = %d\n", *ip ) ;

	exit( 0 ) ;
}
Пример #4
0
/* This is similar to rbm_remove, but doesn't destroy the STRBUF */
int rbm_deregister(const char *filename)
{
    // Rprintf("rbm_deregister: deregistering file: %s\n", filename);

    if (ht_delete(strbufv, filename) != 0) {
        Rprintf("rbm_deregister: error: file not registered: %s\n", filename);
        return -1;
    }

    return 0;
}
Пример #5
0
int main(int argc, char** argv) {

    HashTable hash_table;
    Node *node;
    
    // create table.
    ht_create(&hash_table, 23, NULL, NULL, NULL);
    
    // insert nodes.
    ht_insert( &hash_table, "hg456h", "hh");
    ht_insert( &hash_table, "i46fh5LL", "ii");
    ht_insert( &hash_table, "7dfgsd89", "ee77777");
    ht_insert( &hash_table, "f7ert89f", "ff");
    ht_insert( &hash_table, "g2fghsd52g", "gg");
    ht_insert( &hash_table, "hg43457", "hh");
    ht_insert( &hash_table, "i46dfgkffh5i", "ii");
    ht_insert( &hash_table, "78çlikj9", "ee");
    ht_insert( &hash_table, "f78dcfb9f", "ff");
    ht_insert( &hash_table, "g254342", "gg");
    ht_insert( &hash_table, "hg445656h", "hh");
    ht_insert( &hash_table, "i4645645fh5i99", "ii99"); 
    
    // retrieve information
    node = ht_get_node(&hash_table, "i4645645fh5i99");
    if (node != NULL)
        printf("data %s\n", (char *)node->data);
    
    node = ht_get_node(&hash_table, "789");
    if (node != NULL)
        printf("data %s\n", (char *)node->data);
    
    node = ht_get_node(&hash_table, "7dfgsd89");
    if (node != NULL)
        printf("data %s\n\n", (char *)node->data);
    
    // delete nodes
    ht_delete_entry(&hash_table, "hg456h");
    ht_delete_entry(&hash_table, "i4645645fh5i99");
    
    // print data.
    printf("*-*-*-*-*- Print all *-*-*-*-*-\n\n");
    ht_print_all( &hash_table );
    
    ht_delete( &hash_table );
    return (EXIT_SUCCESS);
}
Пример #6
0
int main(int argc, char *argv[]) {
  hashtbl_t ht;
  char **keys;
  int i, j, retval;
  retval = ht_init(&ht, 5, NULL, free);
  ASSERT_INT_EQ(0, retval, "ht_init: clean initialization");

  for (j = 0; j < 3; j++) {
    for (i = 0; i < 10; i++) {
      char *data;
      char key[12];

      sprintf(key, "hello %d", i);
      data = strdup("world");  /* free()d by ht_destroy(). */

      retval = ht_put(&ht, key, data);
      ASSERT_INT_EQ(0, retval, "ht_put: returns 0 on success.");
      ASSERT_TRUE(ht_get(&ht, key) == data, "ht_get: look up newly-put key");
    }
  }
  ASSERT_LONG_EQ(10, ht.nelems, "ht_put: update element count correctly");

  ASSERT_TRUE(ht_get(&ht, "hello 13") == NULL,
              "ht_get: look up non-existing key");
  ht_call_for_each(&ht, call_for_each_test);
  ASSERT_INT_EQ(10, n_calls, "ht_call_for_each: verify repeated invokations");

  keys = malloc(ht.nelems * sizeof(char *));
  retval = ht_keys(&ht, keys);
  ASSERT_INT_EQ(10, retval, "ht_keys: returns the number of keys.");
  /* TODO(jhinds): verify the contents of keys[] */

  ht_delete(&ht, "hello 0");
  ASSERT_TRUE(ht_get(&ht, "hello 0") == NULL,
              "ht_delete: removes entry successfully");
  ASSERT_LONG_EQ(9, ht.nelems, "ht_delete: updates element count correctly");

  return unittest_has_error;
}
Пример #7
0
/*! Randomly lookup data in the hash */
static void *hash_test_lookup(void *d)
{
	struct hash_test *data = d;
	int max;
	unsigned seed = time(NULL);

	/* ast_atomic_fetchadd_int provide a memory fence so that the optimizer doesn't
	 * optimize away reads.
	 */
	while ((max = ast_atomic_fetchadd_int(&data->grow_count, 0)) < data->max_grow) {
		int i;
		char *obj;
		int is_in_hashtab;

		if (is_timed_out(data)) {
			return "Lookup timed out";
		}

		if (max == 0) {
			/* No data yet; yield and try again */
			sched_yield();
			continue;
		}

		/* Randomly lookup one object from the hash */
		i = rand_r(&seed) % max;
		obj = ht_new(i);
		if (obj == NULL) {
			return "Allocation failed.";
		}
		is_in_hashtab = (ast_hashtab_lookup(data->to_be_thrashed, obj) != NULL);
		ht_delete(obj);
		if (!is_in_hashtab) {
			return "key unexpectedly missing";
		}
	}

	return NULL;
}
Пример #8
0
void
stress_test_ht(int amt)
{
	ht t;
	int i;
	gendata x, y;

	/* Just take a modulo somewhere around amt/4. */
	t = ht_create((unsigned int)(amt / 4.0), num_hash);
	assert(ht_empty(t));

	printf("Creating a hash table with %d items...\n", amt);
	for (i = 0; i < amt; ++i) {
		x.num = y.num = i;
		t = ht_insert_uniq(t, x, y, num_eq);

		assert(!ht_empty(t));

		ht_lookup(t, x, num_eq, &y);
		assert(x.num == y.num);
	}

	y.ptr = NULL;
	printf("Walking a hash table of %d items...\n", amt);
	ht_walk(t, walker, y);

	printf("Deleting %d items from the hash table...\n", amt);
	for (i = 0; i < amt; ++i) {
		/* Inserting an item that's already there should fail */
		x.num = i;
		y.num = i;			/* Value does not matter */
		assert(ht_insert_uniq(t, x, y, num_eq) == NULL);

		t = ht_delete(t, x, num_eq, NULL, NULL);
	}
	assert(ht_empty(t));
	ht_destroy(t, NULL, NULL);
}
Пример #9
0
int main()
{
    double points[] = {
        922803.7855, 7372394.688, 0,
        922849.2037, 7372307.027, 1,
        922894.657, 7372219.306, 2,
        922940.1475, 7372131.528, 3,
        922985.6777, 7372043.692, 4,
        923031.2501, 7371955.802, 5,
        923076.8669, 7371867.857, 6,
        923122.5307, 7371779.861, 7,
        923168.2439, 7371691.816, 8,
        923214.0091, 7371603.722, 9,
        923259.8288, 7371515.583, 10,
        922891.3958, 7372440.117, 11,
        922936.873, 7372352.489, 12,
        922982.3839, 7372264.804, 13,
        923027.9308, 7372177.064, 14,
        923073.5159, 7372089.268, 15,
        923119.1415, 7372001.42, 16,
        923164.8099, 7371913.521, 17,
        923210.5233, 7371825.572, 18,
        923256.2841, 7371737.575, 19,
        923302.0946, 7371649.534, 20,
        923347.9572, 7371561.45, 21,
        922978.9747, 7372485.605, 22,
        923024.5085, 7372398.009, 23,
        923070.0748, 7372310.358, 24,
        923115.6759, 7372222.654, 25,
        923161.3136, 7372134.897, 26,
        923206.9903, 7372047.09, 27,
        923252.7079, 7371959.233, 28,
        923298.4686, 7371871.33, 29,
        923344.2745, 7371783.381, 30,
        923390.1279, 7371695.389, 31,
        923436.0309, 7371607.357, 32,
        923066.5232, 7372531.148, 33,
        923112.1115, 7372443.583, 34,
        923157.7311, 7372355.966, 35,
        923203.3842, 7372268.296, 36,
        923249.0725, 7372180.577, 37,
        923294.7981, 7372092.808, 38,
        923340.5628, 7372004.993, 39,
        923386.3686, 7371917.132, 40,
        923432.2176, 7371829.229, 41,
        923478.1116, 7371741.284, 42,
        923524.0527, 7371653.302, 43,
        923154.0423, 7372576.746, 44,
        923199.6831, 7372489.211, 45,
        923245.3541, 7372401.625, 46,
        923291.0572, 7372313.989, 47,
        923336.7941, 7372226.305, 48,
        923382.5667, 7372138.574, 49,
        923428.3766, 7372050.798, 50,
        923474.2256, 7371962.978, 51,
        923520.1155, 7371875.118, 52,
        923566.0481, 7371787.218, 53,
        923612.0252, 7371699.282, 54,
        923241.533, 7372622.396, 55,
        923287.2244, 7372534.889, 56,
        923332.9449, 7372447.334, 57,
        923378.6963, 7372359.731, 58,
        923424.4801, 7372272.081, 59,
        923470.2979, 7372184.385, 60,
        923516.1513, 7372096.646, 61,
        923562.0418, 7372008.866, 62,
        923607.9709, 7371921.046, 63,
        923653.9402, 7371833.188, 64,
        923699.9514, 7371745.296, 65,
        923328.9962, 7372668.095, 66,
        923374.7365, 7372580.617, 67,
        923420.5049, 7372493.091, 68,
        923466.303, 7372405.519, 69,
        923512.1321, 7372317.901, 70,
        923557.9936, 7372230.24, 71,
        923603.8889, 7372142.536, 72,
        923649.8192, 7372054.793, 73,
        923695.786, 7371967.011, 74,
        923741.7905, 7371879.193, 75,
        923787.8341, 7371791.342, 76,
        923416.4327, 7372713.844, 77,
        923462.2204, 7372626.393, 78,
        923508.0353, 7372538.895, 79,
        923553.8787, 7372451.353, 80,
        923599.7517, 7372363.766, 81,
        923645.6555, 7372276.137, 82,
        923691.5914, 7372188.467, 83,
        923737.5603, 7372100.757, 84,
        923783.5634, 7372013.011, 85,
        923829.6017, 7371925.231, 86,
        923875.6763, 7371837.419, 87,
        923503.8433, 7372759.64, 88,
        923549.6771, 7372672.214, 89,
        923595.5372, 7372584.744, 90,
        923641.4246, 7372497.23, 91,
        923687.3404, 7372409.673, 92,
        923733.2855, 7372322.074, 93,
        923779.2608, 7372234.436, 94,
        923825.2672, 7372146.759, 95,
        923871.3056, 7372059.047, 96,
        923917.3766, 7371971.301, 97,
        923963.4812, 7371883.524, 98,
        923591.2288, 7372805.481, 99,
        923637.1076, 7372718.081, 100,
        923683.0118, 7372630.638, 101,
        923728.9423, 7372543.151, 102,
        923774.8998, 7372455.622, 103,
        923820.8852, 7372368.052, 104,
        923866.8991, 7372280.443, 105,
        923912.9422, 7372192.797, 106,
        923959.015, 7372105.116, 107,
        924005.118, 7372017.402, 108,
        924051.2518, 7371929.657, 109,
        923678.5898, 7372851.367, 110,
        923724.5126, 7372763.992, 111,
        923770.46, 7372676.574, 112,
        923816.4328, 7372589.113, 113,
        923862.4314, 7372501.611, 114,
        923908.4564, 7372414.069, 115,
        923954.5083, 7372326.488, 116,
        924000.5875, 7372238.87, 117,
        924046.6941, 7372151.218, 118,
        924092.8286, 7372063.533, 119,
        924138.9911, 7371975.818, 120
    };

    int size = sizeof(points) / sizeof(double) / 3;
    hashtable* ht;
    int i;

    /*
     * double[2] key 
     */

    printf("\n1. Testing a table with key of double[2] type\n\n");

    printf("  creating a table...");
    ht = ht_create_d2(size);
    printf("done\n");

    printf("  inserting %d values from a file...", size);
    for (i = 0; i < size; ++i)
        ht_insert(ht, &points[i * 3], &points[i * 3 + 2]);
    printf("done\n");

    printf("  stats:\n");
    printf("    %d entries, %d table elements, %d filled elements\n", ht->n, ht->size, ht->nhash);
    printf("    %f entries per hash value in use\n", (double) ht->n / ht->nhash);

    printf("  finding and printing each 10th data:\n");
    for (i = 0; i < size; i += 10) {
        double* point = &points[i * 3];
        double* data = ht_find(ht, point);

        if (data != NULL)
            printf("    i = %d; data = \"%d\"\n", i, (int)* data);
        else
            printf("    i = %d; data = <none>\n", i);
    }

    printf("  removing every 3rd element...");
    for (i = 0; i < size; i += 3) {
        double* point = &points[i * 3];
        ht_delete(ht, point);
    }
    printf("done\n");

    printf("  stats:\n");
    printf("    %d entries, %d table elements, %d filled elements\n", ht->n, ht->size, ht->nhash);
    printf("    %f entries per hash value in use\n", (double) ht->n / ht->nhash);

    printf("  finding and printing each 10th data:\n");
    for (i = 0; i < size; i += 10) {
        double* point = &points[i * 3];
        double* data = ht_find(ht, point);

        if (data != NULL)
            printf("    i = %d; data = \"%d\"\n", i, (int)* data);
        else
            printf("    i = %d; data = <none>\n", i);
    }

    printf("  printing all data by calling ht_process():\n ");
    ht_process(ht, print_double);

    printf("\n  destroying the hash table...");
    ht_destroy(ht);
    printf("done\n");

    /*
     * char* key 
     */

    printf("\n2. Testing a table with key of char* type\n\n");

    printf("  creating a table...");
    ht = ht_create_str(size);
    printf("done\n");

    printf("  inserting %d elements with deep copy of each data string...", size);
    for (i = 0; i < size; ++i) {
        char key[BUFSIZE];
        char str[BUFSIZE];
        char* data;

        sprintf(key, "%d-th key", i);
        sprintf(str, "%d-th data", i);
        data = strdup(str);
        ht_insert(ht, key, data);
    }
    printf("done\n");

    printf("  stats:\n");
    printf("    %d entries, %d table elements, %d filled elements\n", ht->n, ht->size, ht->nhash);
    printf("    %f entries per hash value in use\n", (double) ht->n / ht->nhash);

    printf("  finding and printing each 10th data:\n");
    for (i = 0; i < size; i += 10) {
        char key[BUFSIZE];
        char* data;

        sprintf(key, "%d-th key", i);
        data = ht_find(ht, key);
        if (data != NULL)
            printf("    i = %d; data = \"%s\"\n", i, data);
        else
            printf("    i = %d; data = <none>\n", i);
    }

    printf("  removing every 3rd element...");
    for (i = 0; i < size; i += 3) {
        char key[BUFSIZE];

        sprintf(key, "%d-th key", i);
        free(ht_delete(ht, key));
    }
    printf("done\n");

    printf("  stats:\n");
    printf("    %d entries, %d table elements, %d filled elements\n", ht->n, ht->size, ht->nhash);
    printf("    %f entries per hash value in use\n", (double) ht->n / ht->nhash);

    printf("  finding and printing each 10th data:\n");
    for (i = 0; i < size; i += 10) {
        char key[BUFSIZE];
        char* data;

        sprintf(key, "%d-th key", i);
        data = ht_find(ht, key);
        if (data != NULL)
            printf("    i = %d; data = \"%s\"\n", i, data);
        else
            printf("    i = %d; data = <none>\n", i);
    }

    printf("  printing all data by calling ht_process():\n ");
    ht_process(ht, print_string);

    printf("\n  freeing the remaining data by calling ht_process()...");
    ht_process(ht, free);
    printf("done\n");

    printf("  destroying the hash table...");
    ht_destroy(ht);
    printf("done\n");

    return 0;
}
Пример #10
0
int main(int argc, char **argv)
{
	struct option long_options[] = {
		// These options don't set a flag
		{"help",                      no_argument,       NULL, 'h'},
		{"alternate",                 no_argument,       NULL, 'A'},
		{"effective",                 required_argument, NULL, 'f'},
		{"duration",                  required_argument, NULL, 'd'},
		{"initial-size",              required_argument, NULL, 'i'},
		{"num-threads",               required_argument, NULL, 'n'},
		{"range",                     required_argument, NULL, 'r'},
		{"seed",                      required_argument, NULL, 's'},
		{"update-rate",               required_argument, NULL, 'u'},
		{"move-rate",                 required_argument, NULL, 'm'},
		{"snapshot-rate",             required_argument, NULL, 'a'},
		{"elasticity",                required_argument, NULL, 'x'},
		{NULL, 0, NULL, 0}
	};
	
	ht_intset_t *set;
	int i, c, size;
	val_t last = 0; 
	val_t val = 0;
	unsigned long reads, effreads, updates, effupds, moves, snapshots, aborts, 
	aborts_locked_read, aborts_locked_write, aborts_validate_read, 
	aborts_validate_write, aborts_validate_commit, aborts_invalid_memory, 
	aborts_double_write,
	max_retries, failures_because_contention;
	thread_data_t *data;
	pthread_t *threads;
	pthread_attr_t attr;
	barrier_t barrier;
	struct timeval start, end;
	struct timespec timeout;
	int duration = DEFAULT_DURATION;
	int initial = DEFAULT_INITIAL;
	int nb_threads = DEFAULT_NB_THREADS;
	long range = DEFAULT_RANGE;
	int seed = DEFAULT_SEED;
	int update = DEFAULT_UPDATE;
	int load_factor = DEFAULT_LOAD;
	int move = DEFAULT_MOVE;
	int snapshot = DEFAULT_SNAPSHOT;
	int unit_tx = DEFAULT_ELASTICITY;
	int alternate = DEFAULT_ALTERNATE;
	int effective = DEFAULT_EFFECTIVE;
	sigset_t block_set;
	
	while(1) {
		i = 0;
		c = getopt_long(argc, argv, "hAf:d:i:n:r:s:u:m:a:l:x:", long_options, &i);
		
		if(c == -1)
			break;
		
		if(c == 0 && long_options[i].flag == 0)
			c = long_options[i].val;
		
		switch(c) {
				case 0:
					// Flag is automatically set 
					break;
				case 'h':
					printf("intset -- STM stress test "
								 "(hash table)\n"
								 "\n"
								 "Usage:\n"
								 "  intset [options...]\n"
								 "\n"
								 "Options:\n"
								 "  -h, --help\n"
								 "        Print this message\n"
								 "  -A, --Alternate\n"
								 "        Consecutive insert/remove target the same value\n"
								 "  -f, --effective <int>\n"
								 "        update txs must effectively write (0=trial, 1=effective, default=" XSTR(DEFAULT_EFFECTIVE) ")\n"
								 "  -d, --duration <int>\n"
								 "        Test duration in milliseconds (0=infinite, default=" XSTR(DEFAULT_DURATION) ")\n"
								 "  -i, --initial-size <int>\n"
								 "        Number of elements to insert before test (default=" XSTR(DEFAULT_INITIAL) ")\n"
								 "  -n, --num-threads <int>\n"
								 "        Number of threads (default=" XSTR(DEFAULT_NB_THREADS) ")\n"
								 "  -r, --range <int>\n"
								 "        Range of integer values inserted in set (default=" XSTR(DEFAULT_RANGE) ")\n"
								 "  -s, --seed <int>\n"
								 "        RNG seed (0=time-based, default=" XSTR(DEFAULT_SEED) ")\n"
								 "  -u, --update-rate <int>\n"
								 "        Percentage of update transactions (default=" XSTR(DEFAULT_UPDATE) ")\n"
								 "  -m , --move-rate <int>\n"
								 "        Percentage of move transactions (default=" XSTR(DEFAULT_MOVE) ")\n"
								 "  -a , --snapshot-rate <int>\n"
								 "        Percentage of snapshot transactions (default=" XSTR(DEFAULT_SNAPSHOT) ")\n"
								 "  -l , --load-factor <int>\n"
								 "        Ratio of keys over buckets (default=" XSTR(DEFAULT_LOAD) ")\n"
								 "  -x, --elasticity (default=4)\n"
								 "        Use elastic transactions\n"
								 "        0 = non-protected,\n"
								 "        1 = normal transaction,\n"
								 "        2 = read elastic-tx,\n"
								 "        3 = read/add elastic-tx,\n"
								 "        4 = read/add/rem elastic-tx,\n"
								 "        5 = elastic-tx w/ optimized move.\n"
								 );
					exit(0);
				case 'A':
					alternate = 1;
					break;
				case 'f':
					effective = atoi(optarg);
					break;
				case 'd':
					duration = atoi(optarg);
					break;
				case 'i':
					initial = atoi(optarg);
					break;
				case 'n':
					nb_threads = atoi(optarg);
					break;
				case 'r':
					range = atol(optarg);
					break;
				case 's':
					seed = atoi(optarg);
					break;
				case 'u':
					update = atoi(optarg);
					break;
				case 'm':
					move = atoi(optarg);
					break;
				case 'a':
					snapshot = atoi(optarg);
					break;
				case 'l':
					load_factor = atoi(optarg);
					break;
				case 'x':
					unit_tx = atoi(optarg);
					break;
				case '?':
					printf("Use -h or --help for help\n");
					exit(0);
				default:
					exit(1);
		}
	}
	
	assert(duration >= 0);
	assert(initial >= 0);
	assert(nb_threads > 0);
	assert(range > 0 && range >= initial);
	assert(update >= 0 && update <= 100);
	assert(move >= 0 && move <= update);
	assert(snapshot >= 0 && snapshot <= (100-update));
	assert(initial < MAXHTLENGTH);
	assert(initial >= load_factor);
	
	printf("Set type     : hash table\n");
	printf("Duration     : %d\n", duration);
	printf("Initial size : %d\n", initial);
	printf("Nb threads   : %d\n", nb_threads);
	printf("Value range  : %ld\n", range);
	printf("Seed         : %d\n", seed);
	printf("Update rate  : %d\n", update);
	printf("Load factor  : %d\n", load_factor);
	printf("Move rate    : %d\n", move);
	printf("Snapshot rate: %d\n", snapshot);
	printf("Elasticity   : %d\n", unit_tx);
	printf("Alternate    : %d\n", alternate);	
	printf("Effective    : %d\n", effective);
	printf("Type sizes   : int=%d/long=%d/ptr=%d/word=%d\n",
				 (int)sizeof(int),
				 (int)sizeof(long),
				 (int)sizeof(void *),
				 (int)sizeof(uintptr_t));
	
	timeout.tv_sec = duration / 1000;
	timeout.tv_nsec = (duration % 1000) * 1000000;
	
	if ((data = (thread_data_t *)malloc(nb_threads * sizeof(thread_data_t))) == NULL) {
		perror("malloc");
		exit(1);
	}
	if ((threads = (pthread_t *)malloc(nb_threads * sizeof(pthread_t))) == NULL) {
		perror("malloc");
		exit(1);
	}
	
	if (seed == 0)
		srand((int)time(0));
	else
		srand(seed);
	
	//maxhtlength = (unsigned int) initial / load_factor;
	set = ht_new();
	
	stop = 0;
	
	// Init STM 
	printf("Initializing STM\n");
	
	TM_STARTUP();
	
	// Populate set 
	printf("Adding %d entries to set\n", initial);
	i = 0;
	maxhtlength = (int) (initial / load_factor);
	while (i < initial) {
		val = rand_range(range);
		if (ht_add(set, val, 0)) {
		  last = val;
		  i++;			
		}
	}
	size = ht_size(set);
	printf("Set size     : %d\n", size);
	printf("Bucket amount: %d\n", maxhtlength);
	printf("Load         : %d\n", load_factor);
	
	// Access set from all threads 
	barrier_init(&barrier, nb_threads + 1);
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
	for (i = 0; i < nb_threads; i++) {
		printf("Creating thread %d\n", i);
		data[i].first = last;
		data[i].range = range;
		data[i].update = update;
		data[i].load_factor = load_factor;
		data[i].move = move;
		data[i].snapshot = snapshot;
		data[i].unit_tx = unit_tx;
		data[i].alternate = alternate;
		data[i].effective = effective;
		data[i].nb_add = 0;
		data[i].nb_added = 0;
		data[i].nb_remove = 0;
		data[i].nb_removed = 0;
		data[i].nb_move = 0;
		data[i].nb_moved = 0;
		data[i].nb_snapshot = 0;
		data[i].nb_snapshoted = 0;
		data[i].nb_contains = 0;
		data[i].nb_found = 0;
		data[i].nb_aborts = 0;
		data[i].nb_aborts_locked_read = 0;
		data[i].nb_aborts_locked_write = 0;
		data[i].nb_aborts_validate_read = 0;
		data[i].nb_aborts_validate_write = 0;
		data[i].nb_aborts_validate_commit = 0;
		data[i].nb_aborts_invalid_memory = 0;
		data[i].nb_aborts_double_write = 0;
		data[i].max_retries = 0;
		data[i].seed = rand();
		data[i].set = set;
		data[i].barrier = &barrier;
		data[i].failures_because_contention = 0;
		if (pthread_create(&threads[i], &attr, test, (void *)(&data[i])) != 0) {
			fprintf(stderr, "Error creating thread\n");
			exit(1);
		}
	}
	pthread_attr_destroy(&attr);
	
	// Start threads 
	barrier_cross(&barrier);
	
	printf("STARTING...\n");
	gettimeofday(&start, NULL);
	if (duration > 0) {
		nanosleep(&timeout, NULL);
	} else {
		sigemptyset(&block_set);
		sigsuspend(&block_set);
	}
	AO_store_full(&stop, 1);
	gettimeofday(&end, NULL);
	printf("STOPPING...\n");
	
	// Wait for thread completion 
	for (i = 0; i < nb_threads; i++) {
		if (pthread_join(threads[i], NULL) != 0) {
			fprintf(stderr, "Error waiting for thread completion\n");
			exit(1);
		}
	}
	duration = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000);
	aborts = 0;
	aborts_locked_read = 0;
	aborts_locked_write = 0;
	aborts_validate_read = 0;
	aborts_validate_write = 0;
	aborts_validate_commit = 0;
	aborts_invalid_memory = 0;
	aborts_double_write = 0;
	failures_because_contention = 0;
	reads = 0;
	effreads = 0;
	updates = 0;
	effupds = 0;
	moves = 0;
	snapshots = 0;
	max_retries = 0;
	for (i = 0; i < nb_threads; i++) {
		printf("Thread %d\n", i);
		printf("  #add        : %lu\n", data[i].nb_add);
		printf("    #added    : %lu\n", data[i].nb_added);
		printf("  #remove     : %lu\n", data[i].nb_remove);
		printf("    #removed  : %lu\n", data[i].nb_removed);
		printf("  #contains   : %lu\n", data[i].nb_contains);
		printf("  #found      : %lu\n", data[i].nb_found);
		printf("  #move       : %lu\n", data[i].nb_move);
		printf("  #moved      : %lu\n", data[i].nb_moved);
		printf("  #snapshot   : %lu\n", data[i].nb_snapshot);
		printf("  #snapshoted : %lu\n", data[i].nb_snapshoted);
		printf("  #aborts     : %lu\n", data[i].nb_aborts);
		printf("    #lock-r   : %lu\n", data[i].nb_aborts_locked_read);
		printf("    #lock-w   : %lu\n", data[i].nb_aborts_locked_write);
		printf("    #val-r    : %lu\n", data[i].nb_aborts_validate_read);
		printf("    #val-w    : %lu\n", data[i].nb_aborts_validate_write);
		printf("    #val-c    : %lu\n", data[i].nb_aborts_validate_commit);
		printf("    #inv-mem  : %lu\n", data[i].nb_aborts_invalid_memory);
		printf("    #dup-w  : %lu\n", data[i].nb_aborts_double_write);
		printf("    #failures : %lu\n", data[i].failures_because_contention);
		printf("  Max retries : %lu\n", data[i].max_retries);
		aborts += data[i].nb_aborts;
		aborts_locked_read += data[i].nb_aborts_locked_read;
		aborts_locked_write += data[i].nb_aborts_locked_write;
		aborts_validate_read += data[i].nb_aborts_validate_read;
		aborts_validate_write += data[i].nb_aborts_validate_write;
		aborts_validate_commit += data[i].nb_aborts_validate_commit;
		aborts_invalid_memory += data[i].nb_aborts_invalid_memory;
		aborts_double_write += data[i].nb_aborts_double_write;
		failures_because_contention += data[i].failures_because_contention;
		reads += (data[i].nb_contains + data[i].nb_snapshot);
		effreads += data[i].nb_contains + 
		(data[i].nb_add - data[i].nb_added) + 
		(data[i].nb_remove - data[i].nb_removed) + 
		(data[i].nb_move - data[i].nb_moved) +
		data[i].nb_snapshoted;
		updates += (data[i].nb_add + data[i].nb_remove + data[i].nb_move);
		effupds += data[i].nb_removed + data[i].nb_added + data[i].nb_moved; 
		moves += data[i].nb_move;
		snapshots += data[i].nb_snapshot;
		size += data[i].nb_added - data[i].nb_removed;
		if (max_retries < data[i].max_retries)
			max_retries = data[i].max_retries;
	}
	printf("Set size      : %d (expected: %d)\n", ht_size(set), size);
	printf("Duration      : %d (ms)\n", duration);
	printf("#txs          : %lu (%f / s)\n", reads + updates + moves + snapshots, (reads + updates + moves + snapshots) * 1000.0 / duration);
	
	printf("#read txs     : ");
	if (effective) {
		printf("%lu (%f / s)\n", effreads, effreads * 1000.0 / duration);
		printf("  #cont/snpsht: %lu (%f / s)\n", reads, reads * 1000.0 / duration);
	} else printf("%lu (%f / s)\n", reads, reads * 1000.0 / duration);
	
	printf("#eff. upd rate: %f \n", 100.0 * effupds / (effupds + effreads));
	
	printf("#update txs   : ");
	if (effective) {
		printf("%lu (%f / s)\n", effupds, effupds * 1000.0 / duration);
		printf("  #upd trials : %lu (%f / s)\n", updates, updates * 1000.0 / 
					 duration);
	} else printf("%lu (%f / s)\n", updates, updates * 1000.0 / duration);
	
	printf("#move txs     : %lu (%f / s)\n", moves, moves * 1000.0 / duration);
	printf("#snapshot txs : %lu (%f / s)\n", snapshots, snapshots * 1000.0 / duration);
	printf("#aborts       : %lu (%f / s)\n", aborts, aborts * 1000.0 / duration);
	printf("  #lock-r     : %lu (%f / s)\n", aborts_locked_read, aborts_locked_read * 1000.0 / duration);
	printf("  #lock-w     : %lu (%f / s)\n", aborts_locked_write, aborts_locked_write * 1000.0 / duration);
	printf("  #val-r      : %lu (%f / s)\n", aborts_validate_read, aborts_validate_read * 1000.0 / duration);
	printf("  #val-w      : %lu (%f / s)\n", aborts_validate_write, aborts_validate_write * 1000.0 / duration);
	printf("  #val-c      : %lu (%f / s)\n", aborts_validate_commit, aborts_validate_commit * 1000.0 / duration);
	printf("  #inv-mem    : %lu (%f / s)\n", aborts_invalid_memory, aborts_invalid_memory * 1000.0 / duration);
	printf("  #dup-w      : %lu (%f / s)\n", aborts_double_write, aborts_double_write * 1000.0 / duration);
	printf("  #failures   : %lu\n",  failures_because_contention);
	printf("Max retries   : %lu\n", max_retries);
	
	// Delete set 
	ht_delete(set);
	
	// Cleanup STM 
	TM_SHUTDOWN();
	
	free(threads);
	free(data);
	
	return 0;
}
Пример #11
0
bool sdb_ht_delete(SdbHash* ht, const char *key) {
	return ht_delete (ht, key);
}
Пример #12
0
Файл: ht.c Проект: geocar/pwho
static int ht_die_fn(ht *x, void *key, unsigned klen, void *data)
{
	if (ht_delete(x, key, klen) != 1)
		return HT_WILLFAIL;
	return HT_RESTART;
}
Пример #13
0
/* This is a central procedure for the Natural Neighbours interpolation. It
 * uses the Watson's algorithm for the required areas calculation and implies
 * that the vertices of the delaunay triangulation are listed in uniform
 * (clockwise or counterclockwise) order.
 */
static void nnpi_triangle_process(nnpi* nn, point* p, int i)
{
    delaunay* d = nn->d;
    triangle* t = &d->triangles[i];
    circle* c = &d->circles[i];
    circle cs[3];
    int j;

    /*
     * There used to be a useful assertion here:
     *
     * assert(circle_contains(c, p));
     *
     * I removed it after introducing flag `contains' to 
     * delaunay_circles_find(). It looks like the code is robust enough to
     * run without this assertion.
     */

    /*
     * Sibson interpolation by using Watson's algorithm 
     */
    for (j = 0; j < 3; ++j) {
        int j1 = (j + 1) % 3;
        int j2 = (j + 2) % 3;
        int v1 = t->vids[j1];
        int v2 = t->vids[j2];

        if (!circle_build2(&cs[j], &d->points[v1], &d->points[v2], p)) {
            point* p1 = &d->points[v1];
            point* p2 = &d->points[v2];

	    if ((fabs(p1->x - p->x) + fabs(p1->y - p->y)) / c->r < EPS_SAME) {
		/*
		 * if (p1->x == p->x && p1->y == p->y) {
		 */
                nnpi_add_weight(nn, v1, BIGNUMBER);
                return;
	    } else if ((fabs(p2->x - p->x) + fabs(p2->y - p->y)) / c->r < EPS_SAME) {
		/*
		 * } else if (p2->x == p->x && p2->y == p->y) {
		 */
                nnpi_add_weight(nn, v2, BIGNUMBER);
                return;
            }
        }
    }

    for (j = 0; j < 3; ++j) {
        int j1 = (j + 1) % 3;
        int j2 = (j + 2) % 3;
        double det = ((cs[j1].x - c->x) * (cs[j2].y - c->y) - (cs[j2].x - c->x) * (cs[j1].y - c->y));

        if (isnan(det)) {
            /*
             * If the determinant is NaN, then the interpolation point lies
             * almost in between two data points. This case is difficult to
             * handle robustly because the areas calculated are obtained as a
             * diference between two big numbers.
             *
             * Here this is handles in the following way. If a circle is
             * recognised as very large in circle_build2(), then it parameters 
             * are replaced by NaNs, which results in det above being NaN.
             * The resulting area to be calculated for a vertex does not
             * change if the circle center is moved along some line. The closer
             * it is moved to the actual data point positions, the more
             * numerically robust the calculation of areas becomes. In
             * particular, it can be moved to coincide with one of the other
             * circle centers. When this is done, it is ticked by placing the
             * edge parameters into the hash table, so that when the
             * "cancelling" would be about to be done, this new position is
             * used instead.
             *
             * One complicated circumstance is that sometimes a circle is
             * recognised as very large in cases when it is actually not, 
             * when the interpolated point is close to a data point. This is
             * handled by a special treatment in _nnpi_calculate_weights().
             */
            int remove = 1;
            circle* cc = NULL;
            int key[2];

            key[0] = t->vids[j];

            if (nn->bad == NULL)
                nn->bad = ht_create_i2(HT_SIZE);

            if (isnan(cs[j1].x)) {
                key[1] = t->vids[j2];
                cc = ht_find(nn->bad, &key);

                if (cc == NULL) {
                    remove = 0;
                    cc = malloc(sizeof(circle));
                    cc->x = cs[j2].x;
                    cc->y = cs[j2].y;
                    assert(ht_insert(nn->bad, &key, cc) == NULL);
                }
                det = ((cc->x - c->x) * (cs[j2].y - c->y) - (cs[j2].x - c->x) * (cc->y - c->y));
            } else {            /* j2 */
                key[1] = t->vids[j1];
                cc = ht_find(nn->bad, &key);

                if (cc == NULL) {
                    remove = 0;
                    cc = malloc(sizeof(circle));
                    cc->x = cs[j1].x;
                    cc->y = cs[j1].y;
                    assert(ht_insert(nn->bad, &key, cc) == NULL);
                }
                det = ((cs[j1].x - c->x) * (cc->y - c->y) - (cc->x - c->x) * (cs[j1].y - c->y));
            }
            if (remove)
                assert(ht_delete(nn->bad, &key) != NULL);
        }

        nnpi_add_weight(nn, t->vids[j], det);
    }
}
Пример #14
0
/* This is a central procedure for the Natural Neighbours interpolation. It
 * uses the Watson's algorithm for the required areas calculation and implies
 * that the vertices of the delaunay triangulation are listed in uniform
 * (clockwise or counterclockwise) order.
 */
static void nnpi_triangle_process(nnpi* nn, point* p, int i)
{
    delaunay* d = nn->d;
    triangle* t = &d->triangles[i];
    circle* c = &d->circles[i];
    circle cs[3];
    int j;

    /*
     * There used to be a useful assertion here:
     *
     * assert(circle_contains(c, p));
     *
     * I removed it after introducing flag `contains' to 
     * delaunay_circles_find(). It looks like the code is robust enough to
     * run without this assertion.
     */

    /*
     * Sibson interpolation by using Watson's algorithm 
     */
    for (j = 0; j < 3; ++j) {
        int j1 = (j + 1) % 3;
        int j2 = (j + 2) % 3;
        int v1 = t->vids[j1];
        int v2 = t->vids[j2];

        if (!circle_build2(&cs[j], &d->points[v1], &d->points[v2], p)) {
            point* p1 = &d->points[v1];
            point* p2 = &d->points[v2];

            if ((fabs(p1->x - p->x) + fabs(p1->y - p->y)) / c->r < EPS_SAME) {
                /*
                 * if (p1->x == p->x && p1->y == p->y) {
                 */
                nnpi_add_weight(nn, v1, BIGNUMBER);
                return;
            } else if ((fabs(p2->x - p->x) + fabs(p2->y - p->y)) / c->r < EPS_SAME) {
                /*
                 * } else if (p2->x == p->x && p2->y == p->y) {
                 */
                nnpi_add_weight(nn, v2, BIGNUMBER);
                return;
            }
        }
    }

    for (j = 0; j < 3; ++j) {
        int j1 = (j + 1) % 3;
        int j2 = (j + 2) % 3;
        double det = ((cs[j1].x - c->x) * (cs[j2].y - c->y) - (cs[j2].x - c->x) * (cs[j1].y - c->y));

        if (isnan(det)) {
            /*
             * Here, if the determinant is NaN, then the interpolation point
             * lies almost in between two data points. This case is difficult to
             * handle robustly because the areas (determinants) calculated by
             * Watson's algorithm are obtained as a diference between two big
             * numbers. This case is handled here in the following way.
             *
             * If a circle is recognised as very large in circle_build2(), then
             * its parameters are replaced by NaNs, which results in the
             * variable `det' above being NaN.
             * 
             * When this happens inside convex hall of the data, there is
             * always a triangle on another side of the edge, processing of
             * which also produces an invalid circle. Processing of this edge
             * yields two pairs of infinite determinants, with singularities 
             * of each pair cancelling if the point moves slightly off the edge.
             *
             * Each of the determinants corresponds to the (signed) area of a
             * triangle, and an inifinite determinant corresponds to the area of
             * a triangle with one vertex moved to infinity. "Subtracting" one
             * triangle from another within each pair yields a valid
             * quadrilateral (in fact, a trapezoid). The doubled area of these
             * quadrilaterals is calculated in the cycle over ii below.
             */
            int j1bad = isnan(cs[j1].x);
            int key[2];
            double* v = NULL;

            key[0] = t->vids[j];

            if (nn->bad == NULL)
                nn->bad = ht_create_i2(HT_SIZE);

            key[1] = (j1bad) ? t->vids[j2] : t->vids[j1];
            v = ht_find(nn->bad, &key);

            if (v == NULL) {
                v = malloc(8 * sizeof(double));
                if (j1bad) {
                    v[0] = cs[j2].x;
                    v[1] = cs[j2].y;
                } else {
                    v[0] = cs[j1].x;
                    v[1] = cs[j1].y;
                }
                v[2] = c->x;
                v[3] = c->y;
                (void) ht_insert(nn->bad, &key, v);
                det = 0.0;
            } else {
                int ii;

                if (j1bad) {
                    v[6] = cs[j2].x;
                    v[7] = cs[j2].y;
                } else {
                    v[6] = cs[j1].x;
                    v[7] = cs[j1].y;
                }
                v[4] = c->x;
                v[5] = c->y;

                det = 0;
                for (ii = 0; ii < 4; ++ii) {
                    int ii1 = (ii + 1) % 4;

                    det += (v[ii * 2] + v[ii1 * 2]) * (v[ii * 2 + 1] - v[ii1 * 2 + 1]);
                }
                det = fabs(det);

                free(v);
                ht_delete(nn->bad, &key);
            }
        }

        nnpi_add_weight(nn, t->vids[j], det);
    }
}