summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dist/s_string.ok1
-rw-r--r--examples/c/ex_all.c13
-rw-r--r--examples/java/com/wiredtiger/examples/ex_all.java13
-rw-r--r--lang/python/wiredtiger.i36
-rw-r--r--src/btree/bt_cursor.c49
-rw-r--r--src/cursor/cur_backup.c1
-rw-r--r--src/cursor/cur_config.c1
-rw-r--r--src/cursor/cur_ds.c1
-rw-r--r--src/cursor/cur_dump.c1
-rw-r--r--src/cursor/cur_file.c40
-rw-r--r--src/cursor/cur_index.c1
-rw-r--r--src/cursor/cur_log.c1
-rw-r--r--src/cursor/cur_metadata.c1
-rw-r--r--src/cursor/cur_stat.c1
-rw-r--r--src/cursor/cur_table.c58
-rw-r--r--src/include/cursor.h2
-rw-r--r--src/include/extern.h1
-rw-r--r--src/include/wiredtiger.in19
-rw-r--r--src/lsm/lsm_cursor.c1
-rw-r--r--test/suite/test_cursor_compare.py115
20 files changed, 305 insertions, 51 deletions
diff --git a/dist/s_string.ok b/dist/s_string.ok
index d3717d27331..956b4061c62 100644
--- a/dist/s_string.ok
+++ b/dist/s_string.ok
@@ -581,6 +581,7 @@ enum's
env
eof
eop
+equalityp
errhandler
errno
errv
diff --git a/examples/c/ex_all.c b/examples/c/ex_all.c
index 31ad812e6f6..6fe5296ea58 100644
--- a/examples/c/ex_all.c
+++ b/examples/c/ex_all.c
@@ -242,6 +242,19 @@ cursor_ops(WT_SESSION *session)
}
{
+ WT_CURSOR *other = NULL;
+ /*! [Cursor equality] */
+ int equal;
+ ret = cursor->compare_equal(cursor, other, &equal);
+ if (equal == 0) {
+ /* Cursors reference the same key */
+ } else {
+ /* Cursors don't reference the same key */
+ }
+ /*! [Cursor equality] */
+ }
+
+ {
/*! [Search for an exact match] */
const char *key = "some key";
cursor->set_key(cursor, key);
diff --git a/examples/java/com/wiredtiger/examples/ex_all.java b/examples/java/com/wiredtiger/examples/ex_all.java
index 4c30b893e06..5b1b0f58efa 100644
--- a/examples/java/com/wiredtiger/examples/ex_all.java
+++ b/examples/java/com/wiredtiger/examples/ex_all.java
@@ -215,6 +215,19 @@ public static int cursor_ops(Session session)
}
{
+ Cursor other = null;
+ /*! [Cursor equality] */
+ int equal;
+ equal = cursor.compare_equal(other);
+ if (equal == 0) {
+ /* Cursors reference the same key */
+ } else {
+ /* Cursors don't reference the same key */
+ }
+ /*! [Cursor equality] */
+ }
+
+ {
/*! [Search for an exact match] */
String key = "some key";
cursor.putKeyString(key);
diff --git a/lang/python/wiredtiger.i b/lang/python/wiredtiger.i
index 8eb1c59ee1e..f4a2801ed4c 100644
--- a/lang/python/wiredtiger.i
+++ b/lang/python/wiredtiger.i
@@ -381,6 +381,7 @@ NOTFOUND_OK(__wt_cursor::search)
NOTFOUND_OK(__wt_cursor::update)
COMPARE_OK(__wt_cursor::compare)
+COMPARE_OK(__wt_cursor::compare_equal)
COMPARE_OK(__wt_cursor::search_near)
/* Lastly, some methods need no (additional) error checking. */
@@ -415,6 +416,7 @@ COMPARE_OK(__wt_cursor::search_near)
/* Next, override methods that return integers via arguments. */
%ignore __wt_cursor::compare(WT_CURSOR *, WT_CURSOR *, int *);
+%ignore __wt_cursor::compare_equal(WT_CURSOR *, WT_CURSOR *, int *);
%ignore __wt_cursor::search_near(WT_CURSOR *, int *);
/* SWIG magic to turn Python byte strings into data / size. */
@@ -673,7 +675,7 @@ typedef int int_void;
return (ret);
}
- /* compare and search_near need special handling. */
+ /* compare: special handling. */
int compare(WT_CURSOR *other) {
int cmp = 0;
int ret = 0;
@@ -691,12 +693,37 @@ typedef int int_void;
* Map less-than-zero to -1 and greater-than-zero to 1
* to avoid colliding with other errors.
*/
- ret = ((ret != 0) ? ret :
- (cmp < 0) ? -1 : (cmp == 0) ? 0 : 1);
+ ret = (ret != 0) ? ret :
+ ((cmp < 0) ? -1 : (cmp == 0) ? 0 : 1);
}
return (ret);
}
+ /* compare_equal: special handling. */
+ int compare_equal(WT_CURSOR *other) {
+ int cmp = 0;
+ int ret = 0;
+ if (other == NULL) {
+ SWIG_Error(SWIG_NullReferenceError,
+ "in method 'Cursor_compare_equal', "
+ "argument 1 of type 'struct __wt_cursor *' "
+ "is None");
+ ret = EINVAL; /* any non-zero value will do. */
+ }
+ else {
+ ret = $self->compare_equal($self, other, &cmp);
+
+ /*
+ * Compare-equal is documented to return 0 and !0, map
+ * less-than-zero and greater-than-zero to 1 to avoid
+ * colliding with other errors.
+ */
+ ret = (ret != 0) ? ret : (cmp == 0 ? 0 : 1);
+ }
+ return (ret);
+ }
+
+ /* search_near: special handling. */
int search_near() {
int cmp = 0;
int ret = $self->search_near($self, &cmp);
@@ -704,8 +731,7 @@ typedef int int_void;
* Map less-than-zero to -1 and greater-than-zero to 1 to avoid
* colliding with WT_NOTFOUND.
*/
- return ((ret != 0) ? ret :
- (cmp < 0) ? -1 : (cmp == 0) ? 0 : 1);
+ return ((ret != 0) ? ret : (cmp < 0) ? -1 : (cmp == 0) ? 0 : 1);
}
int _freecb() {
diff --git a/src/btree/bt_cursor.c b/src/btree/bt_cursor.c
index 4aee1883ae0..71bdd0dc7c5 100644
--- a/src/btree/bt_cursor.c
+++ b/src/btree/bt_cursor.c
@@ -800,16 +800,19 @@ err: if (ret != 0)
int
__wt_btcur_compare(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp)
{
- WT_BTREE *btree;
WT_CURSOR *a, *b;
WT_SESSION_IMPL *session;
a = (WT_CURSOR *)a_arg;
b = (WT_CURSOR *)b_arg;
- btree = a_arg->btree;
session = (WT_SESSION_IMPL *)a->session;
- switch (btree->type) {
+ /* Confirm both cursors reference the same object. */
+ if (a_arg->btree != b_arg->btree)
+ WT_RET_MSG(
+ session, EINVAL, "Cursors must reference the same object");
+
+ switch (a_arg->btree->type) {
case BTREE_COL_FIX:
case BTREE_COL_VAR:
/*
@@ -826,7 +829,7 @@ __wt_btcur_compare(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp)
break;
case BTREE_ROW:
WT_RET(__wt_compare(
- session, btree->collator, &a->key, &b->key, cmpp));
+ session, a_arg->btree->collator, &a->key, &b->key, cmpp));
break;
WT_ILLEGAL_VALUE(session);
}
@@ -837,7 +840,7 @@ __wt_btcur_compare(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp)
* __cursor_equals --
* Return if two cursors reference the same row.
*/
-static int
+static inline int
__cursor_equals(WT_CURSOR_BTREE *a, WT_CURSOR_BTREE *b)
{
switch (a->btree->type) {
@@ -867,6 +870,42 @@ __cursor_equals(WT_CURSOR_BTREE *a, WT_CURSOR_BTREE *b)
}
/*
+ * __wt_btcur_compare_equal --
+ * Return an equality comparison between two cursors.
+ */
+int
+__wt_btcur_compare_equal(
+ WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp)
+{
+ WT_CURSOR *a, *b;
+ WT_SESSION_IMPL *session;
+
+ a = (WT_CURSOR *)a_arg;
+ b = (WT_CURSOR *)b_arg;
+ session = (WT_SESSION_IMPL *)a->session;
+
+ /* Confirm both cursors reference the same object. */
+ if (a_arg->btree != b_arg->btree)
+ WT_RET_MSG(
+ session, EINVAL, "Cursors must reference the same object");
+
+ /*
+ * The reason for a compare-equal method is because we can avoid doing
+ * a full key comparison in some cases. If both cursors point into the
+ * tree, take the fast path, otherwise fall back to the slower compare
+ * method.
+ */
+ if (F_ISSET(a, WT_CURSTD_KEY_INT) && F_ISSET(b, WT_CURSTD_KEY_INT))
+ *cmpp = !__cursor_equals(a_arg, b_arg);
+ else {
+ WT_RET(__wt_btcur_compare(a_arg, b_arg, cmpp));
+ if (*cmpp != 0)
+ *cmpp = 1;
+ }
+ return (0);
+}
+
+/*
* __cursor_truncate --
* Discard a cursor range from row-store or variable-width column-store
* tree.
diff --git a/src/cursor/cur_backup.c b/src/cursor/cur_backup.c
index 3c4c5322534..2ef6f8e9274 100644
--- a/src/cursor/cur_backup.c
+++ b/src/cursor/cur_backup.c
@@ -109,6 +109,7 @@ __wt_curbackup_open(WT_SESSION_IMPL *session,
__wt_cursor_notsup, /* set-key */
__wt_cursor_notsup, /* set-value */
__wt_cursor_notsup, /* compare */
+ __wt_cursor_notsup, /* compare_equal */
__curbackup_next, /* next */
__wt_cursor_notsup, /* prev */
__curbackup_reset, /* reset */
diff --git a/src/cursor/cur_config.c b/src/cursor/cur_config.c
index f011f6db126..38f3fc159b5 100644
--- a/src/cursor/cur_config.c
+++ b/src/cursor/cur_config.c
@@ -32,6 +32,7 @@ __wt_curconfig_open(WT_SESSION_IMPL *session,
__wt_cursor_set_key, /* set-key */
__wt_cursor_set_value, /* set-value */
__wt_cursor_notsup, /* compare */
+ __wt_cursor_notsup, /* compare_equal */
__wt_cursor_notsup, /* next */
__wt_cursor_notsup, /* prev */
__wt_cursor_noop, /* reset */
diff --git a/src/cursor/cur_ds.c b/src/cursor/cur_ds.c
index c8b8f6c4547..ef8d1725a28 100644
--- a/src/cursor/cur_ds.c
+++ b/src/cursor/cur_ds.c
@@ -454,6 +454,7 @@ __wt_curds_open(
__wt_cursor_set_key, /* set-key */
__wt_cursor_set_value, /* set-value */
__curds_compare, /* compare */
+ __curds_compare, /* compare_equal */
__curds_next, /* next */
__curds_prev, /* prev */
__curds_reset, /* reset */
diff --git a/src/cursor/cur_dump.c b/src/cursor/cur_dump.c
index 2be1d91f0f3..ac3bc0cf5d2 100644
--- a/src/cursor/cur_dump.c
+++ b/src/cursor/cur_dump.c
@@ -352,6 +352,7 @@ __wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp)
__curdump_set_key, /* set-key */
__curdump_set_value, /* set-value */
__wt_cursor_notsup, /* compare */
+ __wt_cursor_notsup, /* compare_equal */
__curdump_next, /* next */
__curdump_prev, /* prev */
__curdump_reset, /* reset */
diff --git a/src/cursor/cur_file.c b/src/cursor/cur_file.c
index 10d1151c30c..fbedfe6d032 100644
--- a/src/cursor/cur_file.c
+++ b/src/cursor/cur_file.c
@@ -46,10 +46,11 @@ __curfile_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp)
CURSOR_API_CALL(a, session, compare, cbt->btree);
/*
- * Confirm both cursors refer to the same source and have keys, then
- * call the underlying object to compare them.
+ * Check both cursors are a "file:" type then call the underlying
+ * function, it can handle cursors pointing to different objects.
*/
- if (strcmp(a->internal_uri, b->internal_uri) != 0)
+ if (!WT_PREFIX_MATCH(a->internal_uri, "file:") ||
+ !WT_PREFIX_MATCH(b->internal_uri, "file:"))
WT_ERR_MSG(session, EINVAL,
"Cursors must reference the same object");
@@ -63,6 +64,38 @@ err: API_END_RET(session, ret);
}
/*
+ * __curfile_compare_equal --
+ * WT_CURSOR->compare_equal method for the btree cursor type.
+ */
+static int
+__curfile_compare_equal(WT_CURSOR *a, WT_CURSOR *b, int *cmpp)
+{
+ WT_CURSOR_BTREE *cbt;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+
+ cbt = (WT_CURSOR_BTREE *)a;
+ CURSOR_API_CALL(a, session, compare_equal, cbt->btree);
+
+ /*
+ * Check both cursors are a "file:" type then call the underlying
+ * function, it can handle cursors pointing to different objects.
+ */
+ if (!WT_PREFIX_MATCH(a->internal_uri, "file:") ||
+ !WT_PREFIX_MATCH(b->internal_uri, "file:"))
+ WT_ERR_MSG(session, EINVAL,
+ "Cursors must reference the same object");
+
+ WT_CURSOR_CHECKKEY(a);
+ WT_CURSOR_CHECKKEY(b);
+
+ ret = __wt_btcur_compare_equal(
+ (WT_CURSOR_BTREE *)a, (WT_CURSOR_BTREE *)b, cmpp);
+
+err: API_END_RET(session, ret);
+}
+
+/*
* __curfile_next --
* WT_CURSOR->next method for the btree cursor type.
*/
@@ -356,6 +389,7 @@ __wt_curfile_create(WT_SESSION_IMPL *session,
__wt_cursor_set_key, /* set-key */
__wt_cursor_set_value, /* set-value */
__curfile_compare, /* compare */
+ __curfile_compare_equal, /* compare_equal */
__curfile_next, /* next */
__curfile_prev, /* prev */
__curfile_reset, /* reset */
diff --git a/src/cursor/cur_index.c b/src/cursor/cur_index.c
index 007f3a5ae5b..dd7b965642d 100644
--- a/src/cursor/cur_index.c
+++ b/src/cursor/cur_index.c
@@ -343,6 +343,7 @@ __wt_curindex_open(WT_SESSION_IMPL *session,
__wt_cursor_set_key, /* set-key */
__curindex_set_value, /* set-value */
__wt_cursor_notsup, /* compare */
+ __wt_cursor_notsup, /* compare_equal */
__curindex_next, /* next */
__curindex_prev, /* prev */
__curindex_reset, /* reset */
diff --git a/src/cursor/cur_log.c b/src/cursor/cur_log.c
index 04ab1e2a14a..346b6bf5172 100644
--- a/src/cursor/cur_log.c
+++ b/src/cursor/cur_log.c
@@ -315,6 +315,7 @@ __wt_curlog_open(WT_SESSION_IMPL *session,
__wt_cursor_set_key, /* set-key */
__wt_cursor_set_value, /* set-value */
__curlog_compare, /* compare */
+ __curlog_compare, /* compare_equal */
__curlog_next, /* next */
__wt_cursor_notsup, /* prev */
__curlog_reset, /* reset */
diff --git a/src/cursor/cur_metadata.c b/src/cursor/cur_metadata.c
index 618c678558a..55205e02f8e 100644
--- a/src/cursor/cur_metadata.c
+++ b/src/cursor/cur_metadata.c
@@ -409,6 +409,7 @@ __wt_curmetadata_open(WT_SESSION_IMPL *session,
__wt_cursor_set_key, /* set-key */
__wt_cursor_set_value, /* set-value */
__curmetadata_compare, /* compare */
+ __curmetadata_compare, /* compare_equal */
__curmetadata_next, /* next */
__curmetadata_prev, /* prev */
__curmetadata_reset, /* reset */
diff --git a/src/cursor/cur_stat.c b/src/cursor/cur_stat.c
index f7effb87a4f..c017c50e360 100644
--- a/src/cursor/cur_stat.c
+++ b/src/cursor/cur_stat.c
@@ -485,6 +485,7 @@ __wt_curstat_open(WT_SESSION_IMPL *session,
__curstat_set_key, /* set-key */
__curstat_set_value, /* set-value */
__wt_cursor_notsup, /* compare */
+ __wt_cursor_notsup, /* compare_equal */
__curstat_next, /* next */
__curstat_prev, /* prev */
__curstat_reset, /* reset */
diff --git a/src/cursor/cur_table.c b/src/cursor/cur_table.c
index 4eb362cfcd4..2a314f342b0 100644
--- a/src/cursor/cur_table.c
+++ b/src/cursor/cur_table.c
@@ -77,20 +77,21 @@ __curextract_insert(WT_CURSOR *cursor) {
static int
__apply_idx(WT_CURSOR_TABLE *ctable, size_t func_off, int skip_immutable) {
WT_CURSOR_STATIC_INIT(iface,
- __wt_cursor_get_key, /* get-key */
- __wt_cursor_get_value, /* get-value */
- __wt_cursor_set_key, /* set-key */
- __wt_cursor_set_value, /* set-value */
- __wt_cursor_notsup, /* compare */
- __wt_cursor_notsup, /* next */
- __wt_cursor_notsup, /* prev */
- __wt_cursor_notsup, /* reset */
- __wt_cursor_notsup, /* search */
- __wt_cursor_notsup, /* search-near */
- __curextract_insert, /* insert */
- __wt_cursor_notsup, /* update */
- __wt_cursor_notsup, /* remove */
- __wt_cursor_notsup); /* close */
+ __wt_cursor_get_key, /* get-key */
+ __wt_cursor_get_value, /* get-value */
+ __wt_cursor_set_key, /* set-key */
+ __wt_cursor_set_value, /* set-value */
+ __wt_cursor_notsup, /* compare */
+ __wt_cursor_notsup, /* compare_equal */
+ __wt_cursor_notsup, /* next */
+ __wt_cursor_notsup, /* prev */
+ __wt_cursor_notsup, /* reset */
+ __wt_cursor_notsup, /* search */
+ __wt_cursor_notsup, /* search-near */
+ __curextract_insert, /* insert */
+ __wt_cursor_notsup, /* update */
+ __wt_cursor_notsup, /* remove */
+ __wt_cursor_notsup); /* close */
WT_CURSOR **cp;
WT_CURSOR_EXTRACTOR extract_cursor;
WT_DECL_RET;
@@ -832,20 +833,21 @@ __wt_curtable_open(WT_SESSION_IMPL *session,
const char *uri, const char *cfg[], WT_CURSOR **cursorp)
{
WT_CURSOR_STATIC_INIT(iface,
- __wt_curtable_get_key, /* get-key */
- __wt_curtable_get_value, /* get-value */
- __wt_curtable_set_key, /* set-key */
- __wt_curtable_set_value, /* set-value */
- __curtable_compare, /* compare */
- __curtable_next, /* next */
- __curtable_prev, /* prev */
- __curtable_reset, /* reset */
- __curtable_search, /* search */
- __curtable_search_near, /* search-near */
- __curtable_insert, /* insert */
- __curtable_update, /* update */
- __curtable_remove, /* remove */
- __curtable_close); /* close */
+ __wt_curtable_get_key, /* get-key */
+ __wt_curtable_get_value, /* get-value */
+ __wt_curtable_set_key, /* set-key */
+ __wt_curtable_set_value, /* set-value */
+ __curtable_compare, /* compare */
+ __curtable_compare, /* compare_equal */
+ __curtable_next, /* next */
+ __curtable_prev, /* prev */
+ __curtable_reset, /* reset */
+ __curtable_search, /* search */
+ __curtable_search_near, /* search-near */
+ __curtable_insert, /* insert */
+ __curtable_update, /* update */
+ __curtable_remove, /* remove */
+ __curtable_close); /* close */
WT_CONFIG_ITEM cval;
WT_CURSOR *cursor;
WT_CURSOR_TABLE *ctable;
diff --git a/src/include/cursor.h b/src/include/cursor.h
index 0fc4b883a16..cd523274d77 100644
--- a/src/include/cursor.h
+++ b/src/include/cursor.h
@@ -15,6 +15,7 @@
set_key, \
set_value, \
compare, \
+ compare_equal, \
next, \
prev, \
reset, \
@@ -34,6 +35,7 @@
(void (*)(WT_CURSOR *, ...))(set_key), \
(void (*)(WT_CURSOR *, ...))(set_value), \
(int (*)(WT_CURSOR *, WT_CURSOR *, int *))(compare), \
+ (int (*)(WT_CURSOR *, WT_CURSOR *, int *))(compare_equal), \
next, \
prev, \
reset, \
diff --git a/src/include/extern.h b/src/include/extern.h
index d8ed3f5cef1..3c737eb3188 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -96,6 +96,7 @@ extern int __wt_btcur_remove(WT_CURSOR_BTREE *cbt);
extern int __wt_btcur_update(WT_CURSOR_BTREE *cbt);
extern int __wt_btcur_next_random(WT_CURSOR_BTREE *cbt);
extern int __wt_btcur_compare(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp);
+extern int __wt_btcur_compare_equal( WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp);
extern int __wt_btcur_range_truncate(WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop);
extern int __wt_btcur_close(WT_CURSOR_BTREE *cbt);
extern int __wt_debug_set_verbose(WT_SESSION_IMPL *session, const char *v);
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index c8b242b8f14..a76ab67ae1a 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -270,7 +270,8 @@ struct __wt_cursor {
*/
/*!
* Return the ordering relationship between two cursors: both cursors
- * must have the same data source and have valid keys.
+ * must have the same data source and have valid keys. (When testing
+ * only for equality, WT_CURSOR::compare_equality may be faster.)
*
* @snippet ex_all.c Cursor comparison
*
@@ -286,6 +287,22 @@ struct __wt_cursor {
int __F(compare)(WT_CURSOR *cursor, WT_CURSOR *other, int *comparep);
/*!
+ * Return the ordering relationship between two cursors, testing only
+ * for equality: both cursors must have the same data source and have
+ * valid keys.
+ *
+ * @snippet ex_all.c Cursor equality
+ *
+ * @param cursor the cursor handle
+ * @param other another cursor handle
+ * @param equalityp the status of the comparison: 0 if the cursors
+ * refer to the same key, otherwise not 0.
+ * @errors
+ */
+ int __F(compare_equal)
+ (WT_CURSOR *cursor, WT_CURSOR *other, int *equalityp);
+
+ /*!
* Return the next record.
*
* @snippet ex_all.c Return the next record
diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c
index 52bd3e9373d..257c7dee449 100644
--- a/src/lsm/lsm_cursor.c
+++ b/src/lsm/lsm_cursor.c
@@ -1431,6 +1431,7 @@ __wt_clsm_open(WT_SESSION_IMPL *session,
__wt_cursor_set_key, /* set-key */
__wt_cursor_set_value, /* set-value */
__clsm_compare, /* compare */
+ __clsm_compare, /* compare_equal */
__clsm_next, /* next */
__clsm_prev, /* prev */
__clsm_reset, /* reset */
diff --git a/test/suite/test_cursor_compare.py b/test/suite/test_cursor_compare.py
index 227505b14ce..536f5cb0c3f 100644
--- a/test/suite/test_cursor_compare.py
+++ b/test/suite/test_cursor_compare.py
@@ -35,8 +35,9 @@ class test_cursor_comparison(wttest.WiredTigerTestCase):
name = 'test_compare'
types = [
- ('file', dict(type='file:')),
- ('table', dict(type='table:'))
+ ('file', dict(type='file:', config='')),
+ ('lsm', dict(type='table:', config=',type=lsm')),
+ ('table', dict(type='table:', config=''))
]
keyfmt = [
('integer', dict(keyfmt='i')),
@@ -47,32 +48,128 @@ class test_cursor_comparison(wttest.WiredTigerTestCase):
def test_cursor_comparison(self):
uri = self.type + 'compare'
+ uriX = self.type + 'compareX'
# Build the object.
if self.type == 'file:':
- simple_populate(self, uri, 'key_format=' + self.keyfmt, 100)
+ simple_populate(self, uri,
+ 'key_format=' + self.keyfmt + self.config, 100)
+ simple_populate(self, uriX,
+ 'key_format=' + self.keyfmt + self.config, 100)
else:
- complex_populate(self, uri, 'key_format=' + self.keyfmt, 100)
+ complex_populate(self, uri,
+ 'key_format=' + self.keyfmt + self.config, 100)
+ complex_populate(self, uriX,
+ 'key_format=' + self.keyfmt + self.config, 100)
c1 = self.session.open_cursor(uri, None)
c2 = self.session.open_cursor(uri, None)
- # Confirm the method fails unless the keys are set.
+ # Confirm failure unless the keys are set.
msg = '/requires key be set/'
self.assertRaisesWithMessage(
wiredtiger.WiredTigerError, lambda: c1.compare(c2), msg)
self.assertRaisesWithMessage(
wiredtiger.WiredTigerError, lambda: c2.compare(c1), msg)
- # Test cursors in all three orders.
+ # Test cursors before they're positioned.
c1.set_key(key_populate(c1, 10))
- self.assertEquals(c1.search(), 0)
c2.set_key(key_populate(c2, 20))
- self.assertEquals(c2.search(), 0)
self.assertGreater(c2.compare(c1), 0)
self.assertLess(c1.compare(c2), 0)
c2.set_key(key_populate(c2, 10))
- self.assertEquals(c1.compare(c2), 0)
+ self.assertEqual(c1.compare(c2), 0)
+ self.assertEqual(c2.compare(c1), 0)
+
+ # Confirm failure for different objects.
+ cX = self.session.open_cursor(uriX, None)
+ cX.set_key(key_populate(cX, 10))
+ msg = '/must reference the same object/'
+ self.assertRaisesWithMessage(
+ wiredtiger.WiredTigerError, lambda: cX.compare(c1), msg)
+
+ # Test cursors after they're positioned (shouldn't matter for compare).
+ c1.set_key(key_populate(c1, 10))
+ self.assertEqual(c1.search(), 0)
+ c2.set_key(key_populate(c2, 20))
+ self.assertEqual(c2.search(), 0)
+ self.assertGreater(c2.compare(c1), 0)
+ self.assertLess(c1.compare(c2), 0)
+ c2.set_key(key_populate(c2, 10))
+ self.assertEqual(c2.search(), 0)
+ self.assertEqual(c1.compare(c2), 0)
+ self.assertEqual(c2.compare(c1), 0)
+
+ # Confirm failure for different objects.
+ cX = self.session.open_cursor(uriX, None)
+ cX.set_key(key_populate(cX, 10))
+ self.assertEqual(cX.search(), 0)
+ msg = '/must reference the same object/'
+ self.assertRaisesWithMessage(
+ wiredtiger.WiredTigerError, lambda: cX.compare(c1), msg)
+
+ def test_cursor_equality(self):
+ uri = self.type + 'equality'
+ uriX = self.type + 'compareX'
+
+ # Build the object.
+ if self.type == 'file:':
+ simple_populate(self, uri,
+ 'key_format=' + self.keyfmt + self.config, 100)
+ simple_populate(self, uriX,
+ 'key_format=' + self.keyfmt + self.config, 100)
+ else:
+ complex_populate(self, uri,
+ 'key_format=' + self.keyfmt + self.config, 100)
+ complex_populate(self, uriX,
+ 'key_format=' + self.keyfmt + self.config, 100)
+
+ c1 = self.session.open_cursor(uri, None)
+ c2 = self.session.open_cursor(uri, None)
+
+ # Confirm failure unless the keys are set.
+ msg = '/requires key be set/'
+ self.assertRaisesWithMessage(
+ wiredtiger.WiredTigerError, lambda: c1.compare_equal(c2), msg)
+ self.assertRaisesWithMessage(
+ wiredtiger.WiredTigerError, lambda: c2.compare_equal(c1), msg)
+
+ # Test cursors before they're positioned.
+ c1.set_key(key_populate(c1, 10))
+ c2.set_key(key_populate(c2, 20))
+ self.assertNotEqual(c1.compare_equal(c2), 0)
+ self.assertNotEqual(c2.compare_equal(c1), 0)
+ c2.set_key(key_populate(c2, 10))
+ self.assertEqual(c1.compare_equal(c2), 0)
+ self.assertEqual(c2.compare_equal(c1), 0)
+
+ # Confirm failure for different objects.
+ cX = self.session.open_cursor(uriX, None)
+ cX.set_key(key_populate(cX, 10))
+ msg = '/must reference the same object/'
+ self.assertRaisesWithMessage(
+ wiredtiger.WiredTigerError, lambda: cX.compare(c1), msg)
+
+ # Test cursors after they're positioned (internally, it's a different
+ # search path if keys are positioned in the tree).
+ c1.set_key(key_populate(c1, 10))
+ self.assertEqual(c1.search(), 0)
+ c2.set_key(key_populate(c2, 20))
+ self.assertEqual(c2.search(), 0)
+ self.assertNotEqual(c1.compare_equal(c2), 0)
+ self.assertNotEqual(c2.compare_equal(c1), 0)
+ c2.set_key(key_populate(c2, 10))
+ self.assertEqual(c2.search(), 0)
+ self.assertEqual(c1.compare_equal(c2), 0)
+ self.assertEqual(c2.compare_equal(c1), 0)
+
+ # Confirm failure for different objects.
+ cX = self.session.open_cursor(uriX, None)
+ cX.set_key(key_populate(cX, 10))
+ self.assertEqual(cX.search(), 0)
+ msg = '/must reference the same object/'
+ self.assertRaisesWithMessage(
+ wiredtiger.WiredTigerError, lambda: cX.compare(c1), msg)
if __name__ == '__main__':