LMDB数据库原子get和C中的put

LMDB数据库原子get和C中的put,c,linux,lmdb,C,Linux,Lmdb,我需要从LMDB数据库中获取密钥,然后根据该密钥将一些附加数据放回该密钥的值中,并且有必要在该操作期间使该密钥对其他人不可写入 我使用的库-,以及lmdb.h文件- 如何在LMDB中实现这一点 这是我的基本代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include "lmdb.h" #define BUF_SIZE 1024 #define CACHE_SIZE 1UL

我需要从LMDB数据库中获取密钥,然后根据该密钥将一些附加数据放回该密钥的值中,并且有必要在该操作期间使该密钥对其他人不可写入

我使用的库-,以及lmdb.h文件-

如何在LMDB中实现这一点

这是我的基本代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lmdb.h"


#define BUF_SIZE 1024
#define CACHE_SIZE 1UL * 1024UL * 1024UL * 1024UL

#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
    "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))

/* Must create somedb folder first */
#define DBDIR "./somedb"


/* Put the key to db */
int putdb(char *, char *);

/* Put and get the key from db */
int getandputdb(char *, char *);

/* Get the key from db */
int getdb(char *);


int main(int argc, char * argv[])
{
    putdb("key", "value");
    getdb("key");

    /* Must to be atomic */
    getandputdb("KeyToGet", "ValueToBePutAfterGet");

    return 0;
}

/* Put to db */
int putdb(char *keyvalue, char *value) {

    int rc;
    MDB_env *env;
    MDB_dbi dbi;
    MDB_txn *txn;
    MDB_val key, data, rdata;
    MDB_cursor *cursor;
    char sval[32];

    //printf("put %s %s\n",keyvalue, value);

    E(mdb_env_create(&env));

    /* Set the cache size */
    E(mdb_env_set_mapsize(env, CACHE_SIZE));
    E(mdb_env_open(env, DBDIR, 0, 0664));

    /* Put some data */
    E(mdb_txn_begin(env, NULL, 0, &txn));
    E(mdb_dbi_open(txn, NULL, 0, &dbi));

    key.mv_data = keyvalue;
    key.mv_size = strlen(keyvalue);
    data.mv_data = value;
    data.mv_size = strlen(value);

    E(mdb_put(txn, dbi, &key, &data, 0));

    E(mdb_txn_commit(txn));

    mdb_dbi_close(env, dbi);
    mdb_env_close(env);

    return 0;
}

/* Get from lmdb */
int getdb(char *thekey) {

    int rc;
    MDB_env *env;
    MDB_dbi dbi;
    MDB_txn *txn;
    MDB_val key, data, rdata;
    MDB_cursor *cursor;

    //printf("get %s\n", thekey);

    E(mdb_env_create(&env));

    /* Set the cache size */
    E(mdb_env_set_mapsize(env, CACHE_SIZE));
    E(mdb_env_open(env, DBDIR, 0, 0664));

    /* Get some data */
    E(mdb_txn_begin(env, NULL, 0, &txn));
    E(mdb_dbi_open(txn, NULL, 0, &dbi));

    key.mv_data = thekey;
    key.mv_size = strlen(thekey);

    rc = mdb_get(txn, dbi, &key, &data);
    if (!rc) {
        char *valuen = (char *) malloc(data.mv_size + 1);
        memcpy(valuen, data.mv_data, data.mv_size);
        valuen[data.mv_size] = 0;

        printf("%s %s\n", (char *) key.mv_data, valuen);

        free(valuen);
    } else {
        printf("No such key\n");
    }

    //printf("%s %d, %s %d\n", (char *) key.mv_data, key.mv_size, (char *)data.mv_data, data.mv_size);

    E(mdb_txn_commit(txn));


    mdb_dbi_close(env, dbi);
    mdb_env_close(env);

    return 0;
}

/* Put and get from db */
int getandputdb(char *keyvalue, char *value) {

    int rc;
    MDB_env *env;
    MDB_dbi dbi;
    MDB_txn *txn;
    MDB_val key, data, rdata;
    MDB_cursor *cursor;
    char sval[32];

    /*
     * Atomic operation, how to do this?
     * Get the key value and then put the value with some changes back in the atomic operation.
     */



    return 0;

}
#包括
#包括
#包括
#包括“lmdb.h”
#定义BUF_大小1024
#定义缓存大小1UL*1024UL*1024UL*1024UL
#定义E(expr)检查((rc=(expr))==MDB_成功,#expr)
#定义检查(测试,消息)((测试)?(无效)0:((无效)fprintf(标准)\
%s:%d:%s:%s\n“,_文件,_行,msg,mdb_strerror(rc)),abort())
/*必须先创建somedb文件夹*/
#定义DBDIR“/somedb”
/*把钥匙放在db上*/
int putdb(char*,char*);
/*把钥匙从数据库中取出*/
int getandputdb(char*,char*);
/*从数据库中获取密钥*/
int getdb(char*);
int main(int argc,char*argv[])
{
putdb(“键”、“值”);
getdb(“密钥”);
/*必须是原子的*/
getandputdb(“KeyToGet”、“ValueToBePutAfterGet”);
返回0;
}
/*放入数据库*/
int putdb(字符*键值,字符*值){
int rc;
MDB_环境*环境;
MDB_dbi dbi;
MDB_txn*txn;
MDB_val键、数据、rdata;
MDB_光标*光标;
char-sval[32];
//printf(“放置%s%s\n”,键值,值);
E(mdb_环境创建(&env));
/*设置缓存大小*/
E(mdb_环境_集合_映射大小(环境、缓存大小));
E(mdb_env_open)(env,DBDIR,0,0664);;
/*放一些数据*/
E(mdb_txn_begin(env、NULL、0和txn));
E(mdb_dbi_open(txn,NULL,0,&dbi));
key.mv_data=keyvalue;
key.mv_size=strlen(keyvalue);
data.mv_data=数值;
data.mv_size=strlen(值);
E(mdb_put(txn、dbi、key和data,0));
E(mdb_txn_commit(txn));
mdb_dbi_关闭(环境、dbi);
mdb_环境_关闭(环境);
返回0;
}
/*从lmdb获取*/
int getdb(字符*键){
int rc;
MDB_环境*环境;
MDB_dbi dbi;
MDB_txn*txn;
MDB_val键、数据、rdata;
MDB_光标*光标;
//printf(“获取%s\n”,该键);
E(mdb_环境创建(&env));
/*设置缓存大小*/
E(mdb_环境_集合_映射大小(环境、缓存大小));
E(mdb_env_open)(env,DBDIR,0,0664);;
/*获取一些数据*/
E(mdb_txn_begin(env、NULL、0和txn));
E(mdb_dbi_open(txn,NULL,0,&dbi));
key.mv_data=按键;
key.mv_size=strlen(按键);
rc=mdb_-get(txn、dbi、键和数据);
如果(!rc){
char*valuen=(char*)malloc(data.mv_size+1);
memcpy(值,data.mv_数据,data.mv_大小);
valuen[data.mv_size]=0;
printf(“%s%s\n”,(char*)key.mv\u数据,valuen);
自由(瓦伦);
}否则{
printf(“无此类密钥”);
}
//printf(“%s%d,%s%d\n”,(char*)key.mv\u数据,key.mv\u大小,(char*)data.mv\u数据,data.mv\u大小);
E(mdb_txn_commit(txn));
mdb_dbi_关闭(环境、dbi);
mdb_环境_关闭(环境);
返回0;
}
/*从数据库中输入和获取*/
int getandputdb(char*keyvalue,char*value){
int rc;
MDB_环境*环境;
MDB_dbi dbi;
MDB_txn*txn;
MDB_val键、数据、rdata;
MDB_光标*光标;
char-sval[32];
/*
*原子操作,怎么做?
*获取键值,然后将经过一些更改的值放回原子操作中。
*/
返回0;
}
一切都运行得很好,但是如何执行get的原子事务,然后检查一些条件,然后执行put?

  • 使用创建事务。确保不要将其标记为
    MDB\RDONLY
  • 使用获取值
  • 根据需要更改值
  • 将新值与
  • 使用以下命令完成事务:

这几乎就是在任何数据库系统中运行事务的方式。另请参见
mtest*.c
文件中的内容。

谢谢您的回答,它可以工作,但是如果需要在一次提交中放置两次,该怎么办?只要将相同的事务作为参数传递,您就可以执行任何操作。