Skip to content

Commit

Permalink
added new function ham_cursor_get_record_size
Browse files Browse the repository at this point in the history
  • Loading branch information
cruppstahl committed Oct 1, 2011
1 parent 94d6dc4 commit e6eaff2
Show file tree
Hide file tree
Showing 15 changed files with 393 additions and 22 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
@@ -1,4 +1,8 @@

Oct 01, 2011 - chris ---------------------------------------------------
o added a new function ham_cursor_get_record_size; retrieves the record
size of the current item

Sep 27, 2011 - chris ---------------------------------------------------
o the cache size is now a 64bit variable; cachesize can be > 4 GB

Expand Down
6 changes: 5 additions & 1 deletion TODO
Expand Up @@ -13,4 +13,8 @@ This branch is in "maintenance mode". New features are on the branch

x allow files > 2 GB (see TODO on bleeding_edge branch)
x allow cachesize > 4 GB (currently it's a 32bit number)
o new function ham_cursor_get_record_size()
x new function ham_cursor_get_record_size()
- remote stub
- with/without dupes
- with/without in-memory

15 changes: 15 additions & 0 deletions include/ham/hamsterdb.h
Expand Up @@ -2956,6 +2956,21 @@ HAM_EXPORT ham_status_t HAM_CALLCONV
ham_cursor_get_duplicate_count(ham_cursor_t *cursor,
ham_size_t *count, ham_u32_t flags);

/**
* Returns the record size of the current key
*
* Returns the record size of the item to which the Cursor currently refers.
*
* @param cursor A valid Cursor handle
* @param size Returns the record size, in bytes
*
* @return @ref HAM_SUCCESS upon success
* @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item
* @return @ref HAM_INV_PARAMETER if @a cursor or @a size is NULL
*/
HAM_EXPORT ham_status_t HAM_CALLCONV
ham_cursor_get_record_size(ham_cursor_t *cursor, ham_offset_t *size);

/**
* Closes a Database Cursor
*
Expand Down
33 changes: 33 additions & 0 deletions src/blob.c
Expand Up @@ -788,6 +788,39 @@ blob_read(ham_db_t *db, ham_offset_t blobid,
return (0);
}

ham_status_t
blob_get_datasize(ham_db_t *db, ham_offset_t blobid, ham_offset_t *size)
{
ham_status_t st;
ham_page_t *page;
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(db_get_env(db))&HAM_IN_MEMORY_DB) {
blob_t *hdr=(blob_t *)U64_TO_PTR(blobid);
*size=blob_get_size(hdr);
return (0);
}

ham_assert(blobid%DB_CHUNKSIZE==0, ("blobid is %llu", blobid));

/* read the blob header */
st=__read_chunk(db_get_env(db), 0, &page, blobid,
(ham_u8_t *)&hdr, sizeof(hdr));
if (st)
return (st);

ham_assert(blob_get_alloc_size(&hdr)%DB_CHUNKSIZE==0, (0));
if (blob_get_self(&hdr)!=blobid)
return (HAM_BLOB_NOT_FOUND);

*size=blob_get_size(&hdr);
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)
Expand Down
10 changes: 9 additions & 1 deletion src/blob.h
Expand Up @@ -233,12 +233,20 @@ blob_allocate(ham_env_t *env, ham_db_t *db, ham_record_t *record,
*
* stores the data in @a record
*
* flags: either 0 or HAM_DIRECT_ACCESS
* flags: either 0 or HAM_DIRECT_ACCESS
*/
extern ham_status_t
blob_read(ham_db_t *db, ham_offset_t blobid,
ham_record_t *record, ham_u32_t flags);

/**
* retrieve a blob size
*
* stores the data in @a size
*/
extern ham_status_t
blob_get_datasize(ham_db_t *db, ham_offset_t blobid, ham_offset_t *size);

/**
* overwrite an existing blob
*
Expand Down
72 changes: 72 additions & 0 deletions src/btree_cursor.c
Expand Up @@ -958,6 +958,77 @@ bt_cursor_get_duplicate_count(ham_cursor_t *db_cursor,
return (0);
}

static ham_status_t
bt_cursor_get_record_size(ham_cursor_t *db_cursor, ham_offset_t *size)
{
ham_bt_cursor_t *cursor = (ham_bt_cursor_t *)db_cursor;
ham_status_t st;
ham_db_t *db=bt_cursor_get_db(cursor);
ham_btree_t *be=(ham_btree_t *)db_get_backend(db);
ham_page_t *page;
btree_node_t *node;
int_key_t *entry;
ham_u32_t keyflags=0;
ham_u64_t *ridptr=0;
ham_u64_t rid=0;
dupe_entry_t dupeentry;

if (!be)
return (HAM_NOT_INITIALIZED);

/*
* uncoupled cursor: couple it
*/
if (bt_cursor_get_flags(cursor)&BT_CURSOR_FLAG_UNCOUPLED) {
st=bt_cursor_couple(cursor);
if (st)
return (st);
}
else if (!(bt_cursor_get_flags(cursor)&BT_CURSOR_FLAG_COUPLED))
return (HAM_CURSOR_IS_NIL);

page=bt_cursor_get_coupled_page(cursor);
node=ham_page_get_btree_node(page);
entry=btree_node_get_key(db, node, bt_cursor_get_coupled_index(cursor));

if (key_get_flags(entry)&KEY_HAS_DUPLICATES) {
st=blob_duplicate_get(db_get_env(db), key_get_ptr(entry),
bt_cursor_get_dupe_id(cursor),
&dupeentry);
if (st)
return st;
keyflags=dupe_entry_get_flags(&dupeentry);
ridptr=&dupeentry._rid;
rid=dupeentry._rid;
}
else {
keyflags=key_get_flags(entry);
ridptr=(ham_u64_t *)&key_get_rawptr(entry);
rid=key_get_ptr(entry);
}

if (keyflags&KEY_BLOB_SIZE_TINY) {
/* the highest byte of the record id is the size of the blob */
char *p=(char *)ridptr;
*size=p[sizeof(ham_offset_t)-1];
}
else if (keyflags&KEY_BLOB_SIZE_SMALL) {
/* record size is sizeof(ham_offset_t) */
*size=sizeof(ham_offset_t);
}
else if (keyflags&KEY_BLOB_SIZE_EMPTY) {
/* record size is 0 */
*size=0;
}
else {
st=blob_get_datasize(db, rid, size);
if (st)
return (st);
}

return (0);
}

ham_status_t
bt_uncouple_all_cursors(ham_page_t *page, ham_size_t start)
{
Expand Down Expand Up @@ -1025,6 +1096,7 @@ bt_cursor_create(ham_db_t *db, ham_txn_t *txn, ham_u32_t flags,
c->_fun_insert=bt_cursor_insert;
c->_fun_erase=bt_cursor_erase;
c->_fun_get_duplicate_count=bt_cursor_get_duplicate_count;
c->_fun_get_record_size=bt_cursor_get_record_size;

*cu=c;
return (0);
Expand Down
42 changes: 24 additions & 18 deletions src/cursor.h
Expand Up @@ -72,12 +72,18 @@ extern "C" {
*/ \
ham_status_t (*_fun_erase)(clss *cu, ham_u32_t flags); \
\
/** \
* Count the number of records stored with the referenced key. \
*/ \
ham_status_t (*_fun_get_duplicate_count)(ham_cursor_t *cursor, \
ham_size_t *count, ham_u32_t flags); \
\
/** \
* Count the number of records stored with the referenced key. \
*/ \
ham_status_t (*_fun_get_duplicate_count)(ham_cursor_t *cursor, \
ham_size_t *count, ham_u32_t flags); \
\
/** \
* Get the record size \
*/ \
ham_status_t (*_fun_get_record_size)(ham_cursor_t *cursor, \
ham_offset_t *size); \
\
/** \
* pointer to the Database object \
*/ \
Expand Down Expand Up @@ -144,12 +150,12 @@ struct ham_cursor_t
/**
* set the 'next' pointer of the linked list
*/
#define cursor_set_next_in_page(c, n) \
{ \
if (n) \
ham_assert((c)->_previous_in_page!=(n), (0)); \
(c)->_next_in_page=(n); \
}
#define cursor_set_next_in_page(c, n) \
{ \
if (n) \
ham_assert((c)->_previous_in_page!=(n), (0)); \
(c)->_next_in_page=(n); \
}

/**
* get the 'previous' pointer of the linked list
Expand All @@ -159,12 +165,12 @@ struct ham_cursor_t
/**
* set the 'previous' pointer of the linked list
*/
#define cursor_set_previous_in_page(c, p) \
{ \
if (p) \
ham_assert((c)->_next_in_page!=(p), (0)); \
(c)->_previous_in_page=(p); \
}
#define cursor_set_previous_in_page(c, p) \
{ \
if (p) \
ham_assert((c)->_next_in_page!=(p), (0)); \
(c)->_previous_in_page=(p); \
}

/**
* set the database pointer
Expand Down
28 changes: 28 additions & 0 deletions src/db.c
Expand Up @@ -2196,6 +2196,33 @@ _local_cursor_get_duplicate_count(ham_cursor_t *cursor,
return (st);
}

static ham_status_t
_local_cursor_get_record_size(ham_cursor_t *cursor, ham_offset_t *size)
{
ham_status_t st;
ham_txn_t local_txn;
ham_db_t *db=cursor_get_db(cursor);
ham_env_t *env=db_get_env(db);

if (!cursor_get_txn(cursor)) {
st=txn_begin(&local_txn, env, HAM_TXN_READ_ONLY);
if (st)
return (st);
}

st=(*cursor->_fun_get_record_size)(cursor, size);
if (st) {
if (!cursor_get_txn(cursor))
(void)txn_abort(&local_txn, 0);
return (st);
}

if (!cursor_get_txn(cursor))
return (txn_commit(&local_txn, 0));
else
return (st);
}

static ham_status_t
_local_cursor_overwrite(ham_cursor_t *cursor, ham_record_t *record,
ham_u32_t flags)
Expand Down Expand Up @@ -2300,6 +2327,7 @@ db_initialize_local(ham_db_t *db)
db->_fun_cursor_erase =_local_cursor_erase;
db->_fun_cursor_find =_local_cursor_find;
db->_fun_cursor_get_duplicate_count=_local_cursor_get_duplicate_count;
db->_fun_cursor_get_record_size=_local_cursor_get_record_size;
db->_fun_cursor_overwrite=_local_cursor_overwrite;
db->_fun_cursor_move =_local_cursor_move;

Expand Down
6 changes: 6 additions & 0 deletions src/db.h
Expand Up @@ -285,6 +285,12 @@ struct ham_db_t
ham_status_t (*_fun_cursor_get_duplicate_count)(ham_cursor_t *cursor,
ham_size_t *count, ham_u32_t flags);

/**
* get record size
*/
ham_status_t (*_fun_cursor_get_record_size)(ham_cursor_t *cursor,
ham_offset_t *size);

/**
* overwrite a cursor
*/
Expand Down
4 changes: 2 additions & 2 deletions src/env.c
Expand Up @@ -45,7 +45,7 @@ extern ham_status_t
__check_create_parameters(ham_env_t *env, ham_db_t *db, const char *filename,
ham_u32_t *pflags, const ham_parameter_t *param,
ham_size_t *ppagesize, ham_u16_t *pkeysize,
ham_size_t *pcachesize, ham_u16_t *pdbname,
ham_u64_t *pcachesize, ham_u16_t *pdbname,
ham_u16_t *pmaxdbs, ham_u16_t *pdata_access_mode, ham_bool_t create);

/*
Expand Down Expand Up @@ -1148,7 +1148,7 @@ _local_fun_open_db(ham_env_t *env, ham_db_t *db,
ham_db_t *head;
ham_status_t st;
ham_u16_t dam = 0;
ham_size_t cachesize = 0;
ham_u64_t cachesize = 0;
ham_backend_t *be = 0;
ham_u16_t dbi;

Expand Down
30 changes: 30 additions & 0 deletions src/hamsterdb.c
Expand Up @@ -3316,6 +3316,36 @@ ham_cursor_get_duplicate_count(ham_cursor_t *cursor,
db->_fun_cursor_get_duplicate_count(cursor, count, flags)));
}

ham_status_t HAM_CALLCONV
ham_cursor_get_record_size(ham_cursor_t *cursor, ham_offset_t *size)
{
ham_db_t *db;

if (!cursor) {
ham_trace(("parameter 'cursor' must not be NULL"));
return (HAM_INV_PARAMETER);
}
db=cursor_get_db(cursor);
if (!db || !db_get_env(db)) {
ham_trace(("parameter 'cursor' must be linked to a valid database"));
return (HAM_INV_PARAMETER);
}
if (!size) {
ham_trace(("parameter 'size' must not be NULL"));
return (db_set_error(db, HAM_INV_PARAMETER));
}

*size=0;

if (!db->_fun_cursor_get_record_size) {
ham_trace(("Database was not initialized"));
return (db_set_error(db, HAM_NOT_INITIALIZED));
}

return (db_set_error(db,
db->_fun_cursor_get_record_size(cursor, size)));
}

ham_status_t HAM_CALLCONV
ham_cursor_close(ham_cursor_t *cursor)
{
Expand Down
10 changes: 10 additions & 0 deletions src/remote.c
Expand Up @@ -1356,6 +1356,15 @@ _remote_cursor_get_duplicate_count(ham_cursor_t *cursor,
return (st);
}

static ham_status_t
_remote_cursor_get_record_size(ham_cursor_t *cursor, ham_u64_t *size)
{
(void)cursor;
(void)size;
/* need this? send me a mail and i will implement it. */
return (HAM_NOT_IMPLEMENTED);
}

static ham_status_t
_remote_cursor_overwrite(ham_cursor_t *cursor,
ham_record_t *record, ham_u32_t flags)
Expand Down Expand Up @@ -1493,6 +1502,7 @@ db_initialize_remote(ham_db_t *db)
db->_fun_cursor_erase =_remote_cursor_erase;
db->_fun_cursor_find =_remote_cursor_find;
db->_fun_cursor_get_duplicate_count=_remote_cursor_get_duplicate_count;
db->_fun_cursor_get_record_size=_remote_cursor_get_record_size;
db->_fun_cursor_overwrite=_remote_cursor_overwrite;
db->_fun_cursor_move =_remote_cursor_move;
return (0);
Expand Down
1 change: 1 addition & 0 deletions unittests/Makefile.am
Expand Up @@ -21,6 +21,7 @@ test_SOURCES = log.cpp \
cppapi.cpp \
recno.cpp \
duplicates.cpp \
cursor.cpp \
env.cpp \
hamsterdb.cpp \
blob.cpp \
Expand Down

0 comments on commit e6eaff2

Please sign in to comment.