aboutsummaryrefslogtreecommitdiff
path: root/transaction.go
diff options
context:
space:
mode:
authorBen Johnson <benbjohnson@yahoo.com>2014-01-24 16:32:18 -0700
committerBen Johnson <benbjohnson@yahoo.com>2014-01-24 16:32:18 -0700
commit73ab1d420dedd965ebe6f814dcf016c8e10879f2 (patch)
tree2a025e8e8daeaba34953c6b92b83bd579c83962b /transaction.go
parentTODO (diff)
downloaddedo-73ab1d420dedd965ebe6f814dcf016c8e10879f2.tar.gz
dedo-73ab1d420dedd965ebe6f814dcf016c8e10879f2.tar.xz
TODO
Diffstat (limited to 'transaction.go')
-rw-r--r--transaction.go164
1 files changed, 3 insertions, 161 deletions
diff --git a/transaction.go b/transaction.go
index 6319b9e..b79f3e7 100644
--- a/transaction.go
+++ b/transaction.go
@@ -6,7 +6,7 @@ import (
)
var (
- InvalidTransactionError = &Error{"txn is invalid", nil}
+ InvalidTransactionError = &Error{"txn is invalid", nil}
BucketAlreadyExistsError = &Error{"bucket already exists", nil}
)
@@ -17,6 +17,8 @@ const (
ps_last = 8
)
+type txnid uint64
+
type Transaction struct {
id int
db *DB
@@ -158,166 +160,6 @@ func (t *Transaction) Stat(name string) *stat {
// //
// //
-
-// Save the freelist as of this transaction to the freeDB.
-// This changes the freelist. Keep trying until it stabilizes.
-func (t *Transaction) saveFreelist() error {
- /*
- // env->me_pghead[] can grow and shrink during this call.
- // env->me_pglast and txn->mt_free_pgs[] can only grow.
- // Page numbers cannot disappear from txn->mt_free_pgs[].
- MDB_cursor mc;
- MDB_env *env = txn->mt_env;
- int rc, maxfree_1pg = env->me_maxfree_1pg, more = 1;
- txnid_t pglast = 0, head_id = 0;
- pgno_t freecnt = 0, *free_pgs, *mop;
- ssize_t head_room = 0, total_room = 0, mop_len, clean_limit;
-
- mdb_cursor_init(&mc, txn, FREE_DBI, NULL);
-
- if (env->me_pghead) {
- // Make sure first page of freeDB is touched and on freelist
- rc = mdb_page_search(&mc, NULL, MDB_PS_FIRST|MDB_PS_MODIFY);
- if (rc && rc != MDB_NOTFOUND)
- return rc;
- }
-
- // MDB_RESERVE cancels meminit in ovpage malloc (when no WRITEMAP)
- clean_limit = (env->me_flags & (MDB_NOMEMINIT|MDB_WRITEMAP))
- ? SSIZE_MAX : maxfree_1pg;
-
- for (;;) {
- // Come back here after each Put() in case freelist changed
- MDB_val key, data;
- pgno_t *pgs;
- ssize_t j;
-
- // If using records from freeDB which we have not yet
- // deleted, delete them and any we reserved for me_pghead.
- while (pglast < env->me_pglast) {
- rc = mdb_cursor_first(&mc, &key, NULL);
- if (rc)
- return rc;
- pglast = head_id = *(txnid_t *)key.mv_data;
- total_room = head_room = 0;
- mdb_tassert(txn, pglast <= env->me_pglast);
- rc = mdb_cursor_del(&mc, 0);
- if (rc)
- return rc;
- }
-
- // Save the IDL of pages freed by this txn, to a single record
- if (freecnt < txn->mt_free_pgs[0]) {
- if (!freecnt) {
- // Make sure last page of freeDB is touched and on freelist
- rc = mdb_page_search(&mc, NULL, MDB_PS_LAST|MDB_PS_MODIFY);
- if (rc && rc != MDB_NOTFOUND)
- return rc;
- }
- free_pgs = txn->mt_free_pgs;
- // Write to last page of freeDB
- key.mv_size = sizeof(txn->mt_txnid);
- key.mv_data = &txn->mt_txnid;
- do {
- freecnt = free_pgs[0];
- data.mv_size = MDB_IDL_SIZEOF(free_pgs);
- rc = mdb_cursor_put(&mc, &key, &data, MDB_RESERVE);
- if (rc)
- return rc;
- // Retry if mt_free_pgs[] grew during the Put()
- free_pgs = txn->mt_free_pgs;
- } while (freecnt < free_pgs[0]);
- mdb_midl_sort(free_pgs);
- memcpy(data.mv_data, free_pgs, data.mv_size);
- #if (MDB_DEBUG) > 1
- {
- unsigned int i = free_pgs[0];
- DPRINTF(("IDL write txn %"Z"u root %"Z"u num %u",
- txn->mt_txnid, txn->mt_dbs[FREE_DBI].md_root, i));
- for (; i; i--)
- DPRINTF(("IDL %"Z"u", free_pgs[i]));
- }
- #endif
- continue;
- }
-
- mop = env->me_pghead;
- mop_len = mop ? mop[0] : 0;
-
- // Reserve records for me_pghead[]. Split it if multi-page,
- // to avoid searching freeDB for a page range. Use keys in
- // range [1,me_pglast]: Smaller than txnid of oldest reader.
- if (total_room >= mop_len) {
- if (total_room == mop_len || --more < 0)
- break;
- } else if (head_room >= maxfree_1pg && head_id > 1) {
- // Keep current record (overflow page), add a new one
- head_id--;
- head_room = 0;
- }
- // (Re)write {key = head_id, IDL length = head_room}
- total_room -= head_room;
- head_room = mop_len - total_room;
- if (head_room > maxfree_1pg && head_id > 1) {
- // Overflow multi-page for part of me_pghead
- head_room /= head_id; // amortize page sizes
- head_room += maxfree_1pg - head_room % (maxfree_1pg + 1);
- } else if (head_room < 0) {
- // Rare case, not bothering to delete this record
- head_room = 0;
- }
- key.mv_size = sizeof(head_id);
- key.mv_data = &head_id;
- data.mv_size = (head_room + 1) * sizeof(pgno_t);
- rc = mdb_cursor_put(&mc, &key, &data, MDB_RESERVE);
- if (rc)
- return rc;
- // IDL is initially empty, zero out at least the length
- pgs = (pgno_t *)data.mv_data;
- j = head_room > clean_limit ? head_room : 0;
- do {
- pgs[j] = 0;
- } while (--j >= 0);
- total_room += head_room;
- }
-
- // Fill in the reserved me_pghead records
- rc = MDB_SUCCESS;
- if (mop_len) {
- MDB_val key, data;
-
- mop += mop_len;
- rc = mdb_cursor_first(&mc, &key, &data);
- for (; !rc; rc = mdb_cursor_next(&mc, &key, &data, MDB_NEXT)) {
- unsigned flags = MDB_CURRENT;
- txnid_t id = *(txnid_t *)key.mv_data;
- ssize_t len = (ssize_t)(data.mv_size / sizeof(MDB_ID)) - 1;
- MDB_ID save;
-
- mdb_tassert(txn, len >= 0 && id <= env->me_pglast);
- key.mv_data = &id;
- if (len > mop_len) {
- len = mop_len;
- data.mv_size = (len + 1) * sizeof(MDB_ID);
- flags = 0;
- }
- data.mv_data = mop -= len;
- save = mop[0];
- mop[0] = len;
- rc = mdb_cursor_put(&mc, &key, &data, flags);
- mop[0] = save;
- if (rc || !(mop_len -= len))
- break;
- }
- }
- return rc;
- */
- return nil
-}
-
-
-
-
// Return the data associated with a given node.
// @param[in] txn The transaction for this operation.
// @param[in] leaf The node being read.