int main() { int arr[] = {3, 6, 9, 2, 11, 1, 4}, i; skiplist list; skiplist_init(&list); printf("Insert:--------------------\n"); for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) { skiplist_insert(&list, arr[i], arr[i]); } skiplist_dump(&list); printf("Search:--------------------\n"); int keys[] = {3, 4, 7, 10, 111}; for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) { snode *x = skiplist_search(&list, keys[i]); if (x) { printf("key = %d, value = %d\n", keys[i], x->value); } else { printf("key = %d, not fuound\n", keys[i]); } } printf("Search:--------------------\n"); skiplist_delete(&list, 3); skiplist_delete(&list, 9); skiplist_dump(&list); return 0; }
int main(int argc, char *argv[]) { int i, n, seed, key; SkipList skiplist; Cell *node; if (argc < 2 || argc > 3) { printf("Usage: %s <n> [seed]\n", argv[0]); exit(1); } n = atoi(argv[1]); if (argc == 3) seed = atoi(argv[2]); else seed = time(NULL); srand(seed); skiplist_init(&skiplist); printf("[+] dump key: \n"); printf(" (i , key)\n"); for (i = 0; i < n; i++) { key = rand() % SKIPLIST_MAX_KEY; printf(" (%-4d , %4d)\n", i, key); skiplist_insert(&skiplist, key); skiplist_vertical_print(&skiplist); } skiplist_vertical_print(&skiplist); /*node = skiplist_search(&skiplist, 15);*/ if (NULL) printf("[+] key %d found.\n", node->key); else printf("[-] Key 15 not found.\n"); return 0; }
int main(int argc, char** argv) { if (argc != 2) { printf("Usage: %s HPROF_FILE\n", argv[0]); exit(1); } FILE* hprof_fp = fopen(argv[1], "r"); die(hprof_fp == NULL, "File error"); hprof_header* header; char version[19]; u4 ident_size; int count = fread(version, sizeof(version), 1, hprof_fp); die(count != 1, "Unable to read hprof header"); count = fread(&ident_size, sizeof(u4), 1, hprof_fp); die(count != 1, "Unable to read hprof header"); int success = fseek(hprof_fp, sizeof(u8), SEEK_CUR); die(success != 0, "Could not seek forward in the file"); printf("Header: version=%s identsize=%ju\n", version, (uintmax_t) be32_to_native(ident_size)); // For now just reuse it hprof_record_header* record_header = calloc(1, sizeof(hprof_record_header)); hprof_heap_summary* heap_summary = calloc(1, sizeof(hprof_heap_summary)); // The string table is a skip list that should give us // O(n log n) insertion and O(log n) lookup, This is not as // good as a malloc'd array, but does not suffer from the // out of order issues that the string id's present us with skiplist_t *string_table = malloc(sizeof(skiplist_t)); skiplist_init(string_table); skiplist_set_cmp_fn(string_table, stringtable_cmp); skiplist_set_search_fn(string_table, stringtable_search); skiplist_set_destroy_fn(string_table, __destroy); skiplist_t *class_table = malloc(sizeof(skiplist_t)); skiplist_init(class_table); skiplist_set_cmp_fn(class_table, classtable_cmp); skiplist_set_search_fn(class_table, classtable_search); skiplist_set_destroy_fn(class_table, __destroy); while(1) { if (feof(hprof_fp)) { break; } //read_record_header(record_header, hprof_fp); funpack(hprof_fp, "bd>d>", &record_header->tag, &record_header->profiling_ms, &record_header->remaining_bytes); //printf("Tag=%ju\n", (uintmax_t) record_header->tag); switch(record_header->tag) { case UTF8: //printf("UTF8\n"); ; hprof_utf8 *utf8 = malloc(sizeof(hprof_utf8)); funpack(hprof_fp, "q>", &utf8->id); //fread(&utf8->id, sizeof(id), 1, hprof_fp); long bytes_remain = record_header->remaining_bytes - sizeof(id); // Awesome, hprof strings are utf8, this is good ! the only established // C type is char and its a byte wide :D utf8->num_chars = bytes_remain / sizeof(char); utf8->hprof_offset = ftell(hprof_fp); skiplist_insert(string_table, utf8); fseek(hprof_fp, bytes_remain, SEEK_CUR); break; case LOAD_CLASS: //printf("LOAD_CLASS\n"); ; hprof_load_class *class = malloc(sizeof(hprof_load_class)); fread(&class->serial_number, sizeof(u4), 1, hprof_fp); class->serial_number = be32_to_native(class->serial_number); fseek(hprof_fp, sizeof(id) + sizeof(u4), SEEK_CUR); fread(&class->name_id, sizeof(id), 1, hprof_fp); class->name_id = be64_to_native(class->name_id); skiplist_insert(class_table, class); //fseek(hprof_fp, be32_to_native(record_header->remaining_bytes), SEEK_CUR); break; case UNLOAD_CLASS: //printf("UNLOAD_CLASS\n"); fseek(hprof_fp, record_header->remaining_bytes, SEEK_CUR); break; case FRAME: //printf("FRAME\n"); // This is bad !!! If it is slow think about doing two complete passes to // make all the I/O as sequential as possible // This implementation is going to jump all over the hprof file ; long curr_pos = ftell(hprof_fp); id ids[4]; fread(&ids, sizeof(id), 4, hprof_fp); u4 class_serial_num; fread(&class_serial_num, sizeof(u4), 1, hprof_fp); class_serial_num = be32_to_native(class_serial_num); hprof_load_class *clazz = (hprof_load_class*) skiplist_search(class_table, &class_serial_num); i4 line_num; fread(&line_num, sizeof(i4), 1, hprof_fp); line_num = be32_to_native(line_num); char *method_name = read_string(be64_to_native(ids[1]), string_table, hprof_fp); char *method_sig = read_string(be64_to_native(ids[2]), string_table, hprof_fp); char *source_file = read_string(be64_to_native(ids[3]), string_table, hprof_fp); char *class_name = "<UNKNOWN_CLASS>"; if(clazz != NULL) { class_name = read_string(clazz->name_id, string_table, hprof_fp); } // SOMETIMES NULL //printf("%s\n", read_string(ids[3], string_table, hprof_fp)); class_name = (class_name == NULL) ? "<UNKNOWN_CLASS>" : class_name; method_name = (method_name == NULL) ? "<UNKNOWN_METHOD>" : method_name; method_sig = (method_sig == NULL) ? "<UNKNOWN_METHOD_SIG>" : method_sig; source_file = (source_file == NULL) ? "<UNKNOWN_SOURCE>" : source_file; switch(line_num) { case -1: printf("Class %s\n \tMethod=%s\n\tSource=%s @ <UNKNOWN>\n", class_name, method_name, source_file); break; case -2: printf("Class %s\n \tMethod=%s\n\tSource=%s @ <COMPILED_METHOD>\n", class_name, method_name, source_file); break; case -3: printf("Class %s\n \tMethod=%s\n\tSource=%s @ <NATIVE_METHOD>\n", class_name, method_name, source_file); break; default: printf("Class %s\n \tMethod=%s\n\tSource=%s @ %ji\n", class_name, method_name, source_file, (intmax_t) line_num); break; } break; case TRACE: //printf("TRACE\n"); ; hprof_stacktrace* stacktrace = calloc(1, sizeof(hprof_stacktrace)); fread(&stacktrace->serial_number, sizeof(u4), 1, hprof_fp); fread(&stacktrace->thread_number, sizeof(u4), 1, hprof_fp); fread(&stacktrace->number_frames, sizeof(u4), 1, hprof_fp); printf("StackTrace serial_num=%ju " "thread_num=%ju num_frames=%ju\n", (uintmax_t) be64_to_native(stacktrace->serial_number), (uintmax_t) be64_to_native(stacktrace->thread_number), (uintmax_t) be64_to_native(stacktrace->number_frames)); for (int i=0; i < be32_to_native(stacktrace->number_frames); i++) { id frame_id; fread(&frame_id, sizeof(id), 1, hprof_fp); printf("FrameID=%ju\n", (uintmax_t) be64_to_native(frame_id)); } free(stacktrace); break; case ALLOC_SITES: //printf("ALLOC_SITES\n"); fseek(hprof_fp, be32_to_native(record_header->remaining_bytes), SEEK_CUR); break; case HEAP_SUMMARY: //printf("HEAP SUMMARY\n"); fread(&heap_summary->live_bytes, sizeof(u4), 1, hprof_fp); fread(&heap_summary->live_instances, sizeof(u4), 1, hprof_fp); fread(&heap_summary->allocated_bytes, sizeof(u8), 1, hprof_fp); fread(&heap_summary->allocated_instances, sizeof(u8), 1, hprof_fp); printf("Heap summary:\n\tReachable bytes=%ju\n\t" "Reachable instances=%ju\n\t" "Allocated bytes=%ju\n\t" "Allocated instances=%ju\n", (uintmax_t) be32_to_native(heap_summary->live_bytes), (uintmax_t) be32_to_native(heap_summary->live_instances), (uintmax_t) be64_to_native(heap_summary->allocated_bytes), (uintmax_t) be64_to_native(heap_summary->allocated_instances)); break; case START_THREAD: //printf("START_THREAD\n"); fseek(hprof_fp, be32_to_native(record_header->remaining_bytes), SEEK_CUR); break; case END_THREAD: //printf("END_THREAD\n"); fseek(hprof_fp, be32_to_native(record_header->remaining_bytes), SEEK_CUR); break; case HEAP_DUMP: //printf("HEAP_DUMP\n"); fseek(hprof_fp, be32_to_native(record_header->remaining_bytes), SEEK_CUR); break; case CPU_SAMPLES: //printf("CPU_SAMPLES\n"); fseek(hprof_fp, be32_to_native(record_header->remaining_bytes), SEEK_CUR); break; case CONTROL_SETTINGS: //printf("CONTROL_SETTINGS\n"); fseek(hprof_fp, be32_to_native(record_header->remaining_bytes), SEEK_CUR); break; case HEAP_DUMP_SEGMENT: //printf("HEAP_DUMP_SEGMENT\n"); fseek(hprof_fp, be32_to_native(record_header->remaining_bytes), SEEK_CUR); break; case HEAP_DUMP_END: //printf("HEAP_DUMP_END\n"); fseek(hprof_fp, be32_to_native(record_header->remaining_bytes), SEEK_CUR); exit(1); break; default: printf("BANG\n"); exit(1); break; } //printf("%lu\n", ftell(hprof_fp)); } skiplist_destroy(string_table); free(string_table); skiplist_destroy(class_table); free(class_table); fclose(hprof_fp); return 0; }