Change binhelper to avoid stupid user errors; now grows the buffer on demand for the specific # of bytes; fix bugs in get_data_dirs/0 (driver and erlang caller)

This commit is contained in:
Dave Smith 2008-12-17 14:45:39 -07:00
parent 3b9ba443f1
commit 45606ddf56
5 changed files with 24 additions and 20 deletions

View file

@ -122,7 +122,7 @@ static TPool* G_TPOOL_TXNS;
#define RETURN_INT(val, outbuf) { \
BinHelper bh; \
bin_helper_init(&bh, 4); \
bin_helper_init(&bh); \
bin_helper_push_int32(&bh, val); \
RETURN_BH(bh, outbuf); }
@ -351,7 +351,7 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
// Pack the status and dbref (or errno) into a binary and return it
// Outbuf is: <<Status:8, DbRef:32>>
BinHelper bh;
bin_helper_init(&bh, 5);
bin_helper_init(&bh);
bin_helper_push_byte(&bh, status);
bin_helper_push_int32(&bh, dbref);
RETURN_BH(bh, outbuf);
@ -748,6 +748,7 @@ static int delete_database(const char* name)
}
// Good, database doesn't seem to be open -- attempt the delete
DBG("Attempting to delete database: %s\n", name);
int rc = G_DB_ENV->dbremove(G_DB_ENV, 0, name, 0, DB_AUTO_COMMIT);
WRITE_UNLOCK(G_DATABASES_RWLOCK);
return rc;
@ -766,7 +767,7 @@ static void tune_system(int target, void* values, BinHelper* bh)
unsigned int bytes = 0;
int caches = 0;
int rc = G_DB_ENV->get_cachesize(G_DB_ENV, &gbytes, &bytes, &caches);
bin_helper_init(bh, 16);
bin_helper_init(bh);
bin_helper_push_int32(bh, rc);
bin_helper_push_int32(bh, gbytes);
bin_helper_push_int32(bh, bytes);
@ -777,7 +778,7 @@ static void tune_system(int target, void* values, BinHelper* bh)
{
unsigned int timeout = UNPACK_INT(values, 0);
int rc = G_DB_ENV->set_timeout(G_DB_ENV, timeout, DB_SET_TXN_TIMEOUT);
bin_helper_init(bh, 4);
bin_helper_init(bh);
bin_helper_push_int32(bh, rc);
break;
}
@ -785,7 +786,7 @@ static void tune_system(int target, void* values, BinHelper* bh)
{
unsigned int timeout = 0;
int rc = G_DB_ENV->get_timeout(G_DB_ENV, &timeout, DB_SET_TXN_TIMEOUT);
bin_helper_init(bh, 8);
bin_helper_init(bh);
bin_helper_push_int32(bh, rc);
bin_helper_push_int32(bh, timeout);
break;
@ -794,16 +795,12 @@ static void tune_system(int target, void* values, BinHelper* bh)
{
const char** dirs = 0;
int rc = G_DB_ENV->get_data_dirs(G_DB_ENV, &dirs);
printf("DATA DIR: %d\n", rc);
bin_helper_init(bh, 64);
bin_helper_init(bh);
bin_helper_push_int32(bh, rc);
if (dirs)
while (dirs && *dirs)
{
while (*dirs != 0)
{
bin_helper_push_string(bh, *dirs);
dirs++;
}
bin_helper_push_string(bh, *dirs);
dirs++;
}
break;
}

View file

@ -12,15 +12,19 @@
static void bin_helper_check_size(BinHelper* bh, int space_needed)
{
if (bh->offset + space_needed > bh->bin->orig_size)
if (bh->bin && (bh->offset + space_needed > bh->bin->orig_size))
{
bh->bin = driver_realloc_binary(bh->bin, bh->offset + space_needed);
}
else if (!bh->bin)
{
bh->bin = driver_alloc_binary(space_needed);
}
}
void bin_helper_init(BinHelper* bh, unsigned int size)
void bin_helper_init(BinHelper* bh)
{
bh->bin = driver_alloc_binary(size);
bh->bin = 0;
bh->offset = 0;
}

View file

@ -15,7 +15,7 @@ typedef struct
unsigned int offset;
} BinHelper;
void bin_helper_init(BinHelper* bh, unsigned int size);
void bin_helper_init(BinHelper* bh);
void bin_helper_push_byte(BinHelper* bh, int value);
void bin_helper_push_int32(BinHelper* bh, int value);
void bin_helper_push_string(BinHelper* bh, const char* string);

View file

@ -239,7 +239,7 @@ cursor_close() ->
end.
delete_database(Filename) ->
Cmd = list_to_binary(Filename),
Cmd = <<(list_to_binary(Filename))/binary, 0:8>>,
<<Rc:32/native-signed>> = erlang:port_control(get_port(), ?CMD_REMOVE_DB, Cmd),
case decode_rc(Rc) of
ok ->

View file

@ -30,9 +30,11 @@ all() ->
delete_should_remove_file,
delete_should_fail_if_db_inuse].
dbconfig(Config) ->
Cfg = [{set_data_dir, ?config(priv_dir, Config)},
{set_flags, 'DB_TXN_NOSYNC'}],
{set_flags, 'DB_TXN_NOSYNC'},
{set_log_config, 'DB_LOG_IN_MEMORY'}],
list_to_binary(lists:flatten([io_lib:format("~s ~s\n", [K,V]) || {K, V} <- Cfg])).
@ -45,7 +47,8 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
ok.
init_per_testcase(_TestCase, Config) ->
init_per_testcase(TestCase, Config) ->
ct:print("~p", [TestCase]),
{ok, Db} = bdberl:open("api_test.db", btree, [create, exclusive]),
[{db, Db}|Config].