Compare commits

...

2 Commits

Author SHA1 Message Date
5ae9afdfa2 Fix leak on txn abort 2024-11-14 21:41:38 +09:00
7775f8000b Fix memory leak and cursor leak 2024-11-14 20:59:04 +09:00
2 changed files with 44 additions and 16 deletions

View File

@@ -134,12 +134,16 @@ public class KissDB: NSObject {
// TODO: impl. more
public func insertData(from: @escaping ((Int)->DataItem?), count: Int) throws {
throw KissDBError.general(-99, "unimplemented")
#if false
let obj = InsertDataItemCallbackObject(insertCallback: from, maxCount: count)
let userPtr = Unmanaged.passUnretained(obj).toOpaque()
guard kiss_db_insert_from(cPtr, false, InsertDataItemCallbackObject.insertCallback, userPtr, cError) else {
throw KissDBError.general(cError.code, cError.message)
}
#endif
}
public func delete(key: String) throws {

View File

@@ -23,6 +23,16 @@
return val; \
}
#define CHECK_RET_ERROR_STMT(expr, val, statement) \
if ((rc = (expr)) != MDB_SUCCESS) { \
if (error) { \
error->code = rc; \
error->message = mdb_strerror(rc); \
} \
statement \
return val; \
}
#define CHECK_RET(expr, val) \
if ((rc = (expr)) != MDB_SUCCESS) { \
return val; \
@@ -51,10 +61,12 @@ kiss_db_ptr kiss_db_create(const kiss_db_config_t* config, kiss_db_error_t* erro
kiss_db_ptr ptr = (kiss_db_ptr) malloc(sizeof(kiss_db_t));
memset(ptr, 0, sizeof(kiss_db_t));
CHECK_RET_ERROR(mdb_env_create(&ptr->env), NULL);
CHECK_RET_ERROR(mdb_env_set_maxreaders(ptr->env, 10), NULL);
CHECK_RET_ERROR(mdb_env_set_mapsize(ptr->env, TERA_BYTE_SIZE), NULL);
CHECK_RET_ERROR(mdb_env_open(ptr->env, config->file, MDB_FIXEDMAP|MDB_NOSYNC, mode), NULL);
#define FREE_PTR() { free(ptr); }
CHECK_RET_ERROR_STMT(mdb_env_create(&ptr->env), NULL, FREE_PTR());
CHECK_RET_ERROR_STMT(mdb_env_set_maxreaders(ptr->env, 10), NULL, FREE_PTR());
CHECK_RET_ERROR_STMT(mdb_env_set_mapsize(ptr->env, TERA_BYTE_SIZE), NULL, FREE_PTR());
CHECK_RET_ERROR_STMT(mdb_env_open(ptr->env, config->file, MDB_FIXEDMAP|MDB_NOSYNC, mode), NULL, FREE_PTR());
return ptr;
}
@@ -65,6 +77,9 @@ void kiss_db_destroy(kiss_db_ptr ptr)
if (ptr == NULL) {
return;
}
if (ptr->txn) {
mdb_txn_abort(ptr->txn);
}
mdb_dbi_close(ptr->env, ptr->dbi);
mdb_env_close(ptr->env);
free(ptr);
@@ -76,7 +91,10 @@ kiss_bool kiss_db_begin(kiss_db_ptr ptr, kiss_db_error_t* error)
int rc = 0;
CHECK_RET_ERROR(mdb_txn_begin(ptr->env, NULL, 0, &ptr->txn), false);
CHECK_RET_ERROR(mdb_dbi_open(ptr->txn, NULL, MDB_CREATE|MDB_DUPSORT, &ptr->dbi), false);
#define ABORT() { mdb_txn_abort(ptr->txn); }
CHECK_RET_ERROR_STMT(mdb_dbi_open(ptr->txn, NULL, MDB_CREATE|MDB_DUPSORT, &ptr->dbi), false, ABORT());
_kiss_db_update_count(ptr);
return true;
@@ -87,6 +105,7 @@ kiss_bool kiss_db_commit(kiss_db_ptr ptr, kiss_db_error_t* error)
{
_kiss_db_update_count(ptr);
mdb_txn_commit(ptr->txn);
ptr->txn = NULL;
return true;
}
@@ -95,7 +114,7 @@ kiss_bool kiss_db_rollback(kiss_db_ptr ptr, kiss_db_error_t* error)
{
_kiss_db_update_count(ptr);
mdb_txn_abort(ptr->txn);
ptr->txn = NULL;
return true;
}
@@ -111,9 +130,9 @@ kiss_bool kiss_db_insert(kiss_db_ptr ptr, kiss_db_item_t* item, kiss_bool update
flags |= MDB_NOOVERWRITE;
}
key.mv_data = item->key;
key.mv_data = (void*)item->key;
key.mv_size = item->key_size;
data.mv_data = item->data;
data.mv_data = (void*)item->data;
data.mv_size = item->data_size;
CHECK_RET_ERROR(mdb_put(ptr->txn, ptr->dbi, &key, &data, flags), false);
@@ -139,9 +158,9 @@ kiss_bool kiss_db_insert_from(kiss_db_ptr ptr, kiss_bool update, kiss_insert_cal
if (false == callback(&item, callback_user_ptr)) {
break;
}
key.mv_data = item.key;
key.mv_data = (void*)item.key;
key.mv_size = item.key_size;
data.mv_data = item.data;
data.mv_data = (void*)item.data;
data.mv_size = item.data_size;
CHECK_RET_ERROR(mdb_put(ptr->txn, ptr->dbi, &key, &data, flags), false);
@@ -207,6 +226,8 @@ kiss_bool kiss_db_delete_into(kiss_db_ptr ptr, const void* in_key, kiss_uint in_
CHECK_RET_ERROR(mdb_cursor_open(ptr->txn, ptr->dbi, &ptr->cursor), false);
#define CLOSE_CURSOR() { mdb_cursor_close(ptr->cursor); }
key.mv_data = (void*)in_key;
key.mv_size = in_key_size;
@@ -222,12 +243,12 @@ kiss_bool kiss_db_delete_into(kiss_db_ptr ptr, const void* in_key, kiss_uint in_
if (false == callback(&item, callback_user_ptr)) {
break;
}
CHECK_RET_ERROR(mdb_cursor_del(ptr->cursor, 0), false);
CHECK_RET_ERROR_STMT(mdb_cursor_del(ptr->cursor, 0), false, CLOSE_CURSOR());
} while ((rc = mdb_cursor_get(ptr->cursor, &key, &data, MDB_NEXT_DUP)) == 0);
}
mdb_cursor_close(ptr->cursor);
CLOSE_CURSOR();
return true;
}
@@ -239,6 +260,8 @@ kiss_bool kiss_db_select(kiss_db_ptr ptr, const void* in_key, kiss_uint in_key_s
CHECK_RET_ERROR(mdb_cursor_open(ptr->txn, ptr->dbi, &ptr->cursor), false);
#define CLOSE_CURSOR() { mdb_cursor_close(ptr->cursor); }
key.mv_data = (void*)in_key;
key.mv_size = in_key_size;
data.mv_data = NULL;
@@ -248,9 +271,10 @@ kiss_bool kiss_db_select(kiss_db_ptr ptr, const void* in_key, kiss_uint in_key_s
rc = mdb_cursor_get(ptr->cursor, &key, &data, MDB_SET);
if (rc == MDB_NOTFOUND) {
CLOSE_CURSOR();
return true;
}
CHECK_RET_ERROR(rc, false);
CHECK_RET_ERROR_STMT(rc, false, CLOSE_CURSOR());
do {
item.key = key.mv_data;
@@ -264,13 +288,13 @@ kiss_bool kiss_db_select(kiss_db_ptr ptr, const void* in_key, kiss_uint in_key_s
rc = mdb_cursor_get(ptr->cursor, &key, &data, MDB_NEXT_DUP);
if (rc == MDB_NOTFOUND) {
return true;
break;
}
CHECK_RET_ERROR(rc, false);
CHECK_RET_ERROR_STMT(rc, false, CLOSE_CURSOR());
} while (true);
mdb_cursor_close(ptr->cursor);
CLOSE_CURSOR();
return true;
}