summaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
authorAlex Gorrod <alexg@wiredtiger.com>2014-06-16 15:27:31 +1000
committerAlex Gorrod <alexg@wiredtiger.com>2014-06-16 15:27:31 +1000
commit3a9a3d5bc2e5a04d937f239971e62d7c21952b61 (patch)
treed0f5732f113bd3b7443dcc4d016fb1e64f7e1cef /api
parentf39460960701380e4629bfb46f3c3b79e006089e (diff)
downloadmongo-3a9a3d5bc2e5a04d937f239971e62d7c21952b61.tar.gz
Make read snapshots work as expected in LevelDB API.
Always use snapshot isolation level in LevelDB API.
Diffstat (limited to 'api')
-rw-r--r--api/leveldb/leveldb_wt.cc51
1 files changed, 44 insertions, 7 deletions
diff --git a/api/leveldb/leveldb_wt.cc b/api/leveldb/leveldb_wt.cc
index 8fe820c3955..189d5e4089e 100644
--- a/api/leveldb/leveldb_wt.cc
+++ b/api/leveldb/leveldb_wt.cc
@@ -225,7 +225,7 @@ class DbImpl;
class OperationContext {
public:
OperationContext(WT_CONNECTION *conn) {
- int ret = conn->open_session(conn, NULL, NULL, &session_);
+ int ret = conn->open_session(conn, NULL, "isolation=snapshot", &session_);
assert(ret == 0);
ret = session_->open_cursor(
session_, WT_URI, NULL, NULL, &cursor_);
@@ -296,12 +296,19 @@ private:
};
class SnapshotImpl : public Snapshot {
+friend class DbImpl;
public:
- SnapshotImpl(DbImpl *db) : Snapshot() {}
+ SnapshotImpl(DbImpl *db) : Snapshot(), db_(db) {}
virtual ~SnapshotImpl() {}
+protected:
+ Status setupTransaction();
+ Status releaseTransaction();
+private:
+ DbImpl *db_;
};
class DbImpl : public leveldb::DB {
+friend class SnapshotImpl;
public:
DbImpl(WT_CONNECTION *conn) :
DB(), conn_(conn), context_(new ThreadLocal<OperationContext>) {}
@@ -365,12 +372,13 @@ private:
return (ctx);
}
- WT_SESSION *getSession() { return getContext()->getSession(); }
- WT_CURSOR *getCursor() { return getContext()->getCursor(); }
-
// No copying allowed
DbImpl(const DbImpl&);
void operator=(const DbImpl&);
+
+protected:
+ WT_SESSION *getSession() { return getContext()->getSession(); }
+ WT_CURSOR *getCursor() { return getContext()->getCursor(); }
};
Status
@@ -600,7 +608,14 @@ DbImpl::NewIterator(const ReadOptions& options)
const Snapshot *
DbImpl::GetSnapshot()
{
- return new SnapshotImpl(this);
+ SnapshotImpl *snapshot = new SnapshotImpl(this);
+ Status status = snapshot->setupTransaction();
+ if (!status.ok()) {
+ delete snapshot;
+ // TODO: Flag an error here?
+ return NULL;
+ }
+ return snapshot;
}
// Release a previously acquired snapshot. The caller must not
@@ -608,7 +623,12 @@ DbImpl::GetSnapshot()
void
DbImpl::ReleaseSnapshot(const Snapshot* snapshot)
{
- delete (SnapshotImpl *)snapshot;
+ SnapshotImpl *si =
+ static_cast<SnapshotImpl *>(const_cast<Snapshot *>(snapshot));
+ if (si != NULL) {
+ si->releaseTransaction();
+ delete si;
+ }
}
// DB implementations can export properties about their state
@@ -864,3 +884,20 @@ IteratorImpl::Prev()
value_ = Slice((const char *)item.data, item.size);
valid_ = true;
}
+
+// Implementation for WiredTiger specific read snapshot
+Status SnapshotImpl::setupTransaction()
+{
+ WT_SESSION * session = db_->getSession();
+ session->begin_transaction(session, NULL);
+ return Status::OK();
+}
+
+Status SnapshotImpl::releaseTransaction()
+{
+ WT_SESSION * session = db_->getSession();
+ // In LevelDB Snapshots are read only objects - roll back the transaction,
+ // it has a slightly lower cost.
+ session->rollback_transaction(session, NULL);
+ return Status::OK();
+}