summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2012-09-13 17:00:37 +0000
committerKeith Bostic <keith@wiredtiger.com>2012-09-13 17:00:37 +0000
commit016a035d3acefda6ee14e5fbac215a1bd28bb98f (patch)
treeb982c45b717d3e362e25744f3931fc7cb7261d6b
parent66762a6c83d0fbf969f3d5071ad478ef8f38ae70 (diff)
downloadmongo-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.ok1
-rw-r--r--src/cursor/cur_file.c3
-rw-r--r--src/cursor/cur_std.c25
-rw-r--r--src/cursor/cur_table.c3
-rw-r--r--src/include/extern.h1
-rw-r--r--test/suite/test_cursor_random.py4
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()