From 016a035d3acefda6ee14e5fbac215a1bd28bb98f Mon Sep 17 00:00:00 2001 From: Keith Bostic Date: Thu, 13 Sep 2012 17:00:37 +0000 Subject: 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. --- dist/s_string.ok | 1 + src/cursor/cur_file.c | 3 ++- src/cursor/cur_std.c | 25 ++++++++++++++++++++++--- src/cursor/cur_table.c | 3 ++- src/include/extern.h | 1 + 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() -- cgit v1.2.1