/*! 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; }
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); }
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 ) ; }
/* 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; }
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); }
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; }
/*! 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; }
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); }
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; }
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; }
bool sdb_ht_delete(SdbHash* ht, const char *key) { return ht_delete (ht, key); }
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; }
/* 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); } }
/* 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); } }