来源
http://bbs.beishatan.com/
#include
#include
#include
#include
#include
#include "db.h""
#include
#include
#include
#defineDATABASE"bench_001.db"
#defineENV_DIRECTORY"TXNAPP"
#define DESFOLDER"E://test"
char gbuf[2*1024*1024] = {0};
DB_ENV *db_init(char *, char *, int, int);
intfill(DB_ENV *, DB *, int, int, int, int);
intget(DB *,int, int, int, int, int, int *);
intmain(int, char *[]);
voidusage(void);
const char
*progname = "bench_001";/* Program name. */
void env_dir_create()
{
struct stat sb;
/*
* If the directory exists, we're done. We do not further check
* the type of the file, DB will fail appropriately if it's the
* wrong type.
*/
if (stat(ENV_DIRECTORY, &sb) == 0)
return;
/* Create the directory, read/write/access owner only. */
if (mkdir(ENV_DIRECTORY) != 0) {
fprintf(stderr,
"txnapp: mkdir: %s: %s/n", ENV_DIRECTORY, strerror(errno));
exit (1);
}
}
/*
* db_init --
*Initialize the environment.
*/
DB_ENV *
db_init(char *home, char*prefix,
int cachesize, int txn)
{
DB_ENV *dbenv;
int flags, ret;
if ((ret = db_env_create(&dbenv, 0)) != 0) {
dbenv->err(dbenv, ret, "db_env_create");
return (NULL);
}
dbenv->set_errfile(dbenv, stderr);
dbenv->set_errpfx(dbenv, prefix);
(void)dbenv->set_cachesize(dbenv, 0,
cachesize == 0 ? 50 * 1024 * 1024 : (u_int32_t)cachesize, 0);
flags = DB_CREATE | DB_INIT_MPOOL;
flags |= DB_INIT_TXN | DB_INIT_LOCK;
flags |= DB_THREAD | DB_RECOVER;
if (ret = dbenv->open(dbenv, ENV_DIRECTORY,flags, 0) != 0) {
(void)dbenv->close(dbenv, 0);
fprintf(stderr, "dbenv->open: %s: %s/n",
ENV_DIRECTORY, db_strerror(ret));
exit (1);
}
return (dbenv);
}
bool modify(DB *dbp, int txn, char* uid, char* folder, char*name, char*databuf)
{
DBC *dbcp;
DBT key, data;
DB_TXN *txnp;
int ret;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = uid;
key.size = strlen(uid);
txnp = NULL;
dbp->dbenv->txn_begin(dbp->dbenv, NULL, &txnp, 0);
/* Acquire a cursor for the database. */
if ((ret = dbp->cursor(dbp, txnp, &dbcp, 0)) != 0) {
dbp->err(dbp, ret, "DB->cursor");
}
bool blnexist = false;
while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) ==0)
{
int c1, c2, c3;
char *p = (char*)data.data;
char *p1 = p;
char tmpfolder[255] = {0};
char tmpfilename[255] = {0};
memcpy(&c1, p, sizeof(int));
p += sizeof(int);
memset(tmpfolder, 0, 255);
memcpy(tmpfolder, p, c1);
p += c1;
memcpy(&c2, p, sizeof(int));
p += sizeof(int);
memset(tmpfilename, 0, 255);
memcpy(tmpfilename, p, c2);
if (strcmp(folder, tmpfolder) == 0
&& strcmp(name, tmpfilename) == 0)
{
char *p2 = &gbuf[0];
memcpy(p2, p1, c1+c2+sizeof(int)*2);
p2 += c1+c2+sizeof(int)*2;
int len = strlen((char*)databuf);
memcpy(p2, &len, sizeof(len));
p2 += sizeof(len);
memcpy(p2, databuf, len);
data.data = gbuf;
data.size = 2*1024*1024;
dbcp->c_put(dbcp, &key, &data, DB_CURRENT);
blnexist = true;
break;
}
}
dbcp->c_close(dbcp);
txnp->commit(txnp, 0);
if (!blnexist && ret == DB_NOTFOUND)
{
return false;
}
else
{
return true;
}
}
bool append(DB *dbp, int txn, char* uid, char* folder, char*name, char*databuf)
{
DBC *dbcp;
DBT key, data;
DB_TXN *txnp;
int ret;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = uid;
key.size = strlen(uid);
txnp = NULL;
dbp->dbenv->txn_begin(dbp->dbenv, NULL, &txnp, 0);
/* Acquire a cursor for the database. */
if ((ret = dbp->cursor(dbp, txnp, &dbcp, 0)) != 0) {
dbp->err(dbp, ret, "DB->cursor");
}
bool blnexist = false;
while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) ==0)
{
int c1, c2, c3;
char *p = (char*)data.data;
char *p1 = p;
char tmpfolder[255] = {0};
char tmpfilename[255] = {0};
memcpy(&c1, p, sizeof(int));
p += sizeof(int);
memset(tmpfolder, 0, 255);
memcpy(tmpfolder, p, c1);
p += c1;
memcpy(&c2, p, sizeof(int));
p += sizeof(int);
memset(tmpfilename, 0, 255);
memcpy(tmpfilename, p, c2);
p += c2;
memcpy(&c3, p, sizeof(int));
p += sizeof(int);
if (strcmp(folder, tmpfolder) == 0
&& strcmp(name, tmpfilename) == 0)
{
char *p2 = &gbuf[0];
memcpy(p2, p1, c1+c2+sizeof(int)*2);
p2 += c1+c2+sizeof(int)*2;
int len = c3 + strlen((char*)databuf);
memcpy(p2, &len, sizeof(len));
p2 += sizeof(len);
memcpy(p2, p, c3);
p2 += c3;
memcpy(p2, databuf, len);
data.data = gbuf;
data.size = 2*1024*1024;
dbcp->c_put(dbcp, &key, &data, DB_CURRENT);
blnexist = true;
break;
}
}
dbcp->c_close(dbcp);
txnp->commit(txnp, 0);
if (!blnexist && ret == DB_NOTFOUND)
{
return false;
}
else
{
return true;
}
}
bool del(DB *dbp, int txn, char* uid, char* folder, char*name)
{
DBC *dbcp;
DBT key, data;
DB_TXN *txnp;
int ret;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = uid;
key.size = strlen(uid);
txnp = NULL;
dbp->dbenv->txn_begin(dbp->dbenv, NULL, &txnp, 0);
/* Acquire a cursor for the database. */
if ((ret = dbp->cursor(dbp, txnp, &dbcp, 0)) != 0) {
dbp->err(dbp, ret, "DB->cursor");
}
bool blnexist = false;
while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) ==0)
{
int c;
char *p = (char*)data.data;
char tmpfolder[255] = {0};
char tmpfilename[255] = {0};
memcpy(&c, p, sizeof(int));
p += sizeof(int);
memset(tmpfolder, 0, 255);
memcpy(tmpfolder, p, c);
p += c;
memcpy(&c, p, sizeof(int));
p += sizeof(int);
memset(tmpfilename, 0, 20);
memcpy(tmpfilename, p, c);
if (strcmp(folder, tmpfolder) == 0
&& strcmp(name, tmpfilename) == 0)
{
dbcp->c_del(dbcp, 0);
blnexist = true;
break;
}
}
dbcp->c_close(dbcp);
txnp->commit(txnp, 0);
if (!blnexist && ret == DB_NOTFOUND)
{
return false;
}
else
{
return true;
}
}
bool mkfile(DB *dbp, int txn, char* uid, char* folder, char*name)
{
DBC *dbcp;
DBT key, data;
DB_TXN *txnp;
int ret;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = uid;
key.size = strlen(uid);
txnp = NULL;
dbp->dbenv->txn_begin(dbp->dbenv, NULL, &txnp, 0);
/* Acquire a cursor for the database. */
if ((ret = dbp->cursor(dbp, txnp, &dbcp, 0)) != 0) {
dbp->err(dbp, ret, "DB->cursor");
}
bool blnexist = false;
while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) ==0)
{
int c;
char *p = (char*)data.data;
char tmpfolder[255] = {0};
char tmpfilename[255] = {0};
memcpy(&c, p, sizeof(int));
p += sizeof(int);
memset(tmpfolder, 0, 255);
memcpy(tmpfolder, p, c);
p += c;
memcpy(&c, p, sizeof(int));
p += sizeof(int);
memset(tmpfilename, 0, 20);
memcpy(tmpfilename, p, c);
if (strcmp(folder, tmpfolder) == 0
&& strcmp(name, tmpfilename) == 0)
{
p += c;
memcpy(&c, p, sizeof(int));
p += sizeof(int);
memset(gbuf, 0, 2*1024*1024);
memcpy(gbuf, p, c);
FILE *pFile = fopen(tmpfilename, "w");
if (pFile)
{
fwrite(gbuf, sizeof(char), c, pFile);
fclose(pFile);
}
blnexist = true;
break;
}
}
dbcp->c_close(dbcp);
txnp->commit(txnp, 0);
if (!blnexist && ret == DB_NOTFOUND)
{
return false;
}
else
{
return true;
}
}
bool judge(DB *dbp, int txn, char* uid, char* folder, char*name)
{
DBC *dbcp;
DBT key, data;
DB_TXN *txnp;
int ret;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = uid;
key.size = strlen(uid);
txnp = NULL;
dbp->dbenv->txn_begin(dbp->dbenv, NULL, &txnp, 0);
/* Acquire a cursor for the database. */
if ((ret = dbp->cursor(dbp, txnp, &dbcp, 0)) != 0) {
dbp->err(dbp, ret, "DB->cursor");
}
bool blnexist = false;
while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) ==0)
{
int c;
char *p = (char*)data.data;
char tmpfolder[255] = {0};
char tmpfilename[255] = {0};
memcpy(&c, p, sizeof(int));
p += sizeof(int);
memset(tmpfolder, 0, 255);
memcpy(tmpfolder, p, c);
p += c;
memcpy(&c, p, sizeof(int));
p += sizeof(int);
memset(tmpfilename, 0, 20);
memcpy(tmpfilename, p, c);
if (strcmp(folder, tmpfolder) == 0
&& strcmp(name, tmpfilename) == 0)
{
blnexist = true;
break;
}
}
dbcp->c_close(dbcp);
txnp->commit(txnp, 0);
if (!blnexist && ret == DB_NOTFOUND)
{
return false;
}
else
{
return true;
}
}
/*
* get -- loop getting batches of records.
*
*/
int
get(DB *dbp, int txn, int datalen, int num, int dups, int iter, int *countp)
{
DBC *dbcp;
DBT key, data;
DB_TXN *txnp;
u_int32_t len, klen;
int count, flags, i, j, ret;
void *pointer, *dp, *kp;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = "datianxia";
key.size = strlen("datianxia");
txnp = NULL;
dbp->dbenv->txn_begin(dbp->dbenv, NULL, &txnp, 0);
/* Acquire a cursor for the database. */
if ((ret = dbp->cursor(dbp, txnp, &dbcp, 0)) != 0) {
dbp->err(dbp, ret, "DB->cursor");
}
while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) ==0)
{
int c;
char *p = (char*)data.data;
char tmp[20] = {0};
memcpy(&c, p, sizeof(int));
p += sizeof(int);
memset(tmp, 0, 20);
memcpy(tmp, p, c);
printf("%s/n", tmp);
p += c;
memcpy(&c, p, sizeof(int));
p += sizeof(int);
memset(tmp, 0, 20);
memcpy(tmp, p, c);
printf("%s/n", tmp);
}
if (ret == DB_NOTFOUND) {
printf("dfds/n");
}
dbcp->c_close(dbcp);
if (txn)
txnp->commit(txnp, 0);
*countp = count;
return (0);
}
/*
* fill - fill a db
*Since we open/created the db with transactions (potentially),
* we need to populate it with transactions. We'll bundle the puts
* 10 to a transaction.
*/
#definePUTS_PER_TXN1
int
fill(DB_ENV *dbenv, DB *dbp, int txn, int datalen, int num, int dups)
{
DBT key, data;
DB_TXN *txnp;
int count, i, ret;
/*
* Insert records into the database, where the key is the user
* input and the data is the user input in reverse order.
*/
txnp = NULL;
ret = 0;
count = 0;
data.flags = DB_DBT_USERMEM;
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
struct _finddata_t c_file;
char szBuf[255] = {0};
char szDir[255] = {0};
strcpy(szBuf, DESFOLDER);
strcpy(szDir, DESFOLDER);
strcat(szDir, "//");
strcat(szBuf, "//*.*");
long hFile = _findfirst(szBuf, &c_file);
if(hFile == -1L)
return FALSE;
while(_findnext(hFile, &c_file) != -1L)
{
if(strcmp(c_file.name, "..") != 0)
{
if(c_file.attrib & _A_SUBDIR)
{
//do nothing
}
else
{
char *pKey = "datianxia";
key.data = pKey;
key.size = strlen(pKey);
char szFile[255] = {0};
sprintf(szFile, "%s%s", szDir, c_file.name);
int foldersize = sizeof(szDir);
int namesize = sizeof(c_file.name);
char *pFolder;
pFolder = &gbuf[0];
int len = strlen(szDir);
memcpy(gbuf, &len, sizeof(len));
pFolder += sizeof(len);
memcpy(pFolder, szDir, len);
pFolder += len;
len = strlen(c_file.name);
memcpy(pFolder, &len, sizeof(len));
pFolder += sizeof(len);
memcpy(pFolder, c_file.name, len);
pFolder += len;
FILE *pFile = fopen(szFile, "r");
if (!pFile)
return FALSE;
fseek (pFile , 0 , SEEK_END);
int filesize = ftell (pFile);
rewind (pFile);
memcpy(pFolder, &filesize, sizeof(len));
pFolder += sizeof(filesize);
fread(pFolder, sizeof(char), filesize, pFile);
fclose(pFile);
data.data = gbuf;
data.size = 2*1024*1024;
if (i % PUTS_PER_TXN == 0)
{
if (txnp != NULL)
{
ret = txnp->commit(txnp, 0);
txnp = NULL;
if (ret != 0)
goto err;
}
if ((ret =
dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0)
goto err;
}
i++;
if (judge(dbp, txn, "datianxia", szDir, c_file.name))
continue;
do {
switch (ret =
dbp->put(dbp, txnp, &key, &data, 0)) {
case 0:
count++;
break;
default:
dbp->err(dbp, ret, "DB->put");
goto err;
}
} while (ret != 0);
}
}
}//end of find file
_findclose( hFile );
if (txnp != NULL)
ret = txnp->commit(txnp, 0);
printf("%d/n", count);
return (ret);
err:if (txnp != NULL)
(void)txnp->abort(txnp);
return (ret);
}
int
main(int argc,
char *argv[])
{
DB *dbp;
DB_ENV *dbenv;
DB_TXN *txnp;
int cache, ch, count, datalen, dups, env, init, iter, num, pagesize;
int ret, rflag, txn;
txnp = NULL;
datalen = 20;
iter = num = 10000;
env = 1;
dups = init = rflag = txn = 0;
pagesize = 65536;
cache = 1000 * pagesize;
env_dir_create();
dbenv = NULL;
if ((dbenv = db_init("BENCH_001", "bench_001", cache, txn)) == NULL)
return (-1);
if (init)
exit(0);
/* Create and initialize database object, open the database. */
if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
fprintf(stderr,
"%s: db_create: %s/n", progname, db_strerror(ret));
exit(EXIT_FAILURE);
}
dbp->set_errfile(dbp, stderr);
dbp->set_errpfx(dbp, progname);
if ((ret = dbp->set_pagesize(dbp, pagesize)) != 0) {
dbp->err(dbp, ret, "set_pagesize");
goto err1;
}
if ((ret = dbp->set_flags(dbp, DB_DUP)) != 0) {
dbp->err(dbp, ret, "set_flags");
goto err1;
}
if ((ret = dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0)
goto err1;
if ((ret = dbp->open(
dbp, txnp, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s: open", DATABASE);
if (txnp != NULL)
(void)txnp->abort(txnp);
goto err1;
}
ret = txnp->commit(txnp, 0);
txnp = NULL;
if (ret != 0)
goto err1;
if ((ret = fill(dbenv, dbp, txn, datalen, num, dups)) != 0)
goto err1;
/**/
del(dbp, txn, "datianxia", "E://test//", "update.ini");
mkfile(dbp, txn, "datianxia", "E://test//","in.txt");
modify(dbp, txn, "datianxia", "E://test//","in.txt", "datianxiatest");
mkfile(dbp, txn, "datianxia", "E://test//","in.txt");
append(dbp, txn, "datianxia", "E://test//", "in.txt", "dfdsfdsf");
mkfile(dbp, txn, "datianxia", "E://test//","in.txt");
/* If no environment, fill the cache. */
if ((ret =
get(dbp, txn, datalen, num, dups, iter, &count)) != 0)
goto err1;
/* Close everything down. */
if ((ret = dbp->close(dbp, rflag ? DB_NOSYNC : 0)) != 0) {
fprintf(stderr,
"%s: DB->close: %s/n", progname, db_strerror(ret));
return (1);
}
return (ret);
err1:(void)dbp->close(dbp, 0);
return (1);
}
void
usage()
{
(void)fprintf(stderr, "usage: %s %s/n/t%s/n",
progname, "[-EIRT] [-c cachesize] [-d dups]",
"[-i iterations] [-l datalen] [-n keys] [-p pagesize]");
exit(EXIT_FAILURE);
}