summaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2014-07-03 19:07:48 +1000
committerMichael Cahill <michael.cahill@wiredtiger.com>2014-07-03 19:07:48 +1000
commit6f852e4581279519802c5afbfbf8a5dfe70ab78d (patch)
treeb36e5ef773ca38757fdd1f770dd6a074f01ddd6d /api
parent55bbe6084a4aa77b0f39606234108d35b7c2af7a (diff)
downloadmongo-6f852e4581279519802c5afbfbf8a5dfe70ab78d.tar.gz
Used cached cursors for LevelDB Iterators. This gives a ~10x performance improvement in sysbench-mongodb tests.
Diffstat (limited to 'api')
-rw-r--r--api/leveldb/leveldb_wt.cc35
-rw-r--r--api/leveldb/leveldb_wt.h5
-rw-r--r--api/leveldb/rocks_wt.cc21
3 files changed, 38 insertions, 23 deletions
diff --git a/api/leveldb/leveldb_wt.cc b/api/leveldb/leveldb_wt.cc
index 3116db51329..7aa6f7aaf9f 100644
--- a/api/leveldb/leveldb_wt.cc
+++ b/api/leveldb/leveldb_wt.cc
@@ -471,16 +471,11 @@ err:
Iterator *
DbImpl::NewIterator(const ReadOptions& options)
{
+ /* Iterators own the cursor until they are closed. */
OperationContext *context = GetContext(options);
-
- /* Duplicate the normal cursor for the iterator. */
- WT_SESSION *session = context->GetSession();
WT_CURSOR *c = context->GetCursor();
- WT_CURSOR *iterc;
- /* XXX would like a fast duplicate for LSM cursors without position. */
- int ret = session->open_cursor(session, c->uri, NULL, NULL, &iterc);
- assert(ret == 0);
- return new IteratorImpl(this, iterc);
+ context->SetCursor(NULL);
+ return new IteratorImpl(this, c);
}
SnapshotImpl::SnapshotImpl(DbImpl *db) :
@@ -597,8 +592,28 @@ DbImpl::ResumeCompactions()
IteratorImpl::~IteratorImpl()
{
if (cursor_ != NULL) {
- int ret = cursor_->close(cursor_);
- assert(ret == 0);
+ OperationContext *context = db_->GetContext();
+ /*
+ * If we are in the same thread where the iterator was opened, and there is
+ * no cursor stashed there, return it.
+ */
+ if (cursor_->session == context->GetSession()) {
+#ifdef HAVE_ROCKSDB
+ if (context->GetCursor(id_) == NULL) {
+ context->SetCursor(id_, cursor_);
+ cursor_ = NULL;
+ }
+#else
+ if (context->GetCursor() == NULL) {
+ context->SetCursor(cursor_);
+ cursor_ = NULL;
+ }
+#endif
+ }
+ if (cursor_ != NULL) {
+ int ret = cursor_->close(cursor_);
+ assert(ret == 0);
+ }
}
}
diff --git a/api/leveldb/leveldb_wt.h b/api/leveldb/leveldb_wt.h
index c51ea9719a0..60390b361c7 100644
--- a/api/leveldb/leveldb_wt.h
+++ b/api/leveldb/leveldb_wt.h
@@ -135,6 +135,7 @@ public:
}
WT_CURSOR *GetCursor() { return cursor_; }
+ void SetCursor(WT_CURSOR *c) { cursor_ = c; }
#ifdef HAVE_ROCKSDB
WT_CURSOR *GetCursor(u_int i) {
return (i < cursors_.size()) ? cursors_[i] : NULL;
@@ -193,7 +194,7 @@ class ColumnFamilyHandleImpl : public ColumnFamilyHandle {
class IteratorImpl : public Iterator {
public:
- IteratorImpl(DbImpl *db, WT_CURSOR *cursor) : db_(db), cursor_(cursor), own_cursor_(true) {}
+ IteratorImpl(DbImpl *db, WT_CURSOR *cursor, uint32_t id=0) : db_(db), cursor_(cursor), id_(id) {}
virtual ~IteratorImpl();
// An iterator is either positioned at a key/value pair, or
@@ -228,7 +229,7 @@ private:
Slice key_, value_;
Status status_;
bool valid_;
- bool own_cursor_;
+ uint32_t id_;
void SetError(int wiredTigerError) {
valid_ = false;
diff --git a/api/leveldb/rocks_wt.cc b/api/leveldb/rocks_wt.cc
index 2447425851a..4d623854691 100644
--- a/api/leveldb/rocks_wt.cc
+++ b/api/leveldb/rocks_wt.cc
@@ -46,7 +46,7 @@ using leveldb::Snapshot;
using leveldb::Status;
static int
-wtrocks_get_cursor(OperationContext *context, ColumnFamilyHandle *cfhp, WT_CURSOR **cursorp)
+wtrocks_get_cursor(OperationContext *context, ColumnFamilyHandle *cfhp, WT_CURSOR **cursorp, int acquire=0)
{
ColumnFamilyHandleImpl *cf =
static_cast<ColumnFamilyHandleImpl *>(cfhp);
@@ -63,8 +63,10 @@ wtrocks_get_cursor(OperationContext *context, ColumnFamilyHandle *cfhp, WT_CURSO
fprintf(stderr, "Failed to open cursor on %s: %s\n", cf->GetURI().c_str(), wiredtiger_strerror(ret));
return (ret);
}
- context->SetCursor(cf->GetID(), c);
- }
+ if (!acquire)
+ context->SetCursor(cf->GetID(), c);
+ } else if (acquire)
+ context->SetCursor(cf->GetID(), NULL);
*cursorp = c;
return (0);
}
@@ -277,15 +279,12 @@ DbImpl::NewIterator(ReadOptions const &options, ColumnFamilyHandle *cfhp)
{
OperationContext *context = GetContext(options);
- /* Duplicate the normal cursor for the iterator. */
WT_SESSION *session = context->GetSession();
- WT_CURSOR *c, *iterc;
- int ret = wtrocks_get_cursor(context, cfhp, &c);
- assert(ret == 0);
- /* XXX would like a fast duplicate for LSM cursors without position. */
- ret = session->open_cursor(session, c->uri, NULL, NULL, &iterc);
+ WT_CURSOR *c;
+ int ret = wtrocks_get_cursor(context, cfhp, &c, 1);
assert(ret == 0);
- return new IteratorImpl(this, iterc);
+ return new IteratorImpl(this, c,
+ static_cast<ColumnFamilyHandleImpl *>(cfhp)->GetID());
}
Status
@@ -295,8 +294,8 @@ DbImpl::Put(WriteOptions const &options, ColumnFamilyHandle *cfhp, Slice const &
int ret = wtrocks_get_cursor(GetContext(), cfhp, &cursor);
if (ret != 0)
return WiredTigerErrorToStatus(ret);
- WT_ITEM item;
+ WT_ITEM item;
item.data = key.data();
item.size = key.size();
cursor->set_key(cursor, &item);