Update of /project/elephant/cvsroot/elephant/src In directory common-lisp.net:/tmp/cvs-serv22122/src
Modified Files: libsleepycat.c Log Message: poor man's counters
Date: Sat Aug 28 08:40:33 2004 Author: blee
Index: elephant/src/libsleepycat.c diff -u elephant/src/libsleepycat.c:1.3 elephant/src/libsleepycat.c:1.4 --- elephant/src/libsleepycat.c:1.3 Fri Aug 27 19:32:44 2004 +++ elephant/src/libsleepycat.c Sat Aug 28 08:40:33 2004 @@ -368,6 +368,26 @@ return env->lock_id_free(env, id); }
+int db_env_lock_get(DB_ENV *env, u_int32_t locker, + u_int32_t flags, char *object, u_int32_t object_length, + const db_lockmode_t lock_mode, DB_LOCK *lock) { + DBT DBTObject; + memset(&DBTObject, 0, sizeof(DBT)); + DBTObject.data = object; + DBTObject.size = object_length; + + return env->lock_get(env, locker, flags, &DBTObject, lock_mode, lock); +} + +int db_env_lock_put(DB_ENV *env, DB_LOCK *lock) { + return env->lock_put(env, lock); +} + +int db_env_lock_vec(DB_ENV *env, u_int32_t locker, u_int32_t flags, + DB_LOCKREQ list[], int nlist, DB_LOCKREQ **elistp) { + return env->lock_vec(env, locker, flags, list, nlist, elistp); +} + /* db_timeout_t = u_int32_t */ int db_env_set_timeout(DB_ENV *env, db_timeout_t timeout, u_int32_t flags) { return env->set_timeout(env, timeout, flags); @@ -390,3 +410,72 @@ return env->lock_detect(env, flags, atype, aborted); }
+/* Poor man's counters */ + +int next_counter(DB_ENV *env, DB *db, char *key, u_int32_t key_length, + char *lockid, u_int32_t lockid_length) { + DB_LOCK lock; + DBT DBTKey, DBTData; + DB_TXN *tid; + int counter, tries, ret, t_ret; + u_int32_t id; + + /* Initialization. */ + memset(&lock, 0, sizeof(lock)); + memset(&DBTKey, 0, sizeof(DBTKey)); + memset(&DBTData, 0, sizeof(DBTData)); + DBTKey.data = key; + DBTKey.size = key_length; + DBTData.data = lockid; + DBTData.size = lockid_length; + tries = 0; + + loop: + /* Begin the transaction. */ + if ((ret = env->txn_begin(env, NULL, &tid, 0)) != 0) { + env->err(env, ret, "DB_ENV->txn_begin"); + return (-1); + } + + id = tid->id(tid); + + if ((ret = env->lock_get(env, id, 0, &DBTData, DB_LOCK_WRITE, &lock)) != 0) + goto fail; + + memset(&DBTData, 0, sizeof(DBTData)); + DBTData.data = &counter; + DBTData.ulen = sizeof(counter); + DBTData.flags |= DB_DBT_USERMEM; + + if ((ret = db->get(db, tid, &DBTKey, &DBTData, 0)) != 0) + goto fail; + + ++counter; + + memset(&DBTData, 0, sizeof(DBTData)); + DBTData.data = &counter; + DBTData.size = sizeof(counter); + + if ((ret = db->put(db, tid, &DBTKey, &DBTData, 0)) != 0) + goto fail; + + if ((ret = env->lock_put(env, &lock)) != 0) + goto fail; + + if ((ret = tid->commit(tid, 0)) != 0) { + env->err(env, ret, "DB_TXN->commit"); + return (-2); + } + return (counter); + + + fail: + /* Abort and retry the operation. */ + if ((t_ret = tid->abort(tid)) != 0) { + env->err(env, t_ret, "DB_TXN->abort"); + return (-3); + } + if (tries++ == 100) + return (-4); + goto loop; +}