void t_avl() { int i; BST_PTR t = bst_create(); int *a = gen_random_arr(SAMPLE_SIZE); for(i=0; i<SAMPLE_SIZE; i++) bst_insert(t, i); printf("Height of root: %d\n", bst_height(t)); printf("Size of tree: %d\n", bst_size(t)); printf("Min elem: %d\n", bst_min(t)); printf("Max elem: %d\n", bst_max(t)); printf("Nearest elem: %d\n", bst_get_nearest(t,500)); printf("Num LEQ: %d\n", bst_num_leq(t,10)); for(i=0; i<SAMPLE_SIZE-1; i++) { bst_remove(t,a[i]); printf ("Delete %d\n", a[i]); } assert(bst_to_array(t)[0]==a[SAMPLE_SIZE-1]); printf("Height of root: %d\n", bst_height(t)); printf("Size of tree: %d\n", bst_size(t)); printf("Min elem: %d\n", bst_min(t)); printf("Max elem: %d\n", bst_max(t)); printf("Nearest elem: %d\n", bst_get_nearest(t,500)); printf("Num LEQ: %d\n", bst_num_leq(t,10)); free(a); bst_free(t); }
struct bnode* bst_put(struct bnode* x, int val) { int cmp; if (x == NULL) { struct bnode* n = malloc(sizeof(struct bnode)); memset(n, 0, sizeof(struct bnode)); n->v = val; n->n = 1; return n; } cmp = val - x->v; if (cmp < 0) x->left = bst_put(x->left, val); else if (cmp > 0) x->right = bst_put(x->right, val); else x->v = val; x->n = 1 + bst_size(x->left) + bst_size(x->right); return x; }
struct bnode* bst_del(struct bnode* x, int val) { int cmp; struct bnode* t; if (x == NULL) return NULL; cmp = val - x->v; if (cmp < 0) x->left = bst_del(x->left, val); else if (cmp > 0) x->right = bst_del(x->right, val); else { if (x->right == NULL) return x->left; if (x->left == NULL) return x->right; t = x; x = bst_min(t->right); x->right = bst_del_min(t->right); x->left = t->left; } x->n = bst_size(x->left) + bst_size(x->right) + 1; return x; }
int main(){ int i; int a[] = {8, 2, 7, 9, 11, 3, 2, 6}; BST_PTR t = bst_create(); for(i=0; i<8; i++) bst_insert(t, a[i]); assert(bst_size(t) == 7); test_insert(t); test_contains(t); bst_inorder(t); bst_preorder(t); bst_postorder(t); bst_ith_smallest(t, 1) bst_size(t); bst_free(t); }
unsigned long bst_size(node_t* node) { if (ISNULL(node)) { return 0; } else { // fprintf(stderr, "node %p ; left: %p; right: %p\n", node, node->left, node->right); return 1 + bst_size(node->right) + bst_size(node->left); } }
unsigned long bst_size(node_t* node) { if (ISNULL(node)) { return 0; } else if (GETFLAG(node->op) != STATE_OP_MARK) { return 1 + bst_size(node->right) + bst_size(node->left); } else { return bst_size(node->right) + bst_size(node->left); } }
struct bnode* bst_del_min(struct bnode* x) { if (x->left == NULL) return x->right; x->left = bst_del_min(x->left); x->n = 1 + bst_size(x->left) + bst_size(x->right); return x; }
int main(){ int i; /* PART 1 */ int a[] = {8, 2, 6, 9, 11, 3, 7}; BST_PTR t = bst_create(); t_avl(); // t_height(); /* PART 2 */ // bst_inorder(t); // // bst_preorder(t); // // bst_postorder(t); bst_free(t); int sorted_a[] = {2, 3, 6, 7, 8, 9, 11}; t = bst_from_sorted_arr(sorted_a, 7); int *b = bst_to_array(t); printf("Height of root: %d\n", bst_height(t)); printf("Size of tree: %d\n", bst_size(t)); printf("ith smallest element: %d\n", bst_get_ith(t,10)); printf("Num LEQ: %d\n", bst_num_leq(t,3)); printf("A: "); for (i=0; i<7; i++) { printf("%d ", sorted_a[i]); } printf("\n"); printf("B: "); for (i=0; i<7; i++) { printf("%d ", b[i]); } printf("\n"); free(b); bst_free(t); }
int t_bst_insert() { int i; int a[] = {8, 2, 6, 9, 11, 3, 7}; BST_PTR t = bst_create(); for(i=0; i<7; i++) bst_insert(t, a[i]); assert(bst_size(t) == 7); bst_free(t); }
int main(int argc, char* const argv[]) { //place thread on the first cpu set_cpu(0); //initialize the custom memory allocator ssalloc_init(); pthread_t *threads; pthread_attr_t attr; barrier_t barrier; pthread_mutex_t init_lock; struct timeval start, end; struct timespec timeout; thread_data_t *data; sigset_t block_set; //initially, set parameters to their default values num_threads = DEFAULT_NUM_THREADS; seed=DEFAULT_SEED; max_key=DEFAULT_RANGE; updates=DEFAULT_UPDATES; finds=DEFAULT_READS; //inserts=DEFAULT_INSERTS; //removes=DEFAULT_REMOVES; duration=DEFAULT_DURATION; //now read the parameters in case the user provided values for them //we use getopt, the same skeleton may be used for other bechmarks, //though the particular parameters may be different struct option long_options[] = { // These options don't set a flag {"help", no_argument, NULL, 'h'}, {"duration", required_argument, NULL, 'd'}, {"range", required_argument, NULL, 'r'}, {"initial", required_argument, NULL, 'i'}, {"num-threads", required_argument, NULL, 'n'}, {"updates", required_argument, NULL, 'u'}, {"seed", required_argument, NULL, 's'}, {NULL, 0, NULL, 0} }; int i,c; //actually get the parameters form the command-line while(1) { i = 0; c = getopt_long(argc, argv, "hd:n:l:u:i:r:s", 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("lock stress test\n" "\n" "Usage:\n" " stress_test [options...]\n" "\n" "Options:\n" " -h, --help\n" " Print this message\n" " -d, --duration <int>\n" " Test duration in milliseconds (0=infinite, default=" XSTR(DEFAULT_DURATION) ")\n" " -u, --updates <int>\n" " Percentage of update operations (default=" XSTR(DEFAULT_UPDATES) ")\n" " -r, --range <int>\n" " Key range (default=" XSTR(DEFAULT_RANGE) ")\n" " -n, --num-threads <int>\n" " Number of threads (default=" XSTR(DEFAULT_NUM_THREADS) ")\n" " -s, --seed <int>\n" " RNG seed (0=time-based, default=" XSTR(DEFAULT_SEED) ")\n" ); exit(0); case 'd': duration = atoi(optarg); break; case 'u': updates = atoi(optarg); finds = 100 - updates; break; case 'r': max_key = atoi(optarg); break; case 'i': break; case 'l': break; case 'n': num_threads = atoi(optarg); break; case 's': seed = atoi(optarg); break; case '?': printf("Use -h or --help for help\n"); exit(0); default: exit(1); } } max_key--; //we round the max key up to the nearest power of 2, which makes our random key generation more efficient max_key = pow2roundup(max_key)-1; //initialization of the tree root = bst_initialize(num_threads); //initialize the data which will be passed to the threads if ((data = (thread_data_t *)malloc(num_threads * sizeof(thread_data_t))) == NULL) { perror("malloc"); exit(1); } if ((threads = (pthread_t *)malloc(num_threads * sizeof(pthread_t))) == NULL) { perror("malloc"); exit(1); } if (seed == 0) srand((int)time(NULL)); else srand(seed); //flag signaling the threads until when to run *running = 1; //global barrier initialization (used to start the threads at the same time) barrier_init(&barrier, num_threads + 1); pthread_mutex_init(&init_lock, NULL); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); timeout.tv_sec = duration / 1000; timeout.tv_nsec = (duration % 1000) * 1000000; //set the data for each thread and create the threads for (i = 0; i < num_threads; i++) { data[i].id = i; data[i].num_operations = 0; data[i].total_time=0; data[i].num_insert=0; data[i].num_remove=0; data[i].num_search=0; data[i].num_add = max_key/(2 * num_threads); if (i< ((max_key/2)%num_threads)) data[i].num_add++; data[i].seed = rand(); data[i].barrier = &barrier; data[i].init_lock = &init_lock; if (pthread_create(&threads[i], &attr, test, (void *)(&data[i])) != 0) { fprintf(stderr, "Error creating thread\n"); exit(1); } } pthread_attr_destroy(&attr); /* Catch some signals */ if (signal(SIGHUP, catcher) == SIG_ERR || signal(SIGINT, catcher) == SIG_ERR || signal(SIGTERM, catcher) == SIG_ERR) { perror("signal"); exit(1); } // seeds = seed_rand(); // skey_t key; // for (i=0;i<max_key/2;++i) { // key = my_random(&seeds[0],&seeds[1],&seeds[2]) & max_key; // //we make sure the insert was effective (as opposed to just updating an existing entry) // if (bst_add(key, root, 0)!=TRUE) { // i--; // } // } // bst_print(root); /* Start threads */ barrier_cross(&barrier); gettimeofday(&start, NULL); if (duration > 0) { //sleep for the duration of the experiment nanosleep(&timeout, NULL); } else { sigemptyset(&block_set); sigsuspend(&block_set); } //signal the threads to stop *running = 0; gettimeofday(&end, NULL); /* Wait for thread completion */ for (i = 0; i < num_threads; i++) { if (pthread_join(threads[i], NULL) != 0) { fprintf(stderr, "Error waiting for thread completion\n"); exit(1); } } DDPRINT("threads finshed\n",NULL); //compute the exact duration of the experiment duration = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); //bst_print(root); unsigned long operations = 0; ticks total_ticks = 0; long reported_total = 1; //the tree contains two initial dummy nodes, INF1 and INF2 //report some experiment statistics for (i = 0; i < num_threads; i++) { printf("Thread %d\n", i); printf(" #operations : %lu\n", data[i].num_operations); printf(" #inserts : %lu\n", data[i].num_insert); printf(" #removes : %lu\n", data[i].num_remove); operations += data[i].num_operations; total_ticks += data[i].total_time; reported_total = reported_total + data[i].num_add + data[i].num_insert - data[i].num_remove; } printf("Duration : %d (ms)\n", duration); printf("#txs : %lu (%f / s)\n", operations, operations * 1000.0 / duration); //printf("Operation latency %lu\n", total_ticks / operations); //make sure the tree is correct printf("Expected size: %ld Actual size: %lu\n",reported_total,bst_size(root)); free(threads); free(data); return 0; }
#include "common.h" void setup() { bst_init(tree, sizeof(elem_t), sizeof(int), int_cmp, updator); ASSERT(tree != NULL); if (scanf("%i", &idatalen) != 1) { printf("No input\n"); exit(1); } idata = malloc(idatalen * sizeof(int)); for (int i = 0; i < idatalen; i++) { scanf("%i", &idata[i]); bst_insert(tree, &(elem_t){.v = idata[i]}); } verify_tree(tree); ASSERT(bst_size(tree) == idatalen); }
int bst_size(btNode* bst_root) { if (bst_root == 0) return 0; return 1 + bst_size(bst_root->left) + bst_size(bst_root->right); }