static inline void store_string_location (MonoProfiler *prof, const gchar *string, guint32 hash, size_t len) { StringLocation *location = (StringLocation *)g_hash_table_lookup (prof->string_locations_hash, &hash); SavedString *saved; SavedStringFindInfo info; guint32 *hashptr; if (location) return; info.hash = hash; info.len = len; /* Expensive but unavoidable... */ saved = (SavedString*)g_hash_table_find (prof->saved_strings_hash, saved_strings_find_func, &info); hashptr = (guint32*)g_malloc (sizeof (guint32)); *hashptr = hash; location = (StringLocation*)g_malloc0 (sizeof (location)); g_hash_table_insert (prof->string_locations_hash, hashptr, location); if (!saved) return; g_hash_table_remove (prof->saved_strings_hash, saved->string); location->hint = build_hint (saved); }
/* * bc_close() is not thread safe, should stop other threads before call it. * */ void bc_close(Bitcask *bc) { int i=0; pthread_mutex_lock(&bc->write_lock); bc_flush(bc, 0, 0); if (NULL != bc->curr_tree) { uint32_t curr; ht_get_hash(bc->curr_tree, "@", &curr); if (curr > 0) { char name[255], buf[255]; sprintf(name, HINT_FILE, bc->curr); sprintf(buf, "%s/%s", mgr_alloc(bc->mgr, name), name); build_hint(bc->curr_tree, buf); }else{ ht_destroy(bc->curr_tree); } bc->curr_tree = NULL; } bc->curr = 0; ht_destroy(bc->tree); mgr_destroy(bc->mgr); free(bc->write_buffer); free(bc); }
void* build_thread(void *param) { struct build_thread_args *args = (struct build_thread_args*) param; build_hint(args->tree, args->path); free(args->path); free(param); return NULL; }
/* * bc_close() is not thread safe, should stop other threads before call it. * */ void bc_close(Bitcask *bc) { char datapath[255], hintpath[255]; if (bc->optimize_flag > 0) { bc->optimize_flag = 2; while (bc->optimize_flag > 0) { sleep(1); } } pthread_mutex_lock(&bc->write_lock); bc_flush(bc, 0, 0); if (NULL != bc->curr_tree) { if (bc->curr_bytes > 0) { build_hint(bc->curr_tree, new_path(hintpath, bc->mgr, HINT_FILE, bc->curr)); } else { ht_destroy(bc->curr_tree); } bc->curr_tree = NULL; } if (bc->curr_bytes == 0) bc->curr --; if (bc->curr - bc->last_snapshot >= SAVE_HTREE_LIMIT) { if (ht_save(bc->tree, new_path(datapath, bc->mgr, HTREE_FILE, bc->curr)) == 0) { mgr_unlink(gen_path(datapath, mgr_base(bc->mgr), HTREE_FILE, bc->last_snapshot)); } else { fprintf(stderr, "save HTree to %s failed\n", datapath); } } ht_destroy(bc->tree); mgr_destroy(bc->mgr); free(bc->write_buffer); free(bc); }
void scanDataFile(HTree* tree, int bucket, const char* path, const char* hintpath) { MFile *f = open_mfile(path); if (f == NULL) return; fprintf(stderr, "scan datafile %s\n", path); HTree *cur_tree = ht_new(0,0); char *p = f->addr, *end = f->addr + f->size; int broken = 0; while (p < end) { DataRecord *r = decode_record(p, end-p, false); if (r != NULL) { uint32_t pos = p - f->addr; p += record_length(r); r = decompress_record(r); uint16_t hash = gen_hash(r->value, r->vsz); if (r->version > 0){ ht_add2(tree, r->key, r->ksz, pos | bucket, hash, r->version); }else{ ht_remove2(tree, r->key, r->ksz); } ht_add2(cur_tree, r->key, r->ksz, pos | bucket, hash, r->version); free_record(r); } else { broken ++; if (broken > 40960) { // 10M fprintf(stderr, "unexpected broken data in %s at %ld\n", path, p - f->addr - broken * PADDING); break; } p += PADDING; } } close_mfile(f); build_hint(cur_tree, hintpath); }
void bc_optimize(Bitcask *bc, int limit) { int i; for (i=0; i < bc->curr; i++) { char data[20], hint[20], datapath[255], hintpath[255]; sprintf(data, DATA_FILE, i); sprintf(hint, HINT_FILE, i); sprintf(datapath, "%s/%s", mgr_alloc(bc->mgr, data), data); sprintf(hintpath, "%s/%s", mgr_alloc(bc->mgr, hint), hint); uint32_t recoverd = 0; HTree *cur_tree = optimizeDataFile(bc->tree, i, datapath, hintpath, limit, &recoverd); if (NULL == cur_tree) continue; pthread_mutex_lock(&bc->buffer_lock); bc->bytes -= recoverd; pthread_mutex_unlock(&bc->buffer_lock); pthread_mutex_lock(&bc->write_lock); ht_visit(cur_tree, update_items, bc->tree); pthread_mutex_unlock(&bc->write_lock); build_hint(cur_tree, hintpath); } }