diff options
author | Keith Bostic <keith@wiredtiger.com> | 2012-09-13 17:00:37 +0000 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2012-09-13 17:00:37 +0000 |
commit | 016a035d3acefda6ee14e5fbac215a1bd28bb98f (patch) | |
tree | b982c45b717d3e362e25744f3931fc7cb7261d6b | |
parent | 66762a6c83d0fbf969f3d5071ad478ef8f38ae70 (diff) | |
download | mongo-016a035d3acefda6ee14e5fbac215a1bd28bb98f.tar.gz |
Having a next-random cursor open could block transactions or checkpoints
because the cursor.reset method failed with not-supported. Two fixes:
explicitly change next-random cursors to call the underlying reset method,
they're btree handles so it makes sense for them. Additionally, make the
default cursor.reset method be a no-op rather than a not-supported error,
bulk cursors don't want to block transactions/checkpoints either.
-rw-r--r-- | dist/s_string.ok | 1 | ||||
-rw-r--r-- | src/cursor/cur_file.c | 3 | ||||
-rw-r--r-- | src/cursor/cur_std.c | 25 | ||||
-rw-r--r-- | src/cursor/cur_table.c | 3 | ||||
-rw-r--r-- | src/include/extern.h | 1 | ||||
-rw-r--r-- | test/suite/test_cursor_random.py | 4 |
6 files changed, 30 insertions, 7 deletions
diff --git a/dist/s_string.ok b/dist/s_string.ok index 97661ce02d9..678f31e7b1b 100644 --- a/dist/s_string.ok +++ b/dist/s_string.ok @@ -501,6 +501,7 @@ nhex nl nlpo nocase +noop nop notfound notset diff --git a/src/cursor/cur_file.c b/src/cursor/cur_file.c index 988dfcf12b0..05ff4b24e39 100644 --- a/src/cursor/cur_file.c +++ b/src/cursor/cur_file.c @@ -338,12 +338,13 @@ __wt_curfile_create(WT_SESSION_IMPL *session, /* * random_retrieval - * Random retrieval cursors only support next and close. + * Random retrieval cursors only support next, reset and close. */ WT_ERR(__wt_config_gets_defno(session, cfg, "next_random", &cval)); if (cval.val != 0) { __wt_cursor_set_notsup(cursor); cursor->next = __curfile_next_random; + cursor->reset = __curfile_reset; } /* __wt_cursor_init is last so we don't have to clean up on error. */ diff --git a/src/cursor/cur_std.c b/src/cursor/cur_std.c index 2f571625432..fd9422ed5c3 100644 --- a/src/cursor/cur_std.c +++ b/src/cursor/cur_std.c @@ -19,18 +19,37 @@ __wt_cursor_notsup(WT_CURSOR *cursor) return (ENOTSUP); } +/* + * __wt_cursor_noop -- + * Cursor noop. + */ +int +__wt_cursor_noop(WT_CURSOR *cursor) +{ + WT_UNUSED(cursor); + + return (0); +} + /* * __wt_cursor_set_notsup -- - * Set all of the cursor methods (except for close), to not-supported. + * Reset the cursor methods to not-supported. */ void __wt_cursor_set_notsup(WT_CURSOR *cursor) { + /* + * Set all of the cursor methods (except for close and reset), to fail. + * Close is unchanged so the cursor can be discarded, reset defaults to + * a no-op because session transactional operations reset all of the + * cursors in a session, and random cursors shouldn't block transactions + * or checkpoints. + */ cursor->compare = (int (*)(WT_CURSOR *, WT_CURSOR *, int *))__wt_cursor_notsup; cursor->next = __wt_cursor_notsup; cursor->prev = __wt_cursor_notsup; - cursor->reset = __wt_cursor_notsup; + cursor->reset = __wt_cursor_noop; cursor->search = __wt_cursor_notsup; cursor->search_near = (int (*)(WT_CURSOR *, int *))__wt_cursor_notsup; cursor->insert = __wt_cursor_notsup; @@ -458,7 +477,7 @@ __wt_cursor_init(WT_CURSOR *cursor, if (cursor->prev == NULL) cursor->prev = __wt_cursor_notsup; if (cursor->reset == NULL) - cursor->reset = __wt_cursor_notsup; + cursor->reset = __wt_cursor_noop; if (cursor->search == NULL) cursor->search = __cursor_search; if (cursor->search_near == NULL) diff --git a/src/cursor/cur_table.c b/src/cursor/cur_table.c index 61c68246a4e..85024e5ce95 100644 --- a/src/cursor/cur_table.c +++ b/src/cursor/cur_table.c @@ -783,12 +783,13 @@ __wt_curtable_open(WT_SESSION_IMPL *session, /* * random_retrieval - * Random retrieval cursors only support next and close. + * Random retrieval cursors only support next, reset and close. */ WT_ERR(__wt_config_gets_defno(session, cfg, "next_random", &cval)); if (cval.val != 0) { __wt_cursor_set_notsup(cursor); cursor->next = __curtable_next_random; + cursor->reset = __curtable_reset; } STATIC_ASSERT(offsetof(WT_CURSOR_TABLE, iface) == 0); diff --git a/src/include/extern.h b/src/include/extern.h index 3d8c663ee9e..ea1cb091fe7 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -617,6 +617,7 @@ extern int __wt_curstat_open(WT_SESSION_IMPL *session, const char *cfg[], WT_CURSOR **cursorp); extern int __wt_cursor_notsup(WT_CURSOR *cursor); +extern int __wt_cursor_noop(WT_CURSOR *cursor); extern void __wt_cursor_set_notsup(WT_CURSOR *cursor); extern int __wt_cursor_kv_not_set(WT_CURSOR *cursor, int key); extern int __wt_cursor_get_key(WT_CURSOR *cursor, ...); diff --git a/test/suite/test_cursor_random.py b/test/suite/test_cursor_random.py index 073a114344d..63c4d2a04b9 100644 --- a/test/suite/test_cursor_random.py +++ b/test/suite/test_cursor_random.py @@ -37,7 +37,7 @@ class test_cursor_random(wttest.WiredTigerTestCase): ] # Check that opening a random cursor on a row-store returns not-supported - # for every method except for next, and next returns not-found. + # for every method except for next and reset, and next returns not-found. def test_cursor_random_column(self): uri = self.type + 'random' self.session.create(uri, 'key_format=' + self.fmt + ',value_format=S') @@ -45,7 +45,6 @@ class test_cursor_random(wttest.WiredTigerTestCase): self.assertRaises( wiredtiger.WiredTigerError, lambda: cursor.compare(cursor)) self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.prev()) - self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.reset()) self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.search()) self.assertRaises( wiredtiger.WiredTigerError, lambda: cursor.search_near()) @@ -53,6 +52,7 @@ class test_cursor_random(wttest.WiredTigerTestCase): self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.update()) self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.remove()) + cursor.reset() self.assertTrue(cursor.next(), wiredtiger.WT_NOTFOUND) cursor.close() |