Skip to content

Commit

Permalink
LMDB: minimize transaction duration (#323)
Browse files Browse the repository at this point in the history
* LMDB: minimize transaction duration

Readers do not block anything but tie-up resources;
Writers block other writers and thus it's good idea to keep them short.

* LMDB: do not pass data variable when deleting tiles

As MapCache LMDB uses single entry per key, there is no need to
pass data to mdb_del call.
  • Loading branch information
marisn authored Oct 12, 2023
1 parent 885f784 commit 2ac1a61
Showing 1 changed file with 21 additions and 15 deletions.
36 changes: 21 additions & 15 deletions lib/cache_lmdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,24 @@ static int _mapcache_cache_lmdb_has_tile(mapcache_context *ctx, mapcache_cache *
MDB_val key, data;
MDB_txn *txn;
mapcache_cache_lmdb *cache = (mapcache_cache_lmdb*)pcache;
char *skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL);
char *skey;

if (lmdb_env->is_open == 0) {
ctx->set_error(ctx,500,"lmdb is not open %s",cache->basedir);
return MAPCACHE_FALSE;
}

skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL);
key.mv_size = strlen(skey)+1;
key.mv_data = skey;

rc = mdb_txn_begin(lmdb_env->env, NULL, MDB_RDONLY, &txn);
if (rc) {
ctx->set_error(ctx,500,"lmdb failed to begin transaction for has_tile in %s:%s",cache->basedir,mdb_strerror(rc));
return MAPCACHE_FALSE;
}

key.mv_size = strlen(skey)+1;
key.mv_data = skey;

rc = mdb_get(txn, lmdb_env->dbi, &key, &data);

if(rc == 0) {
ret = MAPCACHE_TRUE;
} else if(rc == MDB_NOTFOUND) {
Expand All @@ -107,24 +108,27 @@ static int _mapcache_cache_lmdb_has_tile(mapcache_context *ctx, mapcache_cache *
static void _mapcache_cache_lmdb_delete(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile)
{
int rc;
MDB_val key, data;
MDB_val key;
MDB_txn *txn;
mapcache_cache_lmdb *cache = (mapcache_cache_lmdb*)pcache;
char *skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL);
char *skey;

if (lmdb_env->is_open == 0) {
ctx->set_error(ctx,500,"lmdb is not open %s",cache->basedir);
return;
}

skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL);
key.mv_size = strlen(skey)+1;
key.mv_data = skey;

rc = mdb_txn_begin(lmdb_env->env, NULL, 0, &txn);
if (rc) {
ctx->set_error(ctx,500,"lmdb failed to begin transaction for delete in %s:%s",cache->basedir,mdb_strerror(rc));
return;
}

key.mv_size = strlen(skey)+1;
key.mv_data = skey;
rc = mdb_del(txn, lmdb_env->dbi, &key, &data);
rc = mdb_del(txn, lmdb_env->dbi, &key, NULL);
if (rc) {
if (rc == MDB_NOTFOUND) {
ctx->log(ctx,MAPCACHE_DEBUG,"attempt to delete tile %s absent in the db %s",skey,cache->basedir);
Expand Down Expand Up @@ -152,18 +156,18 @@ static int _mapcache_cache_lmdb_get(mapcache_context *ctx, mapcache_cache *pcach
ctx->set_error(ctx,500,"lmdb is not open %s",cache->basedir);
return MAPCACHE_FALSE;
}

skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL);
key.mv_size = strlen(skey)+1;
key.mv_data = skey;

rc = mdb_txn_begin(lmdb_env->env, NULL, MDB_RDONLY, &txn);
if (rc) {
ctx->set_error(ctx,500,"lmdb failed to begin transaction for get in %s:%s",cache->basedir,mdb_strerror(rc));
return MAPCACHE_FALSE;
}

skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL);
key.mv_size = strlen(skey)+1;
key.mv_data = skey;

rc = mdb_get(txn, lmdb_env->dbi, &key, &data);

if(rc == 0) {
if(((char*)(data.mv_data))[0] == '#') {
tile->encoded_data = mapcache_empty_png_decode(ctx,tile->grid_link->grid->tile_sx, tile->grid_link->grid->tile_sy, (unsigned char*)data.mv_data,&tile->nodata);
Expand Down Expand Up @@ -232,6 +236,7 @@ static void _mapcache_cache_lmdb_set(mapcache_context *ctx, mapcache_cache *pcac
ctx->set_error(ctx,500,"lmdb is not open %s",cache->basedir);
return;
}

rc = mdb_txn_begin(lmdb_env->env, NULL, 0, &txn);
if (rc) {
ctx->set_error(ctx,500,"lmdb failed to begin transaction for set in %s:%s",cache->basedir,mdb_strerror(rc));
Expand Down Expand Up @@ -264,6 +269,7 @@ static void _mapcache_cache_lmdb_multiset(mapcache_context *ctx, mapcache_cache
ctx->set_error(ctx,500,"lmdb is not open %s",cache->basedir);
return;
}

rc = mdb_txn_begin(lmdb_env->env, NULL, 0, &txn);
if (rc) {
ctx->set_error(ctx,500,"lmdb failed to begin transaction for multiset in %s:%s",cache->basedir,mdb_strerror(rc));
Expand Down

0 comments on commit 2ac1a61

Please sign in to comment.