关闭

BDB读、写、删除、更新事物、例子

标签: nullcdatabasetransactionsfilecache
889人阅读 评论(0) 收藏 举报
分类:

来源
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);
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:44338次
    • 积分:691
    • 等级:
    • 排名:千里之外
    • 原创:24篇
    • 转载:2篇
    • 译文:0篇
    • 评论:10条
    最新评论