u_int32_t DbTxn::id() { DB_TXN *txn; txn = unwrap(this); return (txn->id(txn)); // no error }
static int txn_op_getId(lua_State *L) { DB_TXN** ptx = check_txn(L, 1); DB_TXN* tx = *ptx; lua_Number id = tx->id(tx); lua_pushnumber(L, id); return 1; }
int bdb_create_queue(char *queue_name) { pthread_rwlock_wrlock(&qlist_ht_lock); char *k = strdup(queue_name); assert(k != NULL); queue_t *q = (queue_t *)calloc(1, sizeof(queue_t)); assert(q != NULL); q->dbp = NULL; q->set_hits = q->old_set_hits = 0; q->get_hits = q->old_get_hits = 0; pthread_mutex_init(&(q->lock), NULL); int ret; DB_TXN *txnp = NULL; ret = db_create(&(q->dbp), envp, 0); CHECK_DB_RET(ret); if (bdb_settings.q_extentsize != 0){ ret = q->dbp->set_q_extentsize(q->dbp, bdb_settings.q_extentsize); CHECK_DB_RET(ret); } ret = q->dbp->set_re_len(q->dbp, bdb_settings.re_len); CHECK_DB_RET(ret); ret = q->dbp->set_pagesize(q->dbp, bdb_settings.page_size); CHECK_DB_RET(ret); ret = envp->txn_begin(envp, NULL, &txnp, 0); CHECK_DB_RET(ret); ret = q->dbp->open(q->dbp, txnp, queue_name, NULL, DB_QUEUE, DB_CREATE, 0664); CHECK_DB_RET(ret); DBT dbkey,dbdata; qstats_t qs; BDB_CLEANUP_DBT(); memset(&qs, 0, sizeof(qs)); dbkey.data = (void *)queue_name; dbkey.size = strlen(queue_name)+1; dbdata.data = (void *)&qs; dbdata.size = sizeof(qstats_t); ret = qlist_dbp->put(qlist_dbp, txnp, &dbkey, &dbdata, 0); CHECK_DB_RET(ret); ret = txnp->commit(txnp, 0); CHECK_DB_RET(ret); int result = hashtable_insert(qlist_htp, (void *)k, (void *)q); assert(result != 0); pthread_rwlock_unlock(&qlist_ht_lock); return 0; dberr: if (txnp != NULL){ txnp->abort(txnp); } fprintf(stderr, "bdb_create_queue: %s %s\n", queue_name, db_strerror(ret)); pthread_rwlock_unlock(&qlist_ht_lock); return -1; }
int main() { DB *dbp; DB_ENV *dbenv; DB_TXN *xid; DBT key, data; const unsigned int INSERT_NUM = 100; char value[22]; /* should be log INSERT_NUM */ int ret, i, t_ret; env_dir_create(); env_open(&dbenv); if ((ret = db_create(&dbp, dbenv, 0)) != 0) { fprintf(stderr, "db_create: %s\n", db_strerror(ret)); exit (1); } dbenv->txn_begin(dbenv, NULL, &xid, 0); if ((ret = dbp->open(dbp, xid, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) { dbp->err(dbp, ret, "%s", DATABASE); goto err; } memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.size = sizeof(int); key.data = malloc(sizeof(int)); data.data = value; for( i = 0; i < INSERT_NUM; i++ ) { *((int*)key.data) = i; data.size = sizeof(char)*strlen(data.data); sprintf(value, "value: %u\n", i); dbp->put(dbp, xid, &key, &data, 0); } xid->commit(xid, 0); dbenv->txn_begin(dbenv, NULL, &xid, 0); for( i = 0; i < INSERT_NUM; i++ ) { *((int*)key.data) = i; dbp->get(dbp, xid, &key, &data, 0); printf("db: %u: key retrieved: data was %s.\n", *((int*)key.data), (char *)data.data); } xid->abort(xid); err: if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0) ret = t_ret; return 0; }
/* if return item is not NULL, free by caller */ item *bdb_get(char *key){ pthread_rwlock_rdlock(&qlist_ht_lock); item *it = NULL; DB_TXN *txnp = NULL; int ret; queue_t *q = (queue_t *)hashtable_search(qlist_htp, (void *)key); /* queue not exsited */ if (q == NULL) { pthread_rwlock_unlock(&qlist_ht_lock); return NULL; } else { DBT dbkey, dbdata; db_recno_t recno; /* first, alloc a fixed size */ it = item_alloc2(); if (it == 0) { pthread_rwlock_unlock(&qlist_ht_lock); return NULL; } BDB_CLEANUP_DBT(); dbkey.data = &recno; dbkey.ulen = sizeof(recno); dbkey.flags = DB_DBT_USERMEM; dbdata.ulen = bdb_settings.re_len; dbdata.data = it; dbdata.flags = DB_DBT_USERMEM; ret = envp->txn_begin(envp, NULL, &txnp, 0); CHECK_DB_RET(ret); ret = q->dbp->get(q->dbp, txnp, &dbkey, &dbdata, DB_CONSUME); CHECK_DB_RET(ret); ret = txnp->commit(txnp, 0); CHECK_DB_RET(ret); pthread_mutex_lock(&(q->lock)); (q->get_hits)++; pthread_mutex_unlock(&(q->lock)); } pthread_rwlock_unlock(&qlist_ht_lock); return it; dberr: item_free(it); it = NULL; if (txnp != NULL){ txnp->abort(txnp); } if (settings.verbose > 1) { fprintf(stderr, "bdb_get: %s\n", db_strerror(ret)); } pthread_rwlock_unlock(&qlist_ht_lock); return NULL; }
void bdb_qlist_db_open(void){ int ret; DBC *cursorp = NULL; DB_TXN *txnp = NULL; /* Create queue.list db handle */ ret = db_create(&qlist_dbp, envp, 0); CHECK_DB_RET(ret); /* Open and Iterate */ ret = envp->txn_begin(envp, NULL, &txnp, 0); CHECK_DB_RET(ret); ret = qlist_dbp->open(qlist_dbp, txnp, "queue.list", NULL, DB_BTREE, DB_CREATE, 0664); CHECK_DB_RET(ret); ret = qlist_dbp->cursor(qlist_dbp, txnp, &cursorp, 0); CHECK_DB_RET(ret); DBT dbkey, dbdata; char qname[512]; qstats_t qs; BDB_CLEANUP_DBT(); memset(qname, 0, 512); memset(&qs, 0, sizeof(qs)); dbkey.data = (void *)qname; dbkey.ulen = 512; dbkey.flags = DB_DBT_USERMEM; dbdata.data = (void *)&qs; dbdata.ulen = sizeof(qs); dbdata.flags = DB_DBT_USERMEM; while ((ret = cursorp->get(cursorp, &dbkey, &dbdata, DB_NEXT)) == 0) { open_exsited_queue_db(txnp, qname, &qs); } if (ret != DB_NOTFOUND) { goto dberr; } ret = cursorp->close(cursorp); CHECK_DB_RET(ret); ret = txnp->commit(txnp, 0); CHECK_DB_RET(ret); return; dberr: if (cursorp != NULL){ cursorp->close(cursorp); } if (txnp != NULL){ txnp->abort(txnp); } fprintf(stderr, "bdb_qlist_db_open: %s\n", db_strerror(ret)); exit(EXIT_FAILURE); }
/* * Closes databases for a given filesystem. If delete_databases is TRUE, * removes the databases from the system. */ void close_fsdb(char *fsname, fs_db_t *fsdb, boolean_t delete_databases) { size_t i; DB *dbp; char fname[MAXPATHLEN + 1]; DB_TXN *txn; int st; if (fsdb == NULL) { return; } i = sizeof (fs_db_t) / sizeof (DB *); /* close secondaries first, so start from the last in the struct */ while (i > 0) { i--; dbp = ((DB **)fsdb)[i]; if (dbp != NULL) { if (dbp->fname != NULL) { strlcpy(fname, dbp->fname, sizeof (fname)); } else { fname[0] = '\0'; } /* databases must be closed before they're removed. */ dbp->close(dbp, 0); ((DB **)fsdb)[i] = NULL; if ((delete_databases) && (fname[0] != '\0')) { dbEnv->txn_begin(dbEnv, NULL, &txn, 0); dbEnv->dbremove(dbEnv, txn, fname, NULL, 0); txn->commit(txn, 0); } } } if (delete_databases) { char namebuf[MAXPATHLEN]; /* delete fs-specific directory */ st = dbdir_from_fsname(fsname, namebuf, sizeof (namebuf)); if (st == 0) { snprintf(fname, sizeof (fname), "%s/%s", fsmdbdir, namebuf); (void) rmdir(fname); } } }
static int tester__gc(lua_State *L) { DB_TXN** ptx = check_txn(L, 1); DB_TXN* tx = *ptx; if (tx != NULL) { dbgprint("aborting a transaction 0x%x\n", tx); int status = tx->abort(tx); *ptx = NULL; handle_dbexception(L, status); } return 0; }
int main(int argc,char * argv[]) { int rc; DB_ENV *env; DB *dbi; DBT key, data; DB_TXN *txn; DBC *cursor; char sval[32], kval[32]; #define FLAGS (DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_TXN|DB_INIT_MPOOL|DB_CREATE|DB_THREAD) rc = db_env_create(&env, 0); rc = env->open(env, "./testdb", FLAGS, 0664); rc = db_create(&dbi, env, 0); rc = env->txn_begin(env, NULL, &txn, 0); rc = dbi->open(dbi, txn, "test.bdb", NULL, DB_BTREE, DB_CREATE, 0664); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); key.size = sizeof(int); key.data = sval; data.size = sizeof(sval); data.data = sval; sprintf(sval, "%03x %d foo bar", 32, 3141592); rc = dbi->put(dbi, txn, &key, &data, 0); rc = txn->commit(txn, 0); if (rc) { fprintf(stderr, "txn->commit: (%d) %s\n", rc, db_strerror(rc)); goto leave; } rc = env->txn_begin(env, NULL, &txn, 0); rc = dbi->cursor(dbi, txn, &cursor, 0); key.flags = DB_DBT_USERMEM; key.data = kval; key.ulen = sizeof(kval); data.flags = DB_DBT_USERMEM; data.data = sval; data.ulen = sizeof(sval); while ((rc = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) { printf("key: %p %.*s, data: %p %.*s\n", key.data, (int) key.size, (char *) key.data, data.data, (int) data.size, (char *) data.data); } rc = cursor->c_close(cursor); rc = txn->abort(txn); leave: rc = dbi->close(dbi, 0); rc = env->close(env, 0); return rc; }
/* * db_init -- * Open the database. */ int db_init( DB_ENV *dbenv, DB **dbpp, int dups, int pagesize) { DB *dbp; DB_TXN *txnp; int ret; dbp = NULL; txnp = NULL; ret = 0; if ((ret = db_create(&dbp, dbenv, 0)) != 0) { fprintf(stderr, "%s: db_create: %s\n", progname, db_strerror(ret)); return (ret); } 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 err; } if (dups && (ret = dbp->set_flags(dbp, DB_DUP)) != 0) { dbp->err(dbp, ret, "set_flags"); goto err; } if ((ret = dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0) goto err; if ((ret = dbp->open(dbp, txnp, "sss.db", "primary", DB_BTREE, DB_CREATE , 0664)) != 0) { dbp->err(dbp, ret, "%s: open", "sss.db"); goto err; } *dbpp = dbp; ret = txnp->commit(txnp, 0); txnp = NULL; if (ret != 0) goto err; return (0); err: if (txnp != NULL) (void)txnp->abort(0); if (dbp != NULL) (void)dbp->close(dbp, 0); return (ret); }
static int txn_op_abort(lua_State *L) { DB_TXN** ptx = check_txn(L, 1); DB_TXN* tx = *ptx; int status; if (tx != NULL) { dbgprint("aborting tran 0x%x\n", tx); status = tx->abort(tx); handle_dbexception(L, status); *ptx = NULL; } return 0; }
static int txn_op_setName(lua_State *L) { DB_TXN** ptx = check_txn(L, 1); DB_TXN* tx = *ptx; u_int32_t flags = 0; int status; const char* name = lua_tostring(L, 2); if (tx != NULL) { status = tx->set_name(tx, name); handle_dbexception(L, status); } return 0; }
int store_tx_abort(struct acrd_txid *tx) { int ret; DB_TXN *tid = tx->tid; dprintf("tid : %p\n", tid); ret = tid->abort(tid); if (ret != 0) { envp->err(envp, ret, "DB_TXN->abort failed\n"); eprintf("DB_TXN->abort failed\n"); return -1; } return 0; }
/* 0 for Success -1 for SERVER_ERROR */ int bdb_set(char *key, item *it){ pthread_rwlock_rdlock(&qlist_ht_lock); queue_t *q = (queue_t *)hashtable_search(qlist_htp, (void *)key); DB_TXN *txnp = NULL; int ret; if (NULL == q) { pthread_rwlock_unlock(&qlist_ht_lock); ret = bdb_create_queue(key); if (0 != ret){ return -1; } /* search again */ pthread_rwlock_rdlock(&qlist_ht_lock); q = (queue_t *)hashtable_search(qlist_htp, (void *)key); } if (NULL != q) { db_recno_t recno; DBT dbkey, dbdata; BDB_CLEANUP_DBT(); dbkey.data = &recno; dbkey.ulen = sizeof(recno); dbkey.flags = DB_DBT_USERMEM; dbdata.data = it; dbdata.size = ITEM_ntotal(it); ret = envp->txn_begin(envp, NULL, &txnp, 0); CHECK_DB_RET(ret); ret = q->dbp->put(q->dbp, txnp, &dbkey, &dbdata, DB_APPEND); CHECK_DB_RET(ret); ret = txnp->commit(txnp, 0); CHECK_DB_RET(ret); pthread_mutex_lock(&(q->lock)); (q->set_hits)++; pthread_mutex_unlock(&(q->lock)); } pthread_rwlock_unlock(&qlist_ht_lock); return 0; dberr: if (txnp != NULL){ txnp->abort(txnp); } if (settings.verbose > 1) { fprintf(stderr, "bdb_set: %s\n", db_strerror(ret)); } pthread_rwlock_unlock(&qlist_ht_lock); return -1; }
static int txn_op_getName(lua_State *L) { DB_TXN** ptx = check_txn(L, 1); DB_TXN* tx = *ptx; u_int32_t flags = 0; int status; const char* name; if (tx != NULL) { status = tx->get_name(tx, &name); handle_dbexception(L, status); lua_pushstring(L, name); return 1; } return 0; }
void add_fruit(DB_ENV *dbenv, DB *db, char *fruit, char *name) { DBT key, data; DB_TXN *tid; int ret; /* Initialization. */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = fruit; key.size = strlen(fruit); data.data = name; data.size = strlen(name); for (;;) { /* Begin the transaction. */ if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) { dbenv->err(dbenv, ret, "DB_ENV->txn_begin"); exit (1); } /* Store the value. */ switch (ret = db->put(db, tid, &key, &data, 0)) { case 0: /* Success: commit the change. */ if ((ret = tid->commit(tid, 0)) != 0) { dbenv->err(dbenv, ret, "DB_TXN->commit"); exit (1); } return; case DB_LOCK_DEADLOCK: /* Deadlock: retry the operation. */ if ((ret = tid->abort(tid)) != 0) { dbenv->err(dbenv, ret, "DB_TXN->abort"); exit (1); } break; default: /* Error: run recovery. */ dbenv->err(dbenv, ret, "dbc->put: %s/%s", fruit, name); exit (1); } } }
DWORD BdbTxnBegin( PVDIR_BACKEND_CTX pBECtx, VDIR_BACKEND_TXN_MODE txnMode ) { DWORD dwError = 0; DB_TXN* pTxn = NULL; assert(pBECtx); if (pBECtx->pBEPrivate) { pBECtx->iBEPrivateRef++; goto cleanup; } dwError = gVdirBdbGlobals.bdbEnv->txn_begin( gVdirBdbGlobals.bdbEnv, BDB_PARENT_TXN_NULL, &pTxn, BDB_FLAGS_ZERO ); BAIL_ON_VMDIR_ERROR(dwError); pBECtx->pBEPrivate = (PVOID) pTxn; pBECtx->iBEPrivateRef++; cleanup: return dwError; error: if (pTxn) { pTxn->abort(pTxn); } pBECtx->pBEPrivate = NULL; pBECtx->iBEPrivateRef = 0; dwError = BdbToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx); VMDIR_SAFE_FREE_MEMORY(pBECtx->pszBEErrorMsg); VmDirAllocateStringA(db_strerror(pBECtx->dwBEErrorCode), &pBECtx->pszBEErrorMsg); goto cleanup; }
static int txn_op_commit(lua_State *L) { DB_TXN** ptx = check_txn(L, 1); DB_TXN* tx = *ptx; u_int32_t flags = 0; int status; if (lua_gettop(L) > 1) { flags = luabdb_getflags(L, 2); } if (tx != NULL) { dbgprint("commit tran 0x%x\n", tx); status = tx->commit(tx, flags); handle_dbexception(L, status); *ptx = NULL; } return 0; }
static void do_mode_user(void) { char s[LINE_MAX + 1]; DB_TXN *txn = NULL; int rc; rc = tdb.env->txn_begin(tdb.env, NULL, &txn, 0); if (rc) { fprintf(stderr, "txn_begin failed: %d\n", rc); exit(1); } while (fgets(s, sizeof(s), stdin) != NULL) user_line(txn, s); rc = txn->commit(txn, 0); if (rc) { fprintf(stderr, "txn_commit failed: %d\n", rc); exit(1); } }
int bdb_delete_queue(char *queue_name){ pthread_rwlock_wrlock(&qlist_ht_lock); queue_t *q = hashtable_search(qlist_htp, (void *)queue_name); /* NOT FOUND */ if (q == NULL) { pthread_rwlock_unlock(&qlist_ht_lock); return 1; } /* Found, just close and remove it. */ q->dbp->close(q->dbp, 0); pthread_mutex_destroy(&(q->lock)); q = hashtable_remove(qlist_htp, (void *)queue_name); assert(NULL != q); free(q); int ret; DB_TXN *txnp = NULL; ret = envp->txn_begin(envp, NULL, &txnp, 0); CHECK_DB_RET(ret); ret = envp->dbremove(envp, txnp, queue_name, NULL, 0); CHECK_DB_RET(ret); DBT dbkey; memset(&dbkey, 0, sizeof(dbkey)); dbkey.data = (void *)queue_name; dbkey.size = strlen(queue_name) + 1; ret = qlist_dbp->del(qlist_dbp, txnp, &dbkey, 0); CHECK_DB_RET(ret); ret = txnp->commit(txnp, 0); CHECK_DB_RET(ret); pthread_rwlock_unlock(&qlist_ht_lock); return 0; dberr: if (txnp != NULL){ txnp->abort(txnp); } fprintf(stderr, "bdb_delete_queue: %s %s\n", queue_name, db_strerror(ret)); pthread_rwlock_unlock(&qlist_ht_lock); return -1; }
int dbfe_opendb (DB_ENV *dbe, DB **dbp, str filename, int flags, int mode = 0664, bool dups = false) { int r (-1); r = db_create (dbp, dbe, 0); if (r) return r; DB *db = *dbp; db->set_pagesize (db, 16 * 1024); /* Secondary databases, for example, require duplicates */ if (dups && (r = db->set_flags (db, DB_DUPSORT)) != 0) { (void)db->close(db, 0); dbe->err (dbe, r, "db->set_flags: DB_DUP"); return r; } /* the below seems to cause the db to grow much larger. */ // db->set_bt_minkey(db, 60); #if ((DB_VERSION_MAJOR < 4) || ((DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR < 1))) r = db->open (db, filename.cstr (), NULL, DB_BTREE, flags, mode); #else if (!dbe) { r = db->open (db, NULL, filename.cstr (), NULL, DB_BTREE, flags, mode); } else { // Sleepycat 4.1 and greater force us to open the DB inside a // transaction the open suceeds in either case, but if the open // isn't surrounded by a transaction, later calls that use a // transaction will fail DB_TXN *t = NULL; r = dbe->txn_begin (dbe, NULL, &t, 0); if (r || !t) return r; r = db->open (db, t, filename.cstr (), NULL, DB_BTREE, flags, mode); r = t->commit (t, 0); #endif } return r; }
int icalbdbset_delete(DB *dbp, DBT *key) { DB_TXN *tid; int ret; int done = 0; int retry = 0; while ((retry < MAX_RETRY) && !done) { if ((ret = ICAL_DB_ENV->txn_begin(ICAL_DB_ENV, NULL, &tid, 0)) != 0) { if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else { /*char *foo = db_strerror(ret); */ abort(); } } if ((ret = dbp->del(dbp, tid, key, 0)) != 0) { if (ret == DB_NOTFOUND) { /* do nothing - not an error condition */ } else if (ret == DB_LOCK_DEADLOCK) { tid->abort(tid); retry++; continue; } else { char *strError = db_strerror(ret); icalerror_warn("icalbdbset_delete faild: "); icalerror_warn(strError); tid->abort(tid); return ICAL_FILE_ERROR; } } if ((ret = tid->commit(tid, 0)) != 0) { if (ret == DB_LOCK_DEADLOCK) { tid->abort(tid); retry++; continue; } else { /*char *foo = db_strerror(ret); */ abort(); } } done = 1; /* all is well */ } if (!done) { if (tid != NULL) { tid->abort(tid); } } return ret; }
DWORD BdbTxnAbort( PVDIR_BACKEND_CTX pBECtx ) { DWORD dwError = 0; DB_TXN* pTxn = NULL; assert(pBECtx); if (pBECtx->pBEPrivate) { assert(pBECtx->iBEPrivateRef >= 1); pBECtx->iBEPrivateRef--; if (pBECtx->iBEPrivateRef == 0) { pTxn = (DB_TXN*)pBECtx->pBEPrivate; pBECtx->pBEPrivate = NULL; dwError = pTxn->abort(pTxn); BAIL_ON_VMDIR_ERROR(dwError); } } cleanup: return dwError; error: dwError = BdbToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx); VMDIR_SAFE_FREE_MEMORY(pBECtx->pszBEErrorMsg); VmDirAllocateStringA(db_strerror(pBECtx->dwBEErrorCode), &pBECtx->pszBEErrorMsg); goto cleanup; }
DB* PerconaFTEngine::GetFTDB(Context& ctx, const Data& ns, bool create_if_missing) { RWLockGuard<SpinRWLock> guard(m_lock, !create_if_missing); FTDBTable::iterator found = m_dbs.find(ns); if (found != m_dbs.end()) { return found->second; } if (!create_if_missing) { return NULL; } DB *db = NULL; int r = 0; CHECK_EXPR(r = db_create(&db, m_env, 0)); if (0 == r) { DB_TXN* txn = NULL; CHECK_EXPR(m_env->txn_begin(m_env, NULL, &txn, 0)); uint32 open_flags = DB_CREATE | DB_THREAD; int open_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; CHECK_EXPR(r = db->open(db, txn, ns.AsString().c_str(), NULL, DB_BTREE, open_flags, open_mode)); txn->commit(txn, 0); } if (0 == r) { db->set_compression_method(db, g_perconaft_config.compression); m_dbs[ns] = db; INFO_LOG("Success to open db:%s", ns.AsString().c_str()); } else { free(db); db = NULL; ERROR_LOG("Failed to open db:%s for reason:(%d)%s", ns.AsString().c_str(), r, db_strerror(r)); } return db; }
int icalbdbset_put(DB *dbp, DBT *key, DBT *data, u_int32_t access_method) { int ret = 0; DB_TXN *tid = NULL; int retry = 0; int done = 0; while ((retry < MAX_RETRY) && !done) { if ((ret = ICAL_DB_ENV->txn_begin(ICAL_DB_ENV, NULL, &tid, 0)) != 0) { if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else { /*char *foo = db_strerror(ret); */ abort(); } } if ((ret = dbp->put(dbp, tid, key, data, access_method)) != 0) { if (ret == DB_LOCK_DEADLOCK) { tid->abort(tid); retry++; continue; } else { char *strError = db_strerror(ret); icalerror_warn("icalbdbset_put faild: "); icalerror_warn(strError); tid->abort(tid); return ICAL_FILE_ERROR; } } if ((ret = tid->commit(tid, 0)) != 0) { if (ret == DB_LOCK_DEADLOCK) { tid->abort(tid); retry++; continue; } else { /*char *foo = db_strerror(ret); */ abort(); } } done = 1; /* all is well */ } if (!done) { if (tid != NULL) { tid->abort(tid); } return ICAL_FILE_ERROR; } else { return ICAL_NO_ERROR; } }
int bdb_add(Operation *op, SlapReply *rs ) { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; struct berval pdn; Entry *p = NULL, *oe = op->ora_e; EntryInfo *ei; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; AttributeDescription *children = slap_schema.si_ad_children; AttributeDescription *entry = slap_schema.si_ad_entry; DB_TXN *ltid = NULL, *lt2; ID eid = NOID; struct bdb_op_info opinfo = {{{ 0 }}}; int subentry; DB_LOCK lock; int num_retries = 0; int success; LDAPControl **postread_ctrl = NULL; LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; int num_ctrls = 0; #ifdef LDAP_X_TXN int settle = 0; #endif Debug(LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_add) ": %s\n", op->ora_e->e_name.bv_val, 0, 0); #ifdef LDAP_X_TXN if( op->o_txnSpec ) { /* acquire connection lock */ ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { rs->sr_text = "invalid transaction identifier"; rs->sr_err = LDAP_X_TXN_ID_INVALID; goto txnReturn; } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { settle=1; goto txnReturn; } if( op->o_conn->c_txn_backend == NULL ) { op->o_conn->c_txn_backend = op->o_bd; } else if( op->o_conn->c_txn_backend != op->o_bd ) { rs->sr_text = "transaction cannot span multiple database contexts"; rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; goto txnReturn; } /* insert operation into transaction */ rs->sr_text = "transaction specified"; rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; txnReturn: /* release connection lock */ ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); if( !settle ) { send_ldap_result( op, rs ); return rs->sr_err; } } #endif ctrls[num_ctrls] = 0; /* check entry's schema */ rs->sr_err = entry_schema_check( op, op->ora_e, NULL, get_relax(op), 1, NULL, &rs->sr_text, textbuf, textlen ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": entry failed schema check: " "%s (%d)\n", rs->sr_text, rs->sr_err, 0 ); goto return_results; } /* add opattrs to shadow as well, only missing attrs will actually * be added; helps compatibility with older OL versions */ rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": entry failed op attrs add: " "%s (%d)\n", rs->sr_text, rs->sr_err, 0 ); goto return_results; } if ( get_assert( op ) && ( test_filter( op, op->ora_e, get_assertion( op )) != LDAP_COMPARE_TRUE )) { rs->sr_err = LDAP_ASSERTION_FAILED; goto return_results; } subentry = is_entry_subentry( op->ora_e ); if( 0 ) { retry: /* transaction retry */ if( p ) { /* free parent and reader lock */ if ( p != (Entry *)&slap_entry_root ) { bdb_unlocked_cache_return_entry_r( bdb, p ); } p = NULL; } rs->sr_err = TXN_ABORT( ltid ); ltid = NULL; LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); opinfo.boi_oe.oe_key = NULL; op->o_do_not_cache = opinfo.boi_acl_cache; if( rs->sr_err != 0 ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "internal error"; goto return_results; } if ( op->o_abandon ) { rs->sr_err = SLAPD_ABANDON; goto return_results; } bdb_trans_backoff( ++num_retries ); } /* begin transaction */ rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, bdb->bi_db_opflags ); rs->sr_text = NULL; if( rs->sr_err != 0 ) { Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn_begin failed: %s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); rs->sr_err = LDAP_OTHER; rs->sr_text = "internal error"; goto return_results; } Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn1 id: %x\n", ltid->id(ltid), 0, 0 ); opinfo.boi_oe.oe_key = bdb; opinfo.boi_txn = ltid; opinfo.boi_err = 0; opinfo.boi_acl_cache = op->o_do_not_cache; LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); /* * Get the parent dn and see if the corresponding entry exists. */ if ( be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) { pdn = slap_empty_bv; } else { dnParent( &op->ora_e->e_nname, &pdn ); } /* get entry or parent */ rs->sr_err = bdb_dn2entry( op, ltid, &op->ora_e->e_nname, &ei, 1, &lock ); switch( rs->sr_err ) { case 0: rs->sr_err = LDAP_ALREADY_EXISTS; goto return_results; case DB_NOTFOUND: break; case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; case LDAP_BUSY: rs->sr_text = "ldap server busy"; goto return_results; default: rs->sr_err = LDAP_OTHER; rs->sr_text = "internal error"; goto return_results; } p = ei->bei_e; if ( !p ) p = (Entry *)&slap_entry_root; if ( !bvmatch( &pdn, &p->e_nname ) ) { rs->sr_matched = ber_strdup_x( p->e_name.bv_val, op->o_tmpmemctx ); rs->sr_ref = is_entry_referral( p ) ? get_entry_referrals( op, p ) : NULL; if ( p != (Entry *)&slap_entry_root ) bdb_unlocked_cache_return_entry_r( bdb, p ); p = NULL; Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": parent " "does not exist\n", 0, 0, 0 ); rs->sr_err = LDAP_REFERRAL; rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; goto return_results; } rs->sr_err = access_allowed( op, p, children, NULL, ACL_WADD, NULL ); if ( ! rs->sr_err ) { switch( opinfo.boi_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; } if ( p != (Entry *)&slap_entry_root ) bdb_unlocked_cache_return_entry_r( bdb, p ); p = NULL; Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": no write access to parent\n", 0, 0, 0 ); rs->sr_err = LDAP_INSUFFICIENT_ACCESS; rs->sr_text = "no write access to parent"; goto return_results;; } if ( p != (Entry *)&slap_entry_root ) { if ( is_entry_subentry( p ) ) { bdb_unlocked_cache_return_entry_r( bdb, p ); p = NULL; /* parent is a subentry, don't allow add */ Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": parent is subentry\n", 0, 0, 0 ); rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; rs->sr_text = "parent is a subentry"; goto return_results;; } if ( is_entry_alias( p ) ) { bdb_unlocked_cache_return_entry_r( bdb, p ); p = NULL; /* parent is an alias, don't allow add */ Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": parent is alias\n", 0, 0, 0 ); rs->sr_err = LDAP_ALIAS_PROBLEM; rs->sr_text = "parent is an alias"; goto return_results;; } if ( is_entry_referral( p ) ) { /* parent is a referral, don't allow add */ rs->sr_matched = ber_strdup_x( p->e_name.bv_val, op->o_tmpmemctx ); rs->sr_ref = get_entry_referrals( op, p ); bdb_unlocked_cache_return_entry_r( bdb, p ); p = NULL; Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": parent is referral\n", 0, 0, 0 ); rs->sr_err = LDAP_REFERRAL; rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; goto return_results; } } if ( subentry ) { /* FIXME: */ /* parent must be an administrative point of the required kind */ } /* free parent and reader lock */ if ( p != (Entry *)&slap_entry_root ) { if ( p->e_nname.bv_len ) { struct berval ppdn; /* ITS#5326: use parent's DN if differs from provided one */ dnParent( &op->ora_e->e_name, &ppdn ); if ( !dn_match( &p->e_name, &ppdn ) ) { struct berval rdn; struct berval newdn; dnRdn( &op->ora_e->e_name, &rdn ); build_new_dn( &newdn, &p->e_name, &rdn, NULL ); if ( op->ora_e->e_name.bv_val != op->o_req_dn.bv_val ) ber_memfree( op->ora_e->e_name.bv_val ); op->ora_e->e_name = newdn; /* FIXME: should check whether * dnNormalize(newdn) == e->e_nname ... */ } } bdb_unlocked_cache_return_entry_r( bdb, p ); } p = NULL; rs->sr_err = access_allowed( op, op->ora_e, entry, NULL, ACL_WADD, NULL ); if ( ! rs->sr_err ) { switch( opinfo.boi_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; } Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": no write access to entry\n", 0, 0, 0 ); rs->sr_err = LDAP_INSUFFICIENT_ACCESS; rs->sr_text = "no write access to entry"; goto return_results;; } /* * Check ACL for attribute write access */ if (!acl_check_modlist(op, oe, op->ora_modlist)) { switch( opinfo.boi_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; } Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": no write access to attribute\n", 0, 0, 0 ); rs->sr_err = LDAP_INSUFFICIENT_ACCESS; rs->sr_text = "no write access to attribute"; goto return_results;; } if ( eid == NOID ) { rs->sr_err = bdb_next_id( op->o_bd, &eid ); if( rs->sr_err != 0 ) { Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": next_id failed (%d)\n", rs->sr_err, 0, 0 ); rs->sr_err = LDAP_OTHER; rs->sr_text = "internal error"; goto return_results; } op->ora_e->e_id = eid; } /* nested transaction */ rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, bdb->bi_db_opflags ); rs->sr_text = NULL; if( rs->sr_err != 0 ) { Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn_begin(2) failed: " "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); rs->sr_err = LDAP_OTHER; rs->sr_text = "internal error"; goto return_results; } Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn2 id: %x\n", lt2->id(lt2), 0, 0 ); /* dn2id index */ rs->sr_err = bdb_dn2id_add( op, lt2, ei, op->ora_e ); if ( rs->sr_err != 0 ) { Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": dn2id_add failed: %s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); switch( rs->sr_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; case DB_KEYEXIST: rs->sr_err = LDAP_ALREADY_EXISTS; break; default: rs->sr_err = LDAP_OTHER; } goto return_results; } /* attribute indexes */ rs->sr_err = bdb_index_entry_add( op, lt2, op->ora_e ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": index_entry_add failed\n", 0, 0, 0 ); switch( rs->sr_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; default: rs->sr_err = LDAP_OTHER; } rs->sr_text = "index generation failed"; goto return_results; } /* id2entry index */ rs->sr_err = bdb_id2entry_add( op->o_bd, lt2, op->ora_e ); if ( rs->sr_err != 0 ) { Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": id2entry_add failed\n", 0, 0, 0 ); switch( rs->sr_err ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: goto retry; default: rs->sr_err = LDAP_OTHER; } rs->sr_text = "entry store failed"; goto return_results; } if ( TXN_COMMIT( lt2, 0 ) != 0 ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "txn_commit(2) failed"; goto return_results; } /* post-read */ if( op->o_postread ) { if( postread_ctrl == NULL ) { postread_ctrl = &ctrls[num_ctrls++]; ctrls[num_ctrls] = NULL; } if ( slap_read_controls( op, rs, op->ora_e, &slap_post_read_bv, postread_ctrl ) ) { Debug( LDAP_DEBUG_TRACE, "<=- " LDAP_XSTRING(bdb_add) ": post-read " "failed!\n", 0, 0, 0 ); if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { /* FIXME: is it correct to abort * operation if control fails? */ goto return_results; } } } if ( op->o_noop ) { if (( rs->sr_err=TXN_ABORT( ltid )) != 0 ) { rs->sr_text = "txn_abort (no-op) failed"; } else { rs->sr_err = LDAP_X_NO_OPERATION; ltid = NULL; goto return_results; } } else { struct berval nrdn; /* pick the RDN if not suffix; otherwise pick the entire DN */ if (pdn.bv_len) { nrdn.bv_val = op->ora_e->e_nname.bv_val; nrdn.bv_len = pdn.bv_val - op->ora_e->e_nname.bv_val - 1; } else { nrdn = op->ora_e->e_nname; } bdb_cache_add( bdb, ei, op->ora_e, &nrdn, ltid, &lock ); if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) { rs->sr_text = "txn_commit failed"; } else { rs->sr_err = LDAP_SUCCESS; } } ltid = NULL; LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); opinfo.boi_oe.oe_key = NULL; if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": %s : %s (%d)\n", rs->sr_text, db_strerror(rs->sr_err), rs->sr_err ); rs->sr_err = LDAP_OTHER; goto return_results; } Debug(LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": added%s id=%08lx dn=\"%s\"\n", op->o_noop ? " (no-op)" : "", op->ora_e->e_id, op->ora_e->e_dn ); rs->sr_text = NULL; if( num_ctrls ) rs->sr_ctrls = ctrls; return_results: success = rs->sr_err; send_ldap_result( op, rs ); if( ltid != NULL ) { TXN_ABORT( ltid ); } if ( opinfo.boi_oe.oe_key ) { LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); } if( success == LDAP_SUCCESS ) { /* We own the entry now, and it can be purged at will * Check to make sure it's the same entry we entered with. * Possibly a callback may have mucked with it, although * in general callbacks should treat the entry as read-only. */ bdb_cache_deref( oe->e_private ); if ( op->ora_e == oe ) op->ora_e = NULL; if ( bdb->bi_txn_cp_kbyte ) { TXN_CHECKPOINT( bdb->bi_dbenv, bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); } } slap_graduate_commit_csn( op ); if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) { slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); slap_sl_free( *postread_ctrl, op->o_tmpmemctx ); } return rs->sr_err; }
static void b_inmem_op_tds(u_int ops, int update, u_int32_t env_flags, u_int32_t log_flags) { DB *dbp; DBT key, data; DB_ENV *dbenv; DB_MPOOL_STAT *gsp; DB_TXN *txn; char *keybuf, *databuf; DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL); DB_BENCH_ASSERT((databuf = malloc(datasize)) != NULL); memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = keybuf; key.size = keysize; memset(keybuf, 'a', keysize); data.data = databuf; data.size = datasize; memset(databuf, 'b', datasize); DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); dbenv->set_errfile(dbenv, stderr); /* General environment configuration. */ #ifdef DB_AUTO_COMMIT DB_BENCH_ASSERT(dbenv->set_flags(dbenv, DB_AUTO_COMMIT, 1) == 0); #endif if (env_flags != 0) DB_BENCH_ASSERT(dbenv->set_flags(dbenv, env_flags, 1) == 0); /* Logging configuration. */ if (log_flags != 0) #if DB_VERSION_MINOR >= 7 DB_BENCH_ASSERT( dbenv->log_set_config(dbenv, log_flags, 1) == 0); #else DB_BENCH_ASSERT(dbenv->set_flags(dbenv, log_flags, 1) == 0); #endif #ifdef DB_LOG_INMEMORY if (!(log_flags & DB_LOG_INMEMORY)) #endif #ifdef DB_LOG_IN_MEMORY if (!(log_flags & DB_LOG_IN_MEMORY)) #endif DB_BENCH_ASSERT(dbenv->set_lg_max(dbenv, logbufsize * 10) == 0); DB_BENCH_ASSERT(dbenv->set_lg_bsize(dbenv, logbufsize) == 0); DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR", DB_CREATE | DB_PRIVATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0666) == 0); DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0); DB_BENCH_ASSERT(dbp->open( dbp, NULL, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0); if (update) { (void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR); TIMER_START; for (; ops > 0; --ops) DB_BENCH_ASSERT( dbp->put(dbp, NULL, &key, &data, 0) == 0); TIMER_STOP; if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0) DB_BENCH_ASSERT(gsp->st_page_out == 0); } else { DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); (void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR); TIMER_START; for (; ops > 0; --ops) { DB_BENCH_ASSERT( dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0); DB_BENCH_ASSERT( dbp->get(dbp, NULL, &key, &data, 0) == 0); DB_BENCH_ASSERT(txn->commit(txn, 0) == 0); } TIMER_STOP; if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0) DB_BENCH_ASSERT(gsp->st_cache_miss == 0); } DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); }
int main(int argc, char **argv) { DB *dbp; DB_ENV *dbenv; DBT key, data; db_recno_t recno; DB_TXN *xid; int num_xactions; int num_inserts_per_xaction; char *string; int i, j; if (argc != 3) { printf("usage: %s <num xactions> <num inserts per xaction>\n", argv[0]); exit(-1); } num_xactions = atoi(argv[1]); num_inserts_per_xaction = atoi(argv[2]); env_dir_create(); env_open(&dbenv); rand_str_init(); if (db_open(dbenv, &dbp, DATABASE, 0)) { return (1); } memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); recno = 1; for (i = 1; i <= num_xactions; i++ ) { dbenv->txn_begin(dbenv, NULL, &xid, 0); for (j = 0; j < num_inserts_per_xaction; j++) { string = rand_str(); key.size = sizeof(recno); key.data = &recno; data.size = strlen(string) + 1; // + 1 for the null terminator data.data = string; /* if(VERBOSE) { printf("%s\n", string); } */ dbp->put(dbp, xid, &key, &data, 0); recno++; /* Its unclear from BDB docs whether we should free string */ } xid->commit(xid, 0); } return 0; }
void run_xact(DB_ENV *dbenv, DB *db, int offset, int count) { va_list ap; DBC *dbc; DBT key, data; DB_TXN *tid; int ret; char *s; /* Initialization. */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); int keyPtr; int valPtr; key.data = &keyPtr; key.size = sizeof(int);/*strlen(name);*/ data.data = &valPtr; data.size = sizeof(int); retry: /* Begin the transaction. */ if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) { dbenv->err(dbenv, ret, "DB_ENV->txn_begin"); exit (1); } /* Delete any previously existing item. */ /* switch (ret = db->del(db, tid, &key, 0)) { case 0: case DB_NOTFOUND: break; case DB_LOCK_DEADLOCK: / * Deadlock: retry the operation. * / if ((ret = tid->abort(tid)) != 0) { dbenv->err(dbenv, ret, "DB_TXN->abort"); exit (1); } goto retry; default: dbenv->err(dbenv, ret, "db->del: %s", name); exit (1); } */ /* Create a cursor. */ if ((ret = db->cursor(db, tid, &dbc, 0)) != 0) { dbenv->err(dbenv, ret, "db->cursor"); exit (1); } /* Append the items, in order. */ // va_start(ap, name); // while ((s = va_arg(ap, char *)) != NULL) { int q; for(q = offset; q < offset + count; q++) { keyPtr = q; valPtr = q; /* data.data = s; data.size = strlen(s); */ // printf("A"); fflush(NULL); switch (ret = dbc->c_put(dbc, &key, &data, DB_KEYLAST)) { case 0: // printf("B"); fflush(NULL); break; case DB_LOCK_DEADLOCK: va_end(ap); /* Deadlock: retry the operation. */ if ((ret = dbc->c_close(dbc)) != 0) { dbenv->err( dbenv, ret, "dbc->c_close"); exit (1); } if ((ret = tid->abort(tid)) != 0) { dbenv->err(dbenv, ret, "DB_TXN->abort"); exit (1); } goto retry; default: /* Error: run recovery. */ dbenv->err(dbenv, ret, "dbc->put: %d/%d", q, q); exit (1); } } va_end(ap); /* Success: commit the change. */ if ((ret = dbc->c_close(dbc)) != 0) { dbenv->err(dbenv, ret, "dbc->c_close"); exit (1); } if ((ret = tid->commit(tid, 0)) != 0) { dbenv->err(dbenv, ret, "DB_TXN->commit"); exit (1); } }
void add_cat(DB_ENV *dbenv, DB *db, char *name, ...) { va_list ap; DBC *dbc; DBT key, data; DB_TXN *tid; int ret; char *s; /* Initialization. */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = name; key.size = strlen(name); retry: /* Begin the transaction. */ if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) { dbenv->err(dbenv, ret, "DB_ENV->txn_begin"); exit (1); } /* Delete any previously existing item. */ switch (ret = db->del(db, tid, &key, 0)) { case 0: case DB_NOTFOUND: break; case DB_LOCK_DEADLOCK: /* Deadlock: retry the operation. */ if ((ret = tid->abort(tid)) != 0) { dbenv->err(dbenv, ret, "DB_TXN->abort"); exit (1); } goto retry; default: dbenv->err(dbenv, ret, "db->del: %s", name); exit (1); } /* Create a cursor. */ if ((ret = db->cursor(db, tid, &dbc, 0)) != 0) { dbenv->err(dbenv, ret, "db->cursor"); exit (1); } /* Append the items, in order. */ va_start(ap, name); while ((s = va_arg(ap, char *)) != NULL) { data.data = s; data.size = strlen(s); switch (ret = dbc->c_put(dbc, &key, &data, DB_KEYLAST)) { case 0: break; case DB_LOCK_DEADLOCK: va_end(ap); /* Deadlock: retry the operation. */ if ((ret = dbc->c_close(dbc)) != 0) { dbenv->err( dbenv, ret, "dbc->c_close"); exit (1); } if ((ret = tid->abort(tid)) != 0) { dbenv->err(dbenv, ret, "DB_TXN->abort"); exit (1); } goto retry; default: /* Error: run recovery. */ dbenv->err(dbenv, ret, "dbc->put: %s/%s", name, s); exit (1); } } va_end(ap); /* Success: commit the change. */ if ((ret = dbc->c_close(dbc)) != 0) { dbenv->err(dbenv, ret, "dbc->c_close"); exit (1); } if ((ret = tid->commit(tid, 0)) != 0) { dbenv->err(dbenv, ret, "DB_TXN->commit"); exit (1); } }