[Date Prev][Date Next] [Chronological] [Thread] [Top]

LMDB and Referential transparency



Hi,

I love LMDB, thanks for writing it! I wonder whether it would be possibly to add the following feature:

When I change one of the databases (called for instance A) in my environment, I'd like to be able to still keep a copy of A as it was before, and make a new copy B, that would share all its memory with A, except the changes.

In other words, I'd like to have a function like:

int mdb_fork_db(MDB_txn* txn, MDB_dbi dbi_a, char* B, int open_dbi_flags, MDB_dbi* dbi_b),

which would open a new database dbi_b with name B, and copy the B-Tree root of database "dbi_a" as the root of "dbi_b".

After this, any put/delete on A would update A only, and any put/delete on new_name would update new_name only.

Cheers,
Pierre



Here is an example of the semantics I would find really great:


#include<lmdb.h>

void main(){
 MDB_env *env;
 mdb_env_create(&env);
 mdb_env_open(env,"/tmp/test.lmdb",0,0755);
 MDB_txn *txn;
 mdb_env_set_maxdbs(env,2);
 mdb_txn_begin(env,NULL,0,&txn);

 MDB_dbi db_a;
 mdb_dbi_open(txn,"A",MDB_CREATE,&db_a);
 {
   char*k_="shared1";
   char*v_="value 1";
   MDB_val k = { mv_data:k_,mv_size:sizeof(k_) };
   MDB_val v = { mv_data:v_,mv_size:sizeof(v_) };
   mdb_put(txn,db_a,&k,&v,0);
 }

 {
   char*k_="shared2";
   char*v_="value 2";
   MDB_val k = { mv_data:k_,mv_size:sizeof(k_) };
   MDB_val v = { mv_data:v_,mv_size:sizeof(v_) };
   mdb_put(txn,db_a,&k,&v,0);
 }

 MDB_dbi db_b;
 mdb_fork_db(txn,db,"B",MDB_CREATE,&db_b);
 {
   char*k_="BKey";
   char*v_="Value B";
   MDB_val k = { mv_data:k_,mv_size:sizeof(k_) };
   MDB_val v = { mv_data:v_,mv_size:sizeof(v_) };
   mdb_put(txn,db_b,&k,&v,0);
 }
 {
   char*k_="AKey";
   char*v_="Value A";
   MDB_val k = { mv_data:k_,mv_size:sizeof(k_) };
   MDB_val v = { mv_data:v_,mv_size:sizeof(v_) };
   mdb_put(txn,db_a,&k,&v,0);
 }
 // Now, A has {shared1, shared2, AKey}, and B has {shared1,shared2,BKey}.
 {
   char*k_="shared1";
   MDB_val k = { mv_data:k_,mv_size:sizeof(k_) };
   mdb_del(txn,db_b,&k,NULL);
 }
 // Now, A has {shared1, shared2, AKey}, and B has {shared2,BKey}.
 mdb_drop(db_a);

 // Now, the environment has just a single database B, with keys {shared2, BKey}.
 mdb_txn_commit(txn);

 mdb_env_close(env);
}