Created
July 31, 2013 13:48
-
-
Save dim/6122131 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* mtest8.c - memory-mapped database tester/toy */ | |
/* | |
* Copyright 2013 Dimitrij Denissenko, Black Square Media | |
* All rights reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted only as authorized by the OpenLDAP | |
* Public License. | |
* | |
* A copy of this license is available in the file LICENSE in the | |
* top-level directory of the distribution or, alternatively, at | |
* <http://www.OpenLDAP.org/license.html>. | |
*/ | |
/* Tests for multi-process access */ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <time.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include "lmdb.h" | |
int createEnv(MDB_env **env, MDB_dbi *dbi) { | |
int rc; | |
MDB_txn *txn; | |
if ((rc = mdb_env_create(env))) return rc; | |
if ((rc = mdb_env_set_mapsize(*env, 2048LL*1024*1024))) return rc; | |
if ((rc = mdb_env_set_maxdbs(*env, 4))) return rc; | |
if ((rc = mdb_env_open(*env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664))) return rc; | |
if ((rc = mdb_txn_begin(*env, NULL, 0, &txn))) return rc; | |
if ((rc = mdb_open(txn, NULL, MDB_CREATE, dbi))) return rc; | |
if ((rc = mdb_txn_commit(txn))) return rc; | |
return rc; | |
} | |
int bulkWrite(int mode) { | |
char skey[32]; | |
char sval[64]; | |
MDB_env *env = NULL; | |
MDB_dbi dbi; | |
MDB_txn *txn; | |
MDB_val key, data; | |
pid_t childpid = 0; | |
int rc = MDB_SUCCESS; | |
int keys = 10000; | |
if ((rc = createEnv(&env, &dbi))) goto cleanup; | |
while (keys--) { | |
sprintf(skey, "%08x", keys); | |
key.mv_size = 8; | |
key.mv_data = skey; | |
data.mv_size = sizeof(sval); | |
data.mv_data = sval; | |
if ((rc = mdb_txn_begin(env, NULL, 0, &txn))) goto cleanup; | |
if ((rc = mdb_put(txn,dbi,&key,&data,0))) goto cleanup; | |
if ((rc = mdb_txn_commit(txn))) goto cleanup; | |
if ((keys % 1000) == 0) { | |
mdb_env_close(env); | |
env = NULL; | |
/* Wait for previous children */ | |
if (childpid) { | |
int status; | |
waitpid(childpid, &status, 0); | |
childpid = 0; | |
} | |
/* Child */ | |
if (mode && (childpid = fork()) == 0) { | |
char *tmpfile = "./testdb/backup.mdb"; | |
unlink(tmpfile); | |
int fd = open(tmpfile,O_CREAT|O_WRONLY|O_EXCL,0644); | |
if (fd == -1) { | |
printf("Error in child: %s\n",strerror(errno)); | |
exit(1); | |
} | |
rc = createEnv(&env, &dbi); | |
if (mode == 2 && !rc) rc = mdb_env_copyfd(env, fd); | |
close(fd); | |
if (rc) printf("Error in child: %s\n", mdb_strerror(rc)); | |
if (env) mdb_env_close(env); | |
exit(0); | |
} else { | |
if ((rc = createEnv(&env, &dbi))) goto cleanup; | |
} | |
} | |
} | |
cleanup: | |
if (env) mdb_env_close(env); | |
return rc; | |
} | |
int main(int argc,char * argv[]) { | |
int rc; | |
struct stat sb; | |
unlink("./testdb/data.mdb"); | |
if ((rc = bulkWrite(0))) { | |
printf("Error: %s\n", mdb_strerror(rc)); | |
return 1; | |
} | |
if (stat("./testdb/data.mdb", &sb) == -1) { | |
printf("Error: %s\n", strerror(errno)); | |
return 1; | |
} | |
printf("NO FORK : %zu\n", sb.st_size); | |
unlink("./testdb/data.mdb"); | |
if ((rc = bulkWrite(1))) { | |
printf("Error: %s\n", mdb_strerror(rc)); | |
return 1; | |
} | |
if (stat("./testdb/data.mdb", &sb) == -1) { | |
printf("Error: %s\n", strerror(errno)); | |
return 1; | |
} | |
printf("FORK & OPEN : %zu\n", sb.st_size); | |
unlink("./testdb/data.mdb"); | |
if ((rc = bulkWrite(2))) { | |
printf("Error: %s\n", mdb_strerror(rc)); | |
return 1; | |
} | |
if (stat("./testdb/data.mdb", &sb) == -1) { | |
printf("Error: %s\n", strerror(errno)); | |
return 1; | |
} | |
printf("FORK & COPY : %zu\n", sb.st_size); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment