diff options
Diffstat (limited to 'api')
-rw-r--r-- | api/leveldb/leveldb_wt.cc | 35 | ||||
-rw-r--r-- | api/leveldb/leveldb_wt.h | 5 | ||||
-rw-r--r-- | api/leveldb/rocks_wt.cc | 21 |
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); |