Hash *h_new(hash_ft hash, eq_ft eq, free_ft free_key, free_ft free_value) { Hash *self = h_new_str(free_key, free_value); self->lookup_i = &h_lookup; self->eq_i = eq; self->hash_i = hash; return self; }
Hash *h_new_int(free_ft free_value) { Hash *self = h_new_str(NULL, free_value); self->lookup_i = &h_lookup_ptr; self->eq_i = NULL; self->hash_i = NULL; return self; }
Store *open_ram_store() { Store *new_store = store_new(); new_store->dir.ht = h_new_str(NULL, rf_close); new_store->touch = &ram_touch; new_store->exists = &ram_exists; new_store->remove = &ram_remove; new_store->rename = &ram_rename; new_store->count = &ram_count; new_store->clear = &ram_clear; new_store->clear_all = &ram_clear_all; new_store->clear_locks = &ram_clear_locks; new_store->length = &ram_length; new_store->each = &ram_each; new_store->new_output = &ram_new_output; new_store->open_input = &ram_open_input; new_store->open_lock_i = &ram_open_lock_i; new_store->close_lock_i = &ram_close_lock_i; new_store->close_i = &ram_close_i; return new_store; }
Store *open_fs_store(const char *pathname) { Store *store = NULL; mutex_lock(&stores_mutex); if (!stores) { stores = h_new_str(NULL, (free_ft)fs_destroy); register_for_cleanup(stores, (free_ft)h_destroy); } store = (Store *)h_get(stores, pathname); if (store) { mutex_lock(&store->mutex); store->ref_cnt++; mutex_unlock(&store->mutex); } else { store = fs_store_new(pathname); h_set(stores, store->dir.path, store); } mutex_unlock(&stores_mutex); return store; }
Store *open_cmpd_store(Store *store, const char *name) { int count, i; off_t offset; char *fname; FileEntry *entry = NULL; Store *new_store = NULL; CompoundStore *volatile cmpd = NULL; InStream *volatile is = NULL; TRY cmpd = ALLOC_AND_ZERO(CompoundStore); cmpd->store = store; cmpd->name = name; cmpd->entries = h_new_str(&free, &free); is = cmpd->stream = store->open_input(store, cmpd->name); /* read the directory and init files */ count = is_read_vint(is); entry = NULL; for (i = 0; i < count; i++) { offset = (off_t)is_read_i64(is); fname = is_read_string(is); if (entry != NULL) { /* set length of the previous entry */ entry->length = offset - entry->offset; } entry = ALLOC(FileEntry); entry->offset = offset; h_set(cmpd->entries, fname, entry); } XCATCHALL if (is) is_close(is); if (cmpd->entries) h_destroy(cmpd->entries); free(cmpd); XENDTRY /* set the length of the final entry */ if (entry != NULL) { entry->length = is_length(is) - entry->offset; } new_store = store_new(); new_store->dir.cmpd = cmpd; new_store->touch = &cmpd_touch; new_store->exists = &cmpd_exists; new_store->remove = &cmpd_remove; new_store->rename = &cmpd_rename; new_store->count = &cmpd_count; new_store->clear = &cmpd_clear; new_store->length = &cmpd_length; new_store->each = &cmpd_each; new_store->close_i = &cmpd_close_i; new_store->new_output = &cmpd_new_output; new_store->open_input = &cmpd_open_input; new_store->open_lock_i = &cmpd_open_lock_i; new_store->close_lock_i = &cmpd_close_lock_i; return new_store; }
void symbol_init() { symbol_table = h_new_str(free, NULL); register_for_cleanup(symbol_table, (free_ft)&h_destroy); }