Ejemplo n.º 1
0
int main() {
  GC_INIT();
  randomize_rand();

  int fail = 0;
  
  const RRB *rrb = rrb_create();
  for (uint32_t i = 0; i < SIZE; i++) {
    rrb = rrb_push(rrb, (void *)((intptr_t) rand() % 10000));
  }

  const RRB **sliced = GC_MALLOC(sizeof(RRB *) * SLICED);
  for (uint32_t i = 0; i < SLICED; i++) {
    uint32_t from = (uint32_t) rand() % SIZE;
    uint32_t to = (uint32_t) (rand() % (SIZE - from)) + from;
    sliced[i] = rrb_slice(rrb, from, to);
  }

  for (uint32_t i = 0; i < CATTED; i++) {
    const RRB *multicat = rrb_create(); // Originally empty
    uint32_t tot_cats = (uint32_t) rand() % TOT_CATTED;
    uint32_t *merged_in = GC_MALLOC_ATOMIC(sizeof(uint32_t) * tot_cats);
    for (uint32_t cat_num = 0; cat_num < tot_cats; cat_num++) {
      merged_in[cat_num] = (uint32_t) rand() % SLICED;
      multicat = rrb_concat(multicat, sliced[merged_in[cat_num]]);
    }
    
    // checking consistency here
    uint32_t pos = 0;
    uint32_t merged_pos = 0;
    while (pos < rrb_count(multicat)) {
      const RRB *merged = sliced[merged_in[merged_pos]];
      
      for (uint32_t merged_i = 0; merged_i < rrb_count(merged);
           merged_i++, pos++) {
        intptr_t expected = (intptr_t) rrb_nth(merged, merged_i);
        intptr_t actual = (intptr_t) rrb_nth(multicat, pos);
        if (expected != actual) {
          printf("On multicatted object #%u, at merged element %u:\n",
                 i, merged_pos);
          printf("  Expected val at pos %u (%u in merged) to be %ld, but was %ld\n",
                 pos, merged_i, expected, actual);
          printf("  Size of merged: %u, is at index %u\n", rrb_count(merged),
                 merged_in[merged_pos]);
          printf("Sliced lists:\n");
          fail = 1;
          return fail;
        }
      }
      merged_pos++;
    }
  }
  return fail;
}
Ejemplo n.º 2
0
int main() {
  GC_INIT();
  const RRB *rrb = rrb_create();

  for (uintptr_t i = 0; i < 33; i++) {
    rrb = rrb_push(rrb, (void *) i);
  }
  int file_size = rrb_to_dot_file(rrb, "foo.dot");
  switch (file_size) {
  case -1:
    puts("Had trouble either opening or closing \"foo.dot\".");
    return 1;
  case -2:
    puts("Had trouble writing to the file \"foo.dot\".");
    return 1;
  default:
    printf("The file \"foo.dot\" contains an RRB-tree in dot format "
           "(%d bytes)\n", file_size);
    if (RRB_BITS != 2) {
      puts("\n"
"(If you want to use the code for visualising RRB-trees, I'd recommend to use the\n"
" settings `CFLAGS='-Ofast' ./configure --with-branching=2` instead. It is much\n"
" easier to visualise/comprehend with 4 elements per trie node instead of 32.)");
    }
    return 0;
  }
}
Ejemplo n.º 3
0
int main() {
  GC_INIT();
  randomize_rand();

  int fail = 0;
  intptr_t *list = GC_MALLOC_ATOMIC(sizeof(intptr_t) * SIZE);
  for (uint32_t i = 0; i < SIZE; i++) {
    list[i] = (intptr_t) rand();
  }
  const RRB *rrb = rrb_create();
  for (uint32_t i = 0; i < SIZE; i++) {
    rrb = rrb_push(rrb, (void *) list[i]);
    intptr_t val = (intptr_t) rrb_peek(rrb);
    if (val != list[i]) {
      printf("Expected val at pos %d to be %ld, was %ld.\n", i, list[i], val);
      fail = 1;
    }
  }
  return fail;
}
Ejemplo n.º 4
0
int main(int argc, char *argv[]) {
    GC_INIT();
    // CLI argument parsing
    if (argc != 4) {
        fprintf(stderr, "Expected 3 arguments, got %d\nExiting...\n", argc - 1);
        exit(1);
    }
    else {
        char *end;
        uint32_t thread_count = (uint32_t) strtol(argv[1], &end, 10);
        if (*end) {
            fprintf(stderr, "Error, expects first argument to be a power of two,"
                    " was '%s'.\n", argv[1]);
            exit(1);
        }
        if (!(thread_count && !(thread_count & (thread_count - 1)))) {
            fprintf(stderr, "Error, first argument must be a power of two, not %d.\n",
                    thread_count);
            exit(1);
        }
        fprintf(stderr, "Looking for '%s' in file %s using %d threads...\n",
                argv[2], argv[3], thread_count);

        char *search_term = argv[2];

        FILE *fp;
        long file_size;
        char *buffer;
        fp = fopen(argv[3], "rb");
        if (!fp) {
            perror(argv[1]);
            exit(1);
        }
        fseek(fp, 0, SEEK_END);
        file_size = ftell(fp);
        rewind(fp);

        buffer = malloc(file_size + 1);
        if (!buffer) {
            fclose(fp);
            fprintf(stderr, "Cannot allocate buffer for file (probably too large).\n");
            exit(1);
        }
        buffer[file_size] = 0;

        if (1 != fread(buffer, file_size, 1, fp)) {
            fclose(fp);
            free(buffer);
            fprintf(stderr, "Entire read failed.\n");
            exit(1);
        }
        else {
            fclose(fp);
        }

        // Find all lines
        pthread_t *tid = malloc(thread_count * sizeof(pthread_t));
        LineSplitArgs *lsa = malloc(thread_count * sizeof(LineSplitArgs));
        const RRB **intervals = GC_MALLOC(thread_count * sizeof(RRB *));

        for (uint32_t i = 0; i < thread_count; i++) {
            LineSplitArgs arguments =
            {   .buffer = buffer, .file_size = (uint32_t) file_size,
                .own_tid = i, .thread_count = thread_count,
                .intervals = intervals
            };
            lsa[i] = arguments;
        }

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_create(&tid[i], NULL, &split_to_lines, (void *) &lsa[i]);
        }

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_join(tid[i], NULL);
        }
        free(lsa);

        // Concatenate work

        ConcatArgs *ca = malloc(thread_count * sizeof(ConcatArgs));
        pthread_barrier_t *barriers = malloc(thread_count * sizeof(pthread_barrier_t));
        uint32_t *max_concat_size = calloc(sizeof(uint32_t), thread_count);

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_barrier_init(&barriers[i], NULL, 2);
            ConcatArgs args = {.own_tid = i, .thread_count = thread_count,
                               .intervals = intervals, .barriers = barriers,
                               .max_concat_size = max_concat_size
                              };
            ca[i] = args;
        }

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_create(&tid[i], NULL, &concatenate_rrbs, (void *) &ca[i]);
        }

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_join(tid[i], NULL);
        }

        const RRB *lines = intervals[0];
        // Found all lines, now onto searching in each list

        fprintf(stderr, "%d newlines\n", rrb_count(intervals[0]));

        FilterArgs *fa = malloc(thread_count * sizeof(FilterArgs));
        // Reuse intervals array

        for (uint32_t i = 0; i < thread_count; i++) {
            FilterArgs arguments =
            {   .buffer = buffer, .search_term = search_term,
                .lines = lines, .intervals = intervals,
                .own_tid = i, .thread_count = thread_count
            };
            fa[i] = arguments;
        }

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_create(&tid[i], NULL, &filter_by_term, (void *) &fa[i]);
        }

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_join(tid[i], NULL);
        }

        // find total memory usage
        uint32_t total_mem = rrb_memory_usage(intervals, thread_count);

        // Concatenate work
        // Reuse concat args and barriers

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_barrier_init(&barriers[i], NULL, 2);
            ConcatArgs args = {.own_tid = i, .thread_count = thread_count,
                               .intervals = intervals, .barriers = barriers,
                               .max_concat_size = max_concat_size
                              };
            ca[i] = args;
        }

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_create(&tid[i], NULL, &concatenate_rrbs, (void *) &ca[i]);
        }

        for (uint32_t i = 0; i < thread_count; i++) {
            pthread_join(tid[i], NULL);
        }

        uint32_t maxcat = 0;
        for (uint32_t i = 0; i < thread_count; i++) {
            maxcat = MAX(maxcat, max_concat_size[i]);
        }

        fprintf(stderr, "%d hits\n", rrb_count(intervals[0]));

        printf("%d %d \"%s\"\n", total_mem, maxcat, search_term);

        free(barriers);
        free(buffer);
        free(max_concat_size);
        exit(0);
    }

}

static void* split_to_lines(void *void_input) {
    LineSplitArgs *lsa = (LineSplitArgs *) void_input;
    const char *buffer = lsa->buffer;
    const uint32_t own_tid = lsa->own_tid;
    const uint32_t file_size = lsa->file_size;
    const uint32_t thread_count = lsa->thread_count;
    const RRB **intervals = lsa->intervals;

    // calculate the interval to compute for
    uint32_t partition_size = file_size / thread_count;
    uint32_t from = partition_size * own_tid;
    uint32_t to = partition_size * (own_tid + 1);
    if (own_tid + 1 == thread_count) {
        to = file_size;
    }

    // find the lines
    const RRB *lines = rrb_create();

    // rewind to start of line
    uint32_t line_start = from;
    while (0 < line_start && lsa->buffer[line_start] != '\n') {
        line_start--;
    }
    // find and collect lines
    for (uint32_t i = from; i < to; i++) {
        if (buffer[i] == '\n') {
            Interval interval = {.from = line_start, .to = i};
            lines = rrb_push(lines, (void *) interval_to_uint64_t(interval));
            line_start = i + 1;
        }
    }