void extkey_cache_destroy(extkey_cache_t *cache) { ham_size_t i; extkey_t *e, *n; ham_db_t *db=extkey_cache_get_db(cache); ham_env_t *env = db_get_env(db); /* * make sure that all entries are empty */ for (i=0; i<extkey_cache_get_bucketsize(cache); i++) { e=extkey_cache_get_bucket(cache, i); while (e) { #if HAM_DEBUG /* * make sure that the extkey-cache is empty - only for in-memory * databases and DEBUG builds. */ if (env_get_rt_flags(env)&HAM_IN_MEMORY_DB) ham_assert(!"extkey-cache is not empty!", (0)); #endif n=extkey_get_next(e); allocator_free(env_get_allocator(env), e); e=n; } } allocator_free(env_get_allocator(env), cache); }
ham_status_t blob_duplicate_get(ham_env_t *env, ham_offset_t table_id, ham_size_t position, dupe_entry_t *entry) { ham_status_t st; dupe_table_t *table; ham_page_t *page=0; st = __get_duplicate_table(&table, &page, env, table_id); ham_assert(st ? table == NULL : 1, (0)); ham_assert(st ? page == NULL : 1, (0)); if (!table) return st ? st : HAM_INTERNAL_ERROR; if (position>=dupe_table_get_count(table)) { if (!(env_get_rt_flags(env)&HAM_IN_MEMORY_DB)) if (!page) allocator_free(env_get_allocator(env), table); return HAM_KEY_NOT_FOUND; } memcpy(entry, dupe_table_get_entry(table, position), sizeof(*entry)); if (!(env_get_rt_flags(env)&HAM_IN_MEMORY_DB)) { if (!page) allocator_free(env_get_allocator(env), table); } return (0); }
/* * when the last hit leaf node is split or shrunk, blow it away for all operations! * * Also blow away a page when a transaction aborts which has modified this page. We'd rather * reconstruct our critical statistics then carry the wrong bounds, etc. around. * * This is done to prevent the hinter from hinting/pointing at an (by now) * INVALID btree node later on! */ void stats_page_is_nuked(ham_db_t *db, struct ham_page_t *page, ham_bool_t split) { ham_runtime_statistics_dbdata_t *dbdata = db_get_db_perf_data(db); ham_env_t *env = db_get_env(db); int i; for (i = 0; i <= 2; i++) { ham_runtime_statistics_opdbdata_t *opstats = db_get_op_perf_data(db, i); ham_assert(i == HAM_OPERATION_STATS_FIND || i == HAM_OPERATION_STATS_INSERT || i == HAM_OPERATION_STATS_ERASE, (0)); if (opstats->btree_last_page_addr == page_get_self(page)) { opstats->btree_last_page_addr = 0; opstats->btree_last_page_sq_hits = 0; } } if (dbdata->lower_bound_page_address == page_get_self(page)) { if (dbdata->lower_bound.data) { ham_assert(env_get_allocator(env) != 0, (0)); allocator_free(env_get_allocator(env), dbdata->lower_bound.data); } memset(&dbdata->lower_bound, 0, sizeof(dbdata->lower_bound)); dbdata->lower_bound_index = 0; dbdata->lower_bound_page_address = 0; dbdata->lower_bound_set = HAM_FALSE; } if (dbdata->upper_bound_page_address == page_get_self(page)) { if (dbdata->upper_bound.data) { ham_assert(env_get_allocator(env) != 0, (0)); allocator_free(env_get_allocator(env), dbdata->upper_bound.data); } memset(&dbdata->upper_bound, 0, sizeof(dbdata->upper_bound)); dbdata->upper_bound_index = 0; dbdata->upper_bound_page_address = 0; dbdata->upper_bound_set = HAM_FALSE; } }
ham_status_t extkey_cache_remove(extkey_cache_t *cache, ham_offset_t blobid) { ham_db_t *db=extkey_cache_get_db(cache); ham_env_t *env = db_get_env(db); ham_size_t h=my_calc_hash(cache, blobid); extkey_t *e, *prev=0; e=extkey_cache_get_bucket(cache, h); while (e) { if (extkey_get_blobid(e)==blobid) break; prev=e; e=extkey_get_next(e); } if (!e) return (HAM_KEY_NOT_FOUND); if (prev) extkey_set_next(prev, extkey_get_next(e)); else extkey_cache_set_bucket(cache, h, extkey_get_next(e)); extkey_cache_set_usedsize(cache, extkey_cache_get_usedsize(cache)-extkey_get_size(e)); allocator_free(env_get_allocator(env), e); return (0); }
static void _ensure_allocator_traced_free_copes_with_null_parent_allocator( void ) { int x = 0; allocator_traced_t alloc; allocator_traced_init( &alloc, 0, stdout ); allocator_free( &x, allocator_traced_get( &alloc ) ); }
void stats_trash_dbdata(ham_db_t *db, ham_runtime_statistics_dbdata_t *dbdata) { ham_env_t *env = db_get_env(db); /* trash the upper/lower bound keys, when set: */ if (dbdata->upper_bound.data) { ham_assert(env_get_allocator(env) != 0, (0)); allocator_free(env_get_allocator(env), dbdata->upper_bound.data); } if (dbdata->lower_bound.data) { ham_assert(env_get_allocator(env) != 0, (0)); allocator_free(env_get_allocator(env), dbdata->lower_bound.data); } memset(dbdata, 0, sizeof(*dbdata)); }
//************************************************************************// //* free memory allocated from the av heap. //************************************************************************// void av_heap_free(void* vaddr) { int block_idx; unsigned char* paddr; int offset; if(heap_ctx == NULL) { loge("av heap not initialized yet."); return; } pthread_mutex_lock(&heap_ctx->mutex); block_idx = av_heap_find_block_by_vaddr(heap_ctx, vaddr); if(block_idx < 0) { loge("can not find a block of specific virtual address %x.", vaddr); pthread_mutex_unlock(&heap_ctx->mutex); return; } paddr = (unsigned char*)heap_ctx->block_info[block_idx].paddr; offset = (int)(paddr - (heap_ctx->env_info.phymem_start & 0x3fffffff)); munmap(heap_ctx->block_info[block_idx].vaddr, heap_ctx->block_info[block_idx].size); allocator_free(heap_ctx->allocator, offset); memset(&heap_ctx->block_info[block_idx], 0, sizeof(block_info_t)); pthread_mutex_unlock(&heap_ctx->mutex); return; }
/* user logout, client timeout or something error, we need to * close the connection and release resource */ void close_connection(struct conn_server *server, struct connection *conn) { /* remove from fd-conn hash map */ close(conn->sfd); struct fd_entry *fd_entry; HASH_FIND_INT(server->fd_conn_map, &conn->sfd, fd_entry); if (fd_entry) { HASH_DEL(server->fd_conn_map, fd_entry); free(fd_entry); } /* remove from uin-conn hash map */ struct uin_entry *uin_entry; HASH_FIND_INT(server->uin_conn_map, &conn->uin, uin_entry); if (uin_entry) { HASH_DEL(server->uin_conn_map, uin_entry); free(uin_entry); } /* remove from timer */ timer_del(conn); conn_destroy(server, conn); /* free the conn struct */ allocator_free(&server->conn_allocator, conn); }
static lua_matrix_t * create_matrix(int lig, int col) { lua_matrix_def_t * md = 0; lua_matrix_t *m = 0; int size; if (lig <= 0 || col <= 0) { return 0; } size = sizeof(lua_matrix_def_t) + sizeof(float)*(lig*col) - sizeof(md->v); md = allocator_alloc(matrixdef_allocator, size); if (md) { md->refcount = 1; md->l = lig; md->c = col; } m = allocator_alloc(matrixref_allocator, sizeof(*m)); if (!m) { allocator_free(matrixdef_allocator, md); } else { m->md = md; m->li = 0; } return m; }
ham_status_t extkey_cache_purge(extkey_cache_t *cache) { ham_size_t i; extkey_t *e, *n; ham_env_t *env; ham_assert(extkey_cache_get_db(cache), (0)); env = db_get_env(extkey_cache_get_db(cache)); /* * delete all entries which are "too old" (were not * used in the last EXTKEY_MAX_AGE transactions) */ for (i=0; i<extkey_cache_get_bucketsize(cache); i++) { extkey_t *p=0; e=extkey_cache_get_bucket(cache, i); while (e) { n=extkey_get_next(e); if (env_get_txn_id(env)-extkey_get_txn_id(e)>EXTKEY_MAX_AGE) { /* deleted the head element of the list? */ if (!p) extkey_cache_set_bucket(cache, i, n); else extkey_set_next(p, n); allocator_free(env_get_allocator(env), e); } else p=e; e=n; } } return (0); }
static ham_status_t _remote_fun_txn_abort(ham_env_t *env, ham_txn_t *txn, ham_u32_t flags) { ham_status_t st; proto_wrapper_t *request, *reply; request=proto_init_txn_abort_request(txn_get_remote_handle(txn), flags); st=_perform_request(env, env_get_curl(env), request, &reply); proto_delete(request); if (st) { if (reply) proto_delete(reply); return (st); } ham_assert(reply!=0, ("")); ham_assert(proto_has_txn_abort_reply(reply), ("")); st=proto_txn_abort_reply_get_status(reply); if (st==0) { memset(txn, 0, sizeof(*txn)); allocator_free(env_get_allocator(env), txn); /* remove the link between env and txn */ env_set_txn(env, 0); } proto_delete(reply); return (st); }
static void _ensure_allocator_traced_alloc_returns_valid_memory_for_nonempty_allocation( void ) { void * mem; allocator_traced_t alloc; allocator_traced_init_stdout( &alloc, allocator_default( ) ); mem = allocator_alloc( 1024, allocator_traced_get( &alloc ) ); TEST_REQUIRE( mem != 0 ); allocator_free( mem, allocator_traced_get( &alloc ) ); }
void cmd_logout(struct conn_server *server, struct connection *conn, struct list_packet *packet) { allocator_free(&server->packet_allocator, packet); /* send status change command to status server */ send_offline_to_status(server, get_uin(packet)); close_connection(server, conn); }
int main(int argc, char* argv[]) { int i = 0; int n = 100; Allocator* allocator = allocator_normal_create(); for(i = 0; i < n; i++) { char* ptr = allocator_alloc(allocator, i); ptr = allocator_realloc(allocator, ptr, i+4); allocator_free(allocator, ptr); ptr = allocator_calloc(allocator, i+4, 4); allocator_free(allocator, ptr); } allocator_destroy(allocator); return 0; }
/* this function ONLY removes the packets, does not remove the timer */ void conn_destroy(struct conn_server *server, struct connection *conn) { /* remove recv packets */ struct list_head *head = &conn->recv_packet_list; struct list_packet *p; while (!list_empty(head)) { p = list_first_entry(head, struct list_packet, list); list_del(&p->list); allocator_free(&server->packet_allocator, p); } /* remove send packets */ head = &conn->send_packet_list; while (!list_empty(head)) { p = list_first_entry(head, struct list_packet, list); list_del(&p->list); allocator_free(&server->packet_allocator, p); } }
/** @fn DataBuffer_t::~DataBuffer_t() */ DataBuffer_t::~DataBuffer_t() { mutex_deinit(&mBuffLock); #ifndef DVP_USE_ION FREE_IF_PRESENT( pData ) #else allocator_free(pAllocator, ALLOCATOR_MEMORY_TYPE_TILED_1D_UNCACHED, 1, &pData, handles); allocator_deinit(&pAllocator); #endif // DVP_USE_ION }
//*************************************************************************// //* allocate memory from the av heap. //*************************************************************************// void* av_heap_alloc(int size) { int offset; int block_idx; unsigned int paddr; if(size <= 0) { loge("request memory of invalid size %d.", size); return NULL; } if(heap_ctx == NULL) { loge("av heap not initialized yet, return fail."); return NULL; } pthread_mutex_lock(&heap_ctx->mutex); offset = allocator_alloc(heap_ctx->allocator, size); if(offset < 0) { loge("av heap out of memory."); pthread_mutex_unlock(&heap_ctx->mutex); return NULL; } paddr = offset + heap_ctx->env_info.phymem_start; block_idx = av_heap_get_a_free_block(heap_ctx); if(block_idx < 0) { loge("av heap can not get a free block, return fail."); allocator_free(heap_ctx->allocator, offset); pthread_mutex_unlock(&heap_ctx->mutex); return NULL; } heap_ctx->block_info[block_idx].vaddr = (void*)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, heap_ctx->fd, paddr); heap_ctx->block_info[block_idx].paddr = (void*)(paddr & 0x3fffffff); heap_ctx->block_info[block_idx].size = size; heap_ctx->block_info[block_idx].is_used = 1; pthread_mutex_unlock(&heap_ctx->mutex); printf("av heap alloc\n"); return heap_ctx->block_info[block_idx].vaddr; }
/* other kind of packet, check clienti's login type, * if login ok, send the packet to client */ void srv_other_packet(struct conn_server *server, struct list_packet *packet) { uint32_t uin = get_uin(packet); struct connection *conn = get_conn_by_uin(server, uin); /* need to check login status */ if (!conn || conn->type != LOGIN_OK_CONNECTION) { allocator_free(&server->packet_allocator, packet); return; } list_add_tail(&packet->list, &conn->send_packet_list); wait_for_write(server->efd, conn->sfd); }
/* client login successful, we mark the conn as login_ok, * and send the packet to client */ void srv_login_ok(struct conn_server *server, struct list_packet *packet) { uint32_t uin = get_uin(packet); struct connection *conn = get_conn_by_uin(server, uin); if (!conn) { allocator_free(&server->packet_allocator, packet); return; } conn->type = LOGIN_OK_CONNECTION; list_add_tail(&packet->list, &conn->send_packet_list); wait_for_write(server->efd, conn->sfd); }
static size_t __writefunc(void *buffer, size_t size, size_t nmemb, void *ptr) { curl_buffer_t *buf=(curl_buffer_t *)ptr; char *cbuf=(char *)buffer; ham_size_t payload_size=0; if (buf->offset==0) { if (*(ham_u32_t *)&cbuf[0]!=ham_db2h32(HAM_TRANSFER_MAGIC_V1)) { ham_trace(("invalid protocol version")); return (0); } payload_size=ham_h2db32(*(ham_u32_t *)&cbuf[4]); /* did we receive the whole data in this packet? */ if (payload_size+8==size*nmemb) { buf->wrapper=proto_unpack((ham_size_t)(size*nmemb), (ham_u8_t *)&cbuf[0]); if (!buf->wrapper) return (0); return (size*nmemb); } /* otherwise we have to buffer the received data */ buf->packed_size=payload_size+8; buf->packed_data=allocator_alloc(buf->alloc, buf->packed_size); if (!buf->packed_data) return (0); memcpy(buf->packed_data, &cbuf[0], size*nmemb); buf->offset+=(ham_size_t)(size*nmemb); } /* append to an existing buffer? */ else { memcpy(buf->packed_data+buf->offset, &cbuf[0], size*nmemb); buf->offset+=(ham_size_t)(size*nmemb); } /* check if we've received the whole data */ if (buf->offset==buf->packed_size) { buf->wrapper=proto_unpack(buf->packed_size, buf->packed_data); if (!buf->wrapper) return (0); allocator_free(buf->alloc, buf->packed_data); if (!buf->wrapper) return 0; } return (size*nmemb); }
static ham_status_t _remote_fun_txn_begin(ham_env_t *env, ham_db_t *db, ham_txn_t **txn, ham_u32_t flags) { ham_status_t st; proto_wrapper_t *request, *reply; request=proto_init_txn_begin_request(db_get_remote_handle(db), flags); st=_perform_request(env, env_get_curl(env), request, &reply); proto_delete(request); if (st) { if (reply) proto_delete(reply); return (st); } ham_assert(reply!=0, ("")); ham_assert(proto_has_txn_begin_reply(reply), ("")); st=proto_txn_begin_reply_get_status(reply); if (st) { proto_delete(reply); return (st); } *txn=(ham_txn_t *)allocator_alloc(env_get_allocator(env), sizeof(ham_txn_t)); if (!(*txn)) return (HAM_OUT_OF_MEMORY); st=txn_begin(*txn, env, flags); if (st) { allocator_free(env_get_allocator(env), *txn); *txn=0; } else { txn_set_remote_handle(*txn, proto_txn_begin_reply_get_txn_handle(reply)); } proto_delete(reply); return (st); }
ham_status_t blob_free(ham_env_t *env, ham_db_t *db, ham_offset_t blobid, ham_u32_t flags) { ham_status_t st; blob_t hdr; /* * in-memory-database: the blobid is actually a pointer to the memory * buffer, in which the blob is stored */ if (env_get_rt_flags(env)&HAM_IN_MEMORY_DB) { allocator_free(env_get_allocator(env), (void *)U64_TO_PTR(blobid)); return (0); } ham_assert(blobid%DB_CHUNKSIZE==0, (0)); /* * fetch the blob header */ st=__read_chunk(env, 0, 0, blobid, (ham_u8_t *)&hdr, sizeof(hdr)); if (st) return (st); ham_assert(blob_get_alloc_size(&hdr)%DB_CHUNKSIZE==0, (0)); /* * sanity check */ ham_assert(blob_get_self(&hdr)==blobid, ("invalid blobid %llu != %llu", blob_get_self(&hdr), blobid)); if (blob_get_self(&hdr)!=blobid) return (HAM_BLOB_NOT_FOUND); /* * move the blob to the freelist */ st = freel_mark_free(env, db, blobid, (ham_size_t)blob_get_alloc_size(&hdr), HAM_FALSE); ham_assert(!st, ("unexpected error, at least not covered in the old code")); return st; }
/* client packet handler */ void cmd_packet_handler(struct conn_server *server, struct connection *conn, struct list_packet *packet) { uint16_t command = get_command(packet); /* check login status */ if (conn->type != LOGIN_OK_CONNECTION && command != CMD_LOGIN) { /* the client not login, ignore this packet */ allocator_free(&server->packet_allocator, packet); return; } switch (command) { case CMD_KEEP_ALIVE: cmd_keep_alive(server, conn, packet); break; case CMD_LOGIN: cmd_login(server, conn, packet); break; case CMD_LOGOUT: cmd_logout(server, conn, packet); break; case CMD_SET_NICK: cmd_user(server, conn, packet); break; case CMD_ADD_CONTACT: case CMD_ADD_CONTACT_REPLY: case CMD_CONTACT_LIST: case CMD_CONTACT_INFO_MULTI: cmd_contact(server, conn, packet); break; case CMD_MESSAGE: case CMD_OFFLINE_MSG: cmd_message(server, conn, packet); break; default: log_err("unkonwn command %#hx\n", command); break; } }
int HashmapExercise(int verbose, struct cfg *cfg, char *args[]) { struct hashmap *h; int rate = 0, i, n = 0; int count = atoi(args[0]); int interval = atoi(args[1]); iter_t riter; iter_t iter; char *str; struct allocator *al = NULL; char *mem; clock_t t0; int chkpnt = 0; struct allocator *hal; if ((mem = malloc(0xFFFFFF)) == NULL || (al = suba_init(mem, 0xFFFFFF, 1, 0)) == NULL || (h = hashmap_new(hash_str, cmp_str, NULL, al)) == NULL) { AMSG(""); return -1; } hal = AL(h); /* if ((h = hashmap_new(hash_str, cmp_str, NULL, al)) == NULL) { AMSG(""); return -1; } */ srand(0); t0 = clock(); if (verbose) fprintf(stderr, "\n time count size mem\n"); hashmap_iterate(h, &iter); rate_iterate(&riter); for (i = 0; i < count; i++) { if ((i % interval) == 0) { if (verbose) fprintf(stderr, "%2d %8ld %8d %8d %8d\n", chkpnt++, (clock() - t0) / 1000, hashmap_size(h), table_sizes[h->table_size_index], hal->alloc_total - hal->free_total); rate = rate_next(&riter); } if (rand() % 10 < rate) { str = allocator_alloc(NULL, 8, 0); sprintf(str, "%07d", n++); if (hashmap_put(h, str, str) == -1) { AMSG(""); return -1; } else { /*fputc('+', stderr); */ tcase_printf(verbose, "put %s %d\r", str, hashmap_size(h)); } } else { if (hashmap_is_empty(h)) { /*fputc('0', stderr); */ tcase_printf(verbose, "hashmap empty\r"); } else { str = hashmap_next(h, &iter); if (str) { char *data; tcase_printf(verbose, "get %s %d\r", str, hashmap_size(h)); if (hashmap_remove(h, (void **)&str, (void **)&data) == -1) { AMSG(""); return -1; } /*fputc('-', stderr); */ tcase_printf(verbose, "rem %s %d\r", str, hashmap_size(h)); allocator_free(NULL, str); } else { /*fputc('x', stderr); */ tcase_printf(verbose, "nothing left to iterate over\r"); hashmap_iterate(h, &iter); } } } } if (verbose) fprintf(stderr, "%2d %8ld %8d %8d %8d\n", chkpnt++, (clock() - t0) / 1000, hashmap_size(h), table_sizes[h->table_size_index], hal->alloc_total - hal->free_total); hashmap_del(h, allocator_free, NULL, NULL); /* free(mem); */ if (verbose) fprintf(stderr, "bytes outstanding from allocator: %d\n", hal->alloc_total - hal->free_total); cfg = NULL; return 0; }
ham_status_t blob_overwrite(ham_env_t *env, ham_db_t *db, ham_offset_t old_blobid, ham_record_t *record, ham_u32_t flags, ham_offset_t *new_blobid) { ham_status_t st; ham_size_t alloc_size; blob_t old_hdr; blob_t new_hdr; ham_page_t *page; /* * PARTIAL WRITE * * if offset+partial_size equals the full record size, then we won't * have any gaps. In this case we just write the full record and ignore * the partial parameters. */ if (flags&HAM_PARTIAL) { if (record->partial_offset==0 && record->partial_offset+record->partial_size==record->size) flags&=~HAM_PARTIAL; } /* * inmemory-databases: free the old blob, * allocate a new blob (but if both sizes are equal, just overwrite * the data) */ if (env_get_rt_flags(env)&HAM_IN_MEMORY_DB) { blob_t *nhdr, *phdr=(blob_t *)U64_TO_PTR(old_blobid); if (blob_get_size(phdr)==record->size) { ham_u8_t *p=(ham_u8_t *)phdr; if (flags&HAM_PARTIAL) { memmove(p+sizeof(blob_t)+record->partial_offset, record->data, record->partial_size); } else { memmove(p+sizeof(blob_t), record->data, record->size); } *new_blobid=(ham_offset_t)PTR_TO_U64(phdr); } else { st=blob_allocate(env, db, record, flags, new_blobid); if (st) return (st); nhdr=(blob_t *)U64_TO_PTR(*new_blobid); blob_set_flags(nhdr, blob_get_flags(phdr)); allocator_free(env_get_allocator(env), phdr); } return (HAM_SUCCESS); } ham_assert(old_blobid%DB_CHUNKSIZE==0, (0)); /* * blobs are CHUNKSIZE-allocated */ alloc_size=sizeof(blob_t)+record->size; alloc_size += DB_CHUNKSIZE - 1; alloc_size -= alloc_size % DB_CHUNKSIZE; /* * first, read the blob header; if the new blob fits into the * old blob, we overwrite the old blob (and add the remaining * space to the freelist, if there is any) */ st=__read_chunk(env, 0, &page, old_blobid, (ham_u8_t *)&old_hdr, sizeof(old_hdr)); if (st) return (st); ham_assert(blob_get_alloc_size(&old_hdr)%DB_CHUNKSIZE==0, (0)); /* * sanity check */ ham_verify(blob_get_self(&old_hdr)==old_blobid, ("invalid blobid %llu != %llu", blob_get_self(&old_hdr), old_blobid)); if (blob_get_self(&old_hdr)!=old_blobid) return (HAM_BLOB_NOT_FOUND); /* * now compare the sizes; does the new data fit in the old allocated * space? */ if (alloc_size<=blob_get_alloc_size(&old_hdr)) { ham_u8_t *chunk_data[2]; ham_size_t chunk_size[2]; /* * setup the new blob header */ blob_set_self(&new_hdr, blob_get_self(&old_hdr)); blob_set_size(&new_hdr, record->size); blob_set_flags(&new_hdr, blob_get_flags(&old_hdr)); if (blob_get_alloc_size(&old_hdr)-alloc_size>SMALLEST_CHUNK_SIZE) blob_set_alloc_size(&new_hdr, alloc_size); else blob_set_alloc_size(&new_hdr, blob_get_alloc_size(&old_hdr)); /* * PARTIAL WRITE * * if we have a gap at the beginning, then we have to write the * blob header and the blob data in two steps; otherwise we can * write both immediately */ if ((flags&HAM_PARTIAL) && (record->partial_offset)) { chunk_data[0]=(ham_u8_t *)&new_hdr; chunk_size[0]=sizeof(new_hdr); st=__write_chunks(env, page, blob_get_self(&new_hdr), HAM_FALSE, HAM_FALSE, chunk_data, chunk_size, 1); if (st) return (st); chunk_data[0]=record->data; chunk_size[0]=record->partial_size; st=__write_chunks(env, page, blob_get_self(&new_hdr)+sizeof(new_hdr) +record->partial_offset, HAM_FALSE, HAM_FALSE, chunk_data, chunk_size, 1); if (st) return (st); } else { chunk_data[0]=(ham_u8_t *)&new_hdr; chunk_size[0]=sizeof(new_hdr); chunk_data[1]=record->data; chunk_size[1]=(flags&HAM_PARTIAL) ? record->partial_size : record->size; st=__write_chunks(env, page, blob_get_self(&new_hdr), HAM_FALSE, HAM_FALSE, chunk_data, chunk_size, 2); if (st) return (st); } /* * move remaining data to the freelist */ if (blob_get_alloc_size(&old_hdr)!=blob_get_alloc_size(&new_hdr)) { (void)freel_mark_free(env, db, blob_get_self(&new_hdr)+blob_get_alloc_size(&new_hdr), (ham_size_t)(blob_get_alloc_size(&old_hdr)- blob_get_alloc_size(&new_hdr)), HAM_FALSE); } /* * the old rid is the new rid */ *new_blobid=blob_get_self(&new_hdr); return (HAM_SUCCESS); } else { /* * when the new data is larger, allocate a fresh space for it * and discard the old; 'overwrite' has become (delete + insert) now. */ st=blob_allocate(env, db, record, flags, new_blobid); if (st) return (st); (void)freel_mark_free(env, db, old_blobid, (ham_size_t)blob_get_alloc_size(&old_hdr), HAM_FALSE); } return (HAM_SUCCESS); }
/** * Allocate space in storage for and write the content references by 'data' * (and length 'size') to storage. * * Conditions will apply whether the data is written through cache or direct * to device. * * The content is, of course, prefixed by a BLOB header. * * Partial writes are handled in this function. */ ham_status_t blob_allocate(ham_env_t *env, ham_db_t *db, ham_record_t *record, ham_u32_t flags, ham_offset_t *blobid) { ham_status_t st; ham_page_t *page=0; ham_offset_t addr; blob_t hdr; ham_u8_t *chunk_data[2]; ham_size_t alloc_size; ham_size_t chunk_size[2]; ham_device_t *device=env_get_device(env); ham_bool_t freshly_created = HAM_FALSE; *blobid=0; /* * PARTIAL WRITE * * if offset+partial_size equals the full record size, then we won't * have any gaps. In this case we just write the full record and ignore * the partial parameters. */ if (flags&HAM_PARTIAL) { if (record->partial_offset==0 && record->partial_offset+record->partial_size==record->size) flags&=~HAM_PARTIAL; } /* * in-memory-database: the blobid is actually a pointer to the memory * buffer, in which the blob (with the blob-header) is stored */ if (env_get_rt_flags(env)&HAM_IN_MEMORY_DB) { blob_t *hdr; ham_u8_t *p=(ham_u8_t *)allocator_alloc(env_get_allocator(env), record->size+sizeof(blob_t)); if (!p) { return HAM_OUT_OF_MEMORY; } /* initialize the header */ hdr=(blob_t *)p; memset(hdr, 0, sizeof(*hdr)); blob_set_self(hdr, (ham_offset_t)PTR_TO_U64(p)); blob_set_alloc_size(hdr, record->size+sizeof(blob_t)); blob_set_size(hdr, record->size); /* do we have gaps? if yes, fill them with zeroes */ if (flags&HAM_PARTIAL) { ham_u8_t *s=p+sizeof(blob_t); if (record->partial_offset) memset(s, 0, record->partial_offset); memcpy(s+record->partial_offset, record->data, record->partial_size); if (record->partial_offset+record->partial_size<record->size) memset(s+record->partial_offset+record->partial_size, 0, record->size-(record->partial_offset+record->partial_size)); } else { memcpy(p+sizeof(blob_t), record->data, record->size); } *blobid=(ham_offset_t)PTR_TO_U64(p); return (0); } memset(&hdr, 0, sizeof(hdr)); /* * blobs are CHUNKSIZE-allocated */ alloc_size=sizeof(blob_t)+record->size; alloc_size += DB_CHUNKSIZE - 1; alloc_size -= alloc_size % DB_CHUNKSIZE; /* * check if we have space in the freelist */ st = freel_alloc_area(&addr, env, db, alloc_size); if (!addr) { if (st) return st; /* * if the blob is small AND if logging is disabled: load the page * through the cache */ if (__blob_from_cache(env, alloc_size)) { st = db_alloc_page(&page, db, PAGE_TYPE_BLOB, PAGE_IGNORE_FREELIST); ham_assert(st ? page == NULL : 1, (0)); ham_assert(!st ? page != NULL : 1, (0)); if (st) return st; /* blob pages don't have a page header */ page_set_npers_flags(page, page_get_npers_flags(page)|PAGE_NPERS_NO_HEADER); addr=page_get_self(page); /* move the remaining space to the freelist */ (void)freel_mark_free(env, db, addr+alloc_size, env_get_pagesize(env)-alloc_size, HAM_FALSE); blob_set_alloc_size(&hdr, alloc_size); } else { /* * otherwise use direct IO to allocate the space */ ham_size_t aligned=alloc_size; aligned += env_get_pagesize(env) - 1; aligned -= aligned % env_get_pagesize(env); st=device->alloc(device, aligned, &addr); if (st) return (st); /* if aligned!=size, and the remaining chunk is large enough: * move it to the freelist */ { ham_size_t diff=aligned-alloc_size; if (diff > SMALLEST_CHUNK_SIZE) { (void)freel_mark_free(env, db, addr+alloc_size, diff, HAM_FALSE); blob_set_alloc_size(&hdr, aligned-diff); } else { blob_set_alloc_size(&hdr, aligned); } } freshly_created = HAM_TRUE; } ham_assert(HAM_SUCCESS == freel_check_area_is_allocated(env, db, addr, alloc_size), (0)); } else { ham_assert(!st, (0)); blob_set_alloc_size(&hdr, alloc_size); } blob_set_size(&hdr, record->size); blob_set_self(&hdr, addr); /* * PARTIAL WRITE * * are there gaps at the beginning? If yes, then we'll fill with zeros */ if ((flags&HAM_PARTIAL) && (record->partial_offset)) { ham_u8_t *ptr; ham_size_t gapsize=record->partial_offset; ptr=allocator_calloc(env_get_allocator(env), gapsize > env_get_pagesize(env) ? env_get_pagesize(env) : gapsize); if (!ptr) return (HAM_OUT_OF_MEMORY); /* * first: write the header */ chunk_data[0]=(ham_u8_t *)&hdr; chunk_size[0]=sizeof(hdr); st=__write_chunks(env, page, addr, HAM_TRUE, freshly_created, chunk_data, chunk_size, 1); if (st) return (st); addr+=sizeof(hdr); /* now fill the gap; if the gap is bigger than a pagesize we'll * split the gap into smaller chunks */ while (gapsize>=env_get_pagesize(env)) { chunk_data[0]=ptr; chunk_size[0]=env_get_pagesize(env); st=__write_chunks(env, page, addr, HAM_TRUE, freshly_created, chunk_data, chunk_size, 1); if (st) break; gapsize-=env_get_pagesize(env); addr+=env_get_pagesize(env); } /* fill the remaining gap */ if (gapsize) { chunk_data[0]=ptr; chunk_size[0]=gapsize; st=__write_chunks(env, page, addr, HAM_TRUE, freshly_created, chunk_data, chunk_size, 1); if (st) return (st); addr+=gapsize; } allocator_free(env_get_allocator(env), ptr); /* now write the "real" data */ chunk_data[0]=(ham_u8_t *)record->data; chunk_size[0]=record->partial_size; st=__write_chunks(env, page, addr, HAM_TRUE, freshly_created, chunk_data, chunk_size, 1); if (st) return (st); addr+=record->partial_size; } else { /* * not writing partially: write header and data, then we're done */ chunk_data[0]=(ham_u8_t *)&hdr; chunk_size[0]=sizeof(hdr); chunk_data[1]=(ham_u8_t *)record->data; chunk_size[1]=(flags&HAM_PARTIAL) ? record->partial_size : record->size; st=__write_chunks(env, page, addr, HAM_TRUE, freshly_created, chunk_data, chunk_size, 2); if (st) return (st); addr+=sizeof(hdr)+ ((flags&HAM_PARTIAL) ? record->partial_size : record->size); } /* * store the blobid; it will be returned to the caller */ *blobid=blob_get_self(&hdr); /* * PARTIAL WRITES: * * if we have gaps at the end of the blob: just append more chunks to * fill these gaps. Since they can be pretty large we split them into * smaller chunks if necessary. */ if (flags&HAM_PARTIAL) { if (record->partial_offset+record->partial_size < record->size) { ham_u8_t *ptr; ham_size_t gapsize=record->size - (record->partial_offset+record->partial_size); /* now fill the gap; if the gap is bigger than a pagesize we'll * split the gap into smaller chunks * * we split this loop in two - the outer loop will allocate the * memory buffer, thus saving some allocations */ while (gapsize>env_get_pagesize(env)) { ham_u8_t *ptr=allocator_calloc(env_get_allocator(env), env_get_pagesize(env)); if (!ptr) return (HAM_OUT_OF_MEMORY); while (gapsize>env_get_pagesize(env)) { chunk_data[0]=ptr; chunk_size[0]=env_get_pagesize(env); st=__write_chunks(env, page, addr, HAM_TRUE, freshly_created, chunk_data, chunk_size, 1); if (st) break; gapsize-=env_get_pagesize(env); addr+=env_get_pagesize(env); } allocator_free(env_get_allocator(env), ptr); if (st) return (st); } /* now write the remainder, which is less than a pagesize */ ham_assert(gapsize<env_get_pagesize(env), ("")); chunk_size[0]=gapsize; ptr=chunk_data[0]=allocator_calloc(env_get_allocator(env), gapsize); if (!ptr) return (HAM_OUT_OF_MEMORY); st=__write_chunks(env, page, addr, HAM_TRUE, freshly_created, chunk_data, chunk_size, 1); allocator_free(env_get_allocator(env), ptr); if (st) return (st); } } return (0); }
ham_status_t blob_duplicate_erase(ham_db_t *db, ham_offset_t table_id, ham_size_t position, ham_u32_t flags, ham_offset_t *new_table_id) { ham_status_t st; ham_record_t rec; ham_size_t i; dupe_table_t *table; ham_offset_t rid; ham_env_t *env = db_get_env(db); /* store the public record pointer, otherwise it's destroyed */ ham_size_t rs=db_get_record_allocsize(db); void *rp=db_get_record_allocdata(db); db_set_record_allocdata(db, 0); db_set_record_allocsize(db, 0); memset(&rec, 0, sizeof(rec)); if (new_table_id) *new_table_id=table_id; st=blob_read(db, table_id, &rec, 0); if (st) return (st); /* restore the public record pointer */ db_set_record_allocsize(db, rs); db_set_record_allocdata(db, rp); table=(dupe_table_t *)rec.data; /* * if BLOB_FREE_ALL_DUPES is set *OR* if the last duplicate is deleted: * free the whole duplicate table */ if (flags&BLOB_FREE_ALL_DUPES || (position==0 && dupe_table_get_count(table)==1)) { for (i=0; i<dupe_table_get_count(table); i++) { dupe_entry_t *e=dupe_table_get_entry(table, i); if (!(dupe_entry_get_flags(e)&(KEY_BLOB_SIZE_SMALL |KEY_BLOB_SIZE_TINY |KEY_BLOB_SIZE_EMPTY))) { st=blob_free(env, db, dupe_entry_get_rid(e), 0); if (st) { allocator_free(env_get_allocator(env), table); return (st); } } } st=blob_free(env, db, table_id, 0); /* [i_a] isn't this superfluous (& * dangerous), thanks to the * free_all_dupes loop above??? */ allocator_free(env_get_allocator(env), table); if (st) return (st); if (new_table_id) *new_table_id=0; return (0); } else { ham_record_t rec={0}; dupe_entry_t *e=dupe_table_get_entry(table, position); if (!(dupe_entry_get_flags(e)&(KEY_BLOB_SIZE_SMALL |KEY_BLOB_SIZE_TINY |KEY_BLOB_SIZE_EMPTY))) { st=blob_free(env, db, dupe_entry_get_rid(e), 0); if (st) { allocator_free(env_get_allocator(env), table); return (st); } } memmove(e, e+1, ((dupe_table_get_count(table)-position)-1)*sizeof(dupe_entry_t)); dupe_table_set_count(table, dupe_table_get_count(table)-1); rec.data=(ham_u8_t *)table; rec.size=sizeof(dupe_table_t) +(dupe_table_get_capacity(table)-1)*sizeof(dupe_entry_t); st=blob_overwrite(env, db, table_id, &rec, 0, &rid); if (st) { allocator_free(env_get_allocator(env), table); return (st); } if (new_table_id) *new_table_id=rid; } /* * return 0 as a rid if the table is empty */ if (dupe_table_get_count(table)==0) if (new_table_id) *new_table_id=0; allocator_free(env_get_allocator(env), table); return (0); }
ham_status_t blob_duplicate_insert(ham_db_t *db, ham_offset_t table_id, ham_record_t *record, ham_size_t position, ham_u32_t flags, dupe_entry_t *entries, ham_size_t num_entries, ham_offset_t *rid, ham_size_t *new_position) { ham_status_t st=0; dupe_table_t *table=0; ham_bool_t alloc_table=0; ham_bool_t resize=0; ham_page_t *page=0; ham_env_t *env=db_get_env(db); /* * create a new duplicate table if none existed, and insert * the first entry */ if (!table_id) { ham_assert(num_entries==2, ("")); /* allocates space for 8 (!) entries */ table=allocator_calloc(env_get_allocator(env), sizeof(dupe_table_t)+7*sizeof(dupe_entry_t)); if (!table) return HAM_OUT_OF_MEMORY; dupe_table_set_capacity(table, 8); dupe_table_set_count(table, 1); memcpy(dupe_table_get_entry(table, 0), &entries[0], sizeof(entries[0])); /* skip the first entry */ entries++; num_entries--; alloc_table=1; } else { /* * otherwise load the existing table */ st=__get_duplicate_table(&table, &page, env, table_id); ham_assert(st ? table == NULL : 1, (0)); ham_assert(st ? page == NULL : 1, (0)); if (!table) return st ? st : HAM_INTERNAL_ERROR; if (!page && !(env_get_rt_flags(env)&HAM_IN_MEMORY_DB)) alloc_table=1; } if (page) if ((st=ham_log_add_page_before(page))) return (st); ham_assert(num_entries==1, ("")); /* * resize the table, if necessary */ if (!(flags & HAM_OVERWRITE) && dupe_table_get_count(table)+1>=dupe_table_get_capacity(table)) { dupe_table_t *old=table; ham_size_t new_cap=dupe_table_get_capacity(table); if (new_cap < 3*8) new_cap += 8; else new_cap += new_cap/3; table=allocator_calloc(env_get_allocator(env), sizeof(dupe_table_t)+ (new_cap-1)*sizeof(dupe_entry_t)); if (!table) return (HAM_OUT_OF_MEMORY); dupe_table_set_capacity(table, new_cap); dupe_table_set_count(table, dupe_table_get_count(old)); memcpy(dupe_table_get_entry(table, 0), dupe_table_get_entry(old, 0), dupe_table_get_count(old)*sizeof(dupe_entry_t)); if (alloc_table) allocator_free(env_get_allocator(env), old); alloc_table=1; resize=1; } /* * insert sorted, unsorted or overwrite the entry at the requested position */ if (flags&HAM_OVERWRITE) { dupe_entry_t *e=dupe_table_get_entry(table, position); if (!(dupe_entry_get_flags(e)&(KEY_BLOB_SIZE_SMALL |KEY_BLOB_SIZE_TINY |KEY_BLOB_SIZE_EMPTY))) { (void)blob_free(env, db, dupe_entry_get_rid(e), 0); } memcpy(dupe_table_get_entry(table, position), &entries[0], sizeof(entries[0])); } else { if (db_get_rt_flags(db)&HAM_SORT_DUPLICATES) { if (page) page_add_ref(page); position=__get_sorted_position(db, table, record, flags); if (page) page_release_ref(page); if (position<0) return ((ham_status_t)position); } else if (flags&HAM_DUPLICATE_INSERT_BEFORE) { /* do nothing, insert at the current position */ } else if (flags&HAM_DUPLICATE_INSERT_AFTER) { position++; if (position > dupe_table_get_count(table)) position=dupe_table_get_count(table); } else if (flags&HAM_DUPLICATE_INSERT_FIRST) { position=0; } else if (flags&HAM_DUPLICATE_INSERT_LAST) { position=dupe_table_get_count(table); } else { position=dupe_table_get_count(table); } if (position != dupe_table_get_count(table)) { memmove(dupe_table_get_entry(table, position+1), dupe_table_get_entry(table, position), sizeof(entries[0])*(dupe_table_get_count(table)-position)); } memcpy(dupe_table_get_entry(table, position), &entries[0], sizeof(entries[0])); dupe_table_set_count(table, dupe_table_get_count(table)+1); } /* * write the table back to disk and return the blobid of the table */ if ((table_id && !page) || resize) { ham_record_t rec={0}; rec.data=(ham_u8_t *)table; rec.size=sizeof(dupe_table_t) +(dupe_table_get_capacity(table)-1)*sizeof(dupe_entry_t); st=blob_overwrite(env, db, table_id, &rec, 0, rid); } else if (!table_id) { ham_record_t rec={0}; rec.data=(ham_u8_t *)table; rec.size=sizeof(dupe_table_t) +(dupe_table_get_capacity(table)-1)*sizeof(dupe_entry_t); st=blob_allocate(env, db, &rec, 0, rid); } else if (table_id && page) { page_set_dirty(page, env); } else { ham_assert(!"shouldn't be here", (0)); } if (alloc_table) allocator_free(env_get_allocator(env), table); if (new_position) *new_position=position; return (st); }
int TextTest(int verbose, struct cfg *cfg, char *args[]) { tchar buf[1024]; tchar *hello = TEXT("hello"); tchar *a = TEXT("a"); tchar *e = TEXT(""); tchar *cpy; cfg = NULL; *args = NULL; verbose = 1; /* text_length */ T(text_length(NULL, NULL) == 0); T(text_length(hello, NULL) == 0); T(text_length(hello + 3, hello) == 0); T(text_length(hello, hello) == 0); T(text_length(hello, hello + 1) == 0); T(text_length(hello, hello + 4) == 0); T(text_length(a, a + 1) == 0); T(text_length(a, a + 2) == 1); T(text_length(a + 1, a + 2) == 0); T(text_length(hello, hello + 100) == 5); /* text_size */ T(text_size(NULL, NULL) == 0); T(text_size(hello, NULL) == 0); T(text_size(hello + 3, hello) == 0); T(text_size(hello, hello) == 0); T(text_size(hello, hello + 1) == 0); T(text_size(hello, hello + 4) == 0); T(text_size(a, a + 1) == 0); T(text_size(a, a + 2) == (2 * sizeof *a)); T(text_size(a + 1, a + 2) == (1 * sizeof *a)); T(text_size(hello, hello + 100) == (6 * sizeof *hello)); /* text_copy */ T(text_copy(hello, hello + 100, NULL, buf + 1024, 0) == 0); T(text_copy(hello, hello + 100, buf + 3, buf, 0) == 0); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(NULL, hello + 100, buf, buf + 1024, 0) == 0); T(buf[0] == TEXT('\0')); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello + 3, hello, buf, buf + 1024, 0) == 0); T(buf[0] == TEXT('\0')); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 100, buf, buf + 100, 1) == 1); T(tcsncmp(TEXT("h"), buf, 100) == 0); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 100, buf, buf + 100, 5) == 5); T(tcsncmp(hello, buf, 100) == 0); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 100, buf, buf + 1024, 0) == 0); T(buf[0] == TEXT('\0')); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(e, e + 100, buf, buf + 1024, 100) == 0); T(tcsncmp(e, buf, 100) == 0); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 100, buf, buf + 1024, 100) == 5); T(tcsncmp(hello, buf, 100) == 0); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 1, buf, buf + 1024, 100) == 0); T(buf[0] == TEXT('\0')); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 5, buf, buf + 1024, 100) == 0); T(buf[0] == TEXT('\0')); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 6, buf, buf + 1024, 100) == 5); T(tcsncmp(hello, buf, 100) == 0); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 100, buf, buf + 1, 100) == 0); T(buf[0] == TEXT('\0')); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 100, buf, buf + 5, 100) == 0); T(buf[0] == TEXT('\0')); memset(buf, 'x', 1024 * sizeof(tchar)); T(text_copy(hello, hello + 100, buf, buf + 6, 100) == 5); T(tcsncmp(hello, buf, 100) == 0); /* text_copy_new */ T(text_copy_new(hello, hello + 100, &cpy, 100, NULL) == 5); T(tcsncmp(hello, cpy, 100) == 0); allocator_free(NULL, cpy); T(text_copy_new(hello, hello + 100, NULL, 100, NULL) == 0); T(text_copy_new(NULL, hello + 100, &cpy, 100, NULL) == 0); T(cpy == NULL); T(text_copy_new(hello + 3, hello, &cpy, 100, NULL) == 0); T(cpy == NULL); T(text_copy_new(hello, hello + 100, &cpy, 0, NULL) == 0); T(tcsncmp(e, cpy, 100) == 0); allocator_free(NULL, cpy); T(text_copy_new(hello, hello + 100, &cpy, 4, NULL) == 4); T(tcsncmp(TEXT("hell"), cpy, 100) == 0); allocator_free(NULL, cpy); T(text_copy_new(hello, hello + 100, &cpy, 5, NULL) == 5); T(tcsncmp(hello, cpy, 100) == 0); allocator_free(NULL, cpy); return 0; }
static ham_status_t _remote_fun_get_parameters(ham_db_t *db, ham_parameter_t *param) { static char filename[1024]; ham_status_t st; ham_env_t *env=db_get_env(db); proto_wrapper_t *request, *reply; ham_size_t i, num_names=0; ham_u32_t *names; ham_parameter_t *p; /* count number of parameters */ p=param; if (p) { for (; p->name; p++) { num_names++; } } /* allocate a memory and copy the parameter names */ names=(ham_u32_t *)allocator_alloc(env_get_allocator(env), num_names*sizeof(ham_u32_t)); if (!names) return (HAM_OUT_OF_MEMORY); p=param; if (p) { for (i=0; p->name; p++) { names[i]=p->name; i++; } } request=proto_init_db_get_parameters_request(db_get_remote_handle(db), names, num_names); st=_perform_request(env, env_get_curl(env), request, &reply); proto_delete(request); allocator_free(env_get_allocator(env), names); if (st) { if (reply) proto_delete(reply); return (st); } ham_assert(reply!=0, ("")); ham_assert(proto_has_db_get_parameters_reply(reply), ("")); st=proto_db_get_parameters_reply_get_status(reply); if (st) { proto_delete(reply); return (st); } p=param; while (p && p->name) { switch (p->name) { case HAM_PARAM_CACHESIZE: ham_assert(proto_db_get_parameters_reply_has_cachesize(reply), ("")); p->value=proto_db_get_parameters_reply_get_cachesize(reply); break; case HAM_PARAM_PAGESIZE: ham_assert(proto_db_get_parameters_reply_has_pagesize(reply), ("")); p->value=proto_db_get_parameters_reply_get_pagesize(reply); break; case HAM_PARAM_MAX_ENV_DATABASES: ham_assert(proto_db_get_parameters_reply_has_max_env_databases(reply), ("")); p->value=proto_db_get_parameters_reply_get_max_env_databases(reply); break; case HAM_PARAM_GET_FLAGS: ham_assert(proto_db_get_parameters_reply_has_flags(reply), ("")); p->value=proto_db_get_parameters_reply_get_flags(reply); break; case HAM_PARAM_GET_FILEMODE: ham_assert(proto_db_get_parameters_reply_has_filemode(reply), ("")); p->value=proto_db_get_parameters_reply_get_filemode(reply); break; case HAM_PARAM_GET_FILENAME: ham_assert(proto_db_get_parameters_reply_has_filename(reply), ("")); strncpy(filename, proto_db_get_parameters_reply_get_filename(reply), sizeof(filename)); p->value=PTR_TO_U64(&filename[0]); break; case HAM_PARAM_KEYSIZE: ham_assert(proto_db_get_parameters_reply_has_keysize(reply), ("")); p->value=proto_db_get_parameters_reply_get_keysize(reply); break; case HAM_PARAM_GET_DATABASE_NAME: ham_assert(proto_db_get_parameters_reply_has_dbname(reply), ("")); p->value=proto_db_get_parameters_reply_get_dbname(reply); break; case HAM_PARAM_GET_KEYS_PER_PAGE: ham_assert(proto_db_get_parameters_reply_has_keys_per_page(reply), ("")); p->value=proto_db_get_parameters_reply_get_keys_per_page(reply); break; case HAM_PARAM_GET_DATA_ACCESS_MODE: ham_assert(proto_db_get_parameters_reply_has_dam(reply), ("")); p->value=proto_db_get_parameters_reply_get_dam(reply); break; default: ham_trace(("unknown parameter %d", (int)p->name)); break; } p++; } proto_delete(reply); return (st); }