Esempio n. 1
0
// Builds index and loads probe values. For each value, the index is probed
// and the range identifier is appended to an array. The array is then printed out.
// takes in command line arguments in the form: build K P 9 5 9
int main(int argc, char** argv) {
  if(argc < 4){
    printf("Usage: build K P <fanouts> \n ");
    return 0;
  }
  // Gathers input and builds index
  int levels_n = argc - 3;
  int k = atoi(argv[1]);
  int p = atoi(argv[2]);
  int* fanouts = malloc(levels_n * sizeof(int));
  for(int f = 0; f<levels_n; f++){
    fanouts[f] = atoi(argv[3+f]);
  }
  RangeIndex range_index = build_index(k, levels_n, fanouts);

  if(range_index.didFail == 1){
    free(fanouts);
    return 0;
  }

  int32_t  *level;
  for(int i=0; i<levels_n; i++){
    level = range_index.index[i];
    printf("\n[ ");
    for(int j=0; j<range_index.level_sizes[i]; j++){
      if(level[j] == INT_MAX)
      printf("MI ");
      else printf("%d ", level[j]);
    }
    printf(" ] \n");
  }

  // Generates P random values and probes index for each value
  rand32_t *gen = rand32_init(time(NULL));
  int32_t *probes = generate(p, gen);
  free(gen);

  for(int i = 0; i<p; i++){
    int range = probe(range_index, levels_n, fanouts, probes[i]);
    printf("probe %d: %d\n", probes[i], range);
  }

  //clean up
  for(int i=0; i<levels_n; i++){
    free(range_index.index[i]);
  }
  free(range_index.index);
  free(range_index.level_sizes);
  free(probes);
  return 0;
}
Esempio n. 2
0
// Builds the tree index.
// k = number of keys, levels_n = number of levels, fanouts = array of fanouts for each level
RangeIndex build_index(int k, int levels_n, int *fanouts){
  RangeIndex range_index;
  // Initialize an array to store how large each level should be
  int* level_sizes = malloc(levels_n * sizeof(int));
  for(int l = 0; l<levels_n; l++){
    level_sizes[l] = 0;
  }

  // Find size of each level
  int key = 0;
  int should_do[levels_n];
  for(int l=0; l<levels_n; l++){
    should_do[l] = 1;
  }
  int current = levels_n - 1;

  while(key < k){
    while(should_do[current] == 0){
      current -= 1;
    }
    // if there are still keys left over and tree is full, report error.
    if(current < 0){
      printf("Error: Too many build keys! \n");
      free(level_sizes);
      range_index.didFail = 1;
      return range_index;
    }

    level_sizes[current]++;

    for(int reset=levels_n-1; reset > current; reset--){
      should_do[reset] = 1;
    }

    if(level_sizes[current] % (fanouts[current] - 1 ) == 0){
      should_do[current] = 0;
    }
    current = levels_n - 1;
    key++;
  }

  // Find padding for each level
  for(int i=0; i < levels_n; i++){
    printf("levels[%d] = %d\n", i, level_sizes[i]);
    level_sizes[i] += (level_sizes[i] % (fanouts[i]-1));
  }

  // If root node is empty, there are too few keys and an error should be reported.
  if (level_sizes[0] == 0) {
    printf("Error: Too few build keys! \n");
    free(level_sizes);
    range_index.didFail = 1;
    return range_index;
  }

  // Create index
  int32_t  **index = malloc(sizeof(int32_t *)*levels_n);
  void *ptr;
  for(int i=0; i<levels_n; i++){
    if(posix_memalign(&ptr, 16, sizeof(int32_t ) * level_sizes[i]) != 0){
      printf("Failed to allocate memory\n");
      range_index.didFail = 1;
      return range_index;
    }
    index[i] = ptr;
  }

// Hold a count of how many keys we've added for each level
  int level_counts[levels_n];
  for(int i=0; i<levels_n; i++){
    level_counts[i] = 0; //initialize
  }

  key = 0;
  for(int l=0; l<levels_n; l++){
    should_do[l] = 1;
  }

  // Generate k random keys
  rand32_t *gen = rand32_init(time(NULL));
  int32_t *keys = generate_sorted_unique(k, gen);
  free(gen);

  current = levels_n - 1;
  int32_t  *level;
  // Initialze to MAX INT
  for(int i=0; i<levels_n; i++){
    level = index[i];
    for(int j=0; j<level_sizes[i]; j++){
      level[j] = INT_MAX;
    }
  }

  // Insert keys
  while(key < k){

    while(should_do[current] == 0){
      current -= 1;
    }

    level = index[current];
    level[level_counts[current]] = keys[key];
    level_counts[current]++;

    for(int reset=levels_n-1; reset > current; reset--){
      should_do[reset] = 1;
    }

    // If node full
    if(level_counts[current] % (fanouts[current] - 1 ) == 0){
      should_do[current] = 0;
    }

    current = levels_n - 1;
    key++;

  }

  // Clean up and return
  free(keys);
  range_index.index = index;
  range_index.level_sizes = level_sizes;
  return range_index;
}
Esempio n. 3
0
int main(int argc, char* argv[]) {
        // parsing arguments
        assert(argc > 3);
        size_t num_keys = strtoull(argv[1], NULL, 0);
        size_t num_probes = strtoull(argv[2], NULL, 0);
        size_t num_levels = (size_t) argc - 3;
        size_t* fanout = malloc(sizeof(size_t) * num_levels);
        assert(fanout != NULL);
        for (size_t i = 0; i < num_levels; ++i) {
                fanout[i] = strtoull(argv[i + 3], NULL, 0);
                assert(fanout[i] >= 2 && fanout[i] <= 17);
        }
			
        // building the tree index
        rand32_t* gen = rand32_init((uint32_t) time(NULL));
        assert(gen != NULL);
        int32_t* delimiter = generate_sorted_unique(num_keys, gen);
        assert(delimiter != NULL);
        Tree* tree = build_index(num_levels, fanout, num_keys, delimiter);
        free(delimiter);
        free(fanout);
        if (tree == NULL) {
                free(gen);
                exit(EXIT_FAILURE);
        }


        // generate probes
        int32_t* probe = generate(num_probes, gen);
        assert(probe != NULL);
        free(gen);
        uint32_t* result = malloc(sizeof(uint32_t) * num_probes);
		uint32_t* result1 = malloc(sizeof(uint32_t) * num_probes);
		uint32_t* result2 = malloc(sizeof(uint32_t) * num_probes);
        assert(result != NULL);
		
        // perform index probing (Phase 2)
		struct timeval stop_1, stop_2, start_1, start_2, start_3, stop_3;

		gettimeofday(&start_1, NULL);
		for (size_t i = 0; i < num_probes; ++i) {
                result[i] = probe_index(tree, probe[i]);
        }
		gettimeofday(&stop_1, NULL);	

		gettimeofday(&start_2, NULL);
		for (size_t i = 0; i < num_probes; ++i) {
				result1[i] = probe_index_sse(tree,probe[i]);
        }
		gettimeofday(&stop_2, NULL);	
		gettimeofday(&start_3, NULL);
		int flag=0;
		if(tree->num_levels==3 && (tree->node_capacity[0]==8) && (tree->node_capacity[1]==4) && (tree->node_capacity[2]==8))
		{
			__m128i lvl_0_a = _mm_load_si128(&(tree->key_array[0][0])); 
			__m128i lvl_0_b = _mm_load_si128(&(tree->key_array[0][0])+4); 
        
			for (size_t i = 0; i < num_probes/4; ++i) {
				__m128i k=_mm_load_si128((__m128i*)&probe[4*i]);
				probe_hardcoded(tree,k,result2,lvl_0_a, lvl_0_b, 4*i);
			}
			flag=1; //Setting flag to determine whether result2 needs to be published or not
		}
		gettimeofday(&stop_3, NULL);
		int ch=0;
		printf("Enter 1 if you want to print the results along with the time:");
		scanf("%d",&ch);
		if(ch==1){
		for (size_t i = 0; i < num_probes; ++i) {
                if(flag==1)
				fprintf(stdout, "%d:%d %u %u %u\n", i,probe[i], result[i], result1[i], result2[i]);
				else
				fprintf(stdout, "%d:%d %u %u\n", i,probe[i], result[i], result1[i]);	
        } 
		}
		printf("Method 1 took %lu.\n", stop_1.tv_usec - start_1.tv_usec);
		printf("Method 2 took %lu.\n", stop_2.tv_usec - start_2.tv_usec);
		if(flag==1)printf("Method 3 took %lu.\n", stop_3.tv_usec - start_3.tv_usec);
        free(result);
		free(result1);
		free(result2);
		free(probe);
        cleanup_index(tree);
        return EXIT_SUCCESS;
}