summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClarisse Cheah <clarisse.cheah@mongodb.com>2022-10-16 23:44:08 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-10-17 00:18:57 +0000
commitd38979363d12493873ea26cfe847d528dacee70e (patch)
tree3f4f0c5aa389b6685df696b2b4129cbdafd8c116
parentdb634af010edf9566d596aa8418c15c7e3f9b2da (diff)
downloadmongo-d38979363d12493873ea26cfe847d528dacee70e.tar.gz
Import wiredtiger: d69ee179611d881d06d0469480985992a7f186a2 from branch mongodb-master
ref: 994ff9d67a..d69ee17961 for: 6.2.0-rc0 WT-9936 Reduce overhead of configuration parsing for the bounded cursor. (#8342)
-rw-r--r--src/third_party/wiredtiger/dist/api_data.py11
-rw-r--r--src/third_party/wiredtiger/dist/s_funcs.list1
-rw-r--r--src/third_party/wiredtiger/dist/s_string.ok2
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_std.c99
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in18
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_bound01.py16
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_bound02.py10
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_bound03.py8
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_bound04.py12
10 files changed, 83 insertions, 96 deletions
diff --git a/src/third_party/wiredtiger/dist/api_data.py b/src/third_party/wiredtiger/dist/api_data.py
index 84b3719692c..448506a4473 100644
--- a/src/third_party/wiredtiger/dist/api_data.py
+++ b/src/third_party/wiredtiger/dist/api_data.py
@@ -1207,18 +1207,15 @@ cursor_bound_config = [
Config('action', 'set', r'''
configures whether this call into the API will set or clear range bounds on the given
cursor. It takes one of two values, "set" or "clear". If "set" is specified then "bound"
- must also be specified. If "clear" is specified without any bounds then both bounds will
- be cleared. The keys relevant to the given bound must have been set prior to the call using
- WT_CURSOR::set_key. This configuration is currently a work in progress and should not be
- used.''',
+ must also be specified. The keys relevant to the given bound must have been set prior to the
+ call using WT_CURSOR::set_key.''',
choices=['clear','set']),
Config('inclusive', 'true', r'''
- configures whether the given bound is inclusive or not. This configuration is currently a
- work in progress and should not be used.''',
+ configures whether the given bound is inclusive or not.''',
type='boolean'),
Config('bound', '', r'''
configures which bound is being operated on. It takes one of two values, "lower" or "upper".
- This configuration is currently a work in progress and should not be used.''',
+ ''',
choices=['lower','upper']),
]
diff --git a/src/third_party/wiredtiger/dist/s_funcs.list b/src/third_party/wiredtiger/dist/s_funcs.list
index a5f61123e88..7501ce0ce85 100644
--- a/src/third_party/wiredtiger/dist/s_funcs.list
+++ b/src/third_party/wiredtiger/dist/s_funcs.list
@@ -3,6 +3,7 @@ WT_CRC32_ENTRY
WT_CURDUMP_PASS
__bit_ffs
__bit_nclr
+__curstd_config_value_for
__ovfl_discard_dump
__ovfl_reuse_dump
__wt_bloom_drop
diff --git a/src/third_party/wiredtiger/dist/s_string.ok b/src/third_party/wiredtiger/dist/s_string.ok
index c65436830d8..8f2951fad48 100644
--- a/src/third_party/wiredtiger/dist/s_string.ok
+++ b/src/third_party/wiredtiger/dist/s_string.ok
@@ -612,6 +612,7 @@ bm
bnd
bool
boolean
+booleans
boption
br
breakpoint
@@ -750,6 +751,7 @@ cursoring
cursorp
curstartrecno
curstat
+curstd
curtable
curtiered
curversion
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index 034278f67f7..d37c28d4312 100644
--- a/src/third_party/wiredtiger/import.data
+++ b/src/third_party/wiredtiger/import.data
@@ -2,5 +2,5 @@
"vendor": "wiredtiger",
"github": "wiredtiger/wiredtiger.git",
"branch": "mongodb-master",
- "commit": "994ff9d67aec692c6add208035d7d8691b271e6f"
+ "commit": "d69ee179611d881d06d0469480985992a7f186a2"
}
diff --git a/src/third_party/wiredtiger/src/cursor/cur_std.c b/src/third_party/wiredtiger/src/cursor/cur_std.c
index f6ca142c2f6..ae5f6c242e4 100644
--- a/src/third_party/wiredtiger/src/cursor/cur_std.c
+++ b/src/third_party/wiredtiger/src/cursor/cur_std.c
@@ -9,6 +9,23 @@
#include "wt_internal.h"
/*
+ * __curstd_config_value_for --
+ * Returns NULL if the string being searched for isn't found, or the string after the "=" sign
+ * in the config string.
+ */
+static inline char *
+__curstd_config_value_for(const char *config, const char *var, size_t len)
+{
+ char *cfg;
+ if ((cfg = strstr(config, var)) == NULL)
+ return (NULL);
+ return (cfg + len);
+}
+
+#define CONFIG_VALUE_FOR(config, var, cfg) \
+ ((cfg) = __curstd_config_value_for((config), var "=", strlen(var "=")))
+
+/*
* __wt_cursor_noop --
* Cursor noop.
*/
@@ -1177,19 +1194,33 @@ err:
int
__wt_cursor_bound(WT_CURSOR *cursor, const char *config)
{
- WT_CONFIG_ITEM cval;
WT_CURSOR_BTREE *cbt;
WT_DECL_RET;
WT_ITEM key;
WT_SESSION_IMPL *session;
int exact;
- bool inclusive;
+ char *cfg;
+ bool inclusive, have_action;
+ cfg = NULL;
cbt = (WT_CURSOR_BTREE *)cursor;
exact = 0;
- inclusive = false;
- CURSOR_API_CALL_CONF(cursor, session, bound, config, cfg, NULL);
+ /*
+ * Our API defines "inclusive" as true by default, it also defines "set" as the default action.
+ * This means we can't expect the user to have provided those configurations via the config
+ * string. Normally WiredTiger merges the user provided configuration with the default
+ * configuration, for performance reasons we are skipping this step. As such we need to handle
+ * the cases where the user did and didn't provide the config making up the difference for the
+ * defaults.
+ *
+ * These two booleans provide a mechanism to handle the user not providing the configuration and
+ * still being able to parse it.
+ */
+ inclusive = true;
+ have_action = false;
+
+ CURSOR_API_CALL(cursor, session, bound, NULL);
if (CUR2BT(cursor)->type == BTREE_COL_FIX)
WT_ERR_MSG(session, EINVAL, "setting bounds is not compatible with fixed column store.");
@@ -1197,22 +1228,28 @@ __wt_cursor_bound(WT_CURSOR *cursor, const char *config)
if (F_ISSET(cursor, WT_CURSTD_PREFIX_SEARCH))
WT_ERR_MSG(session, EINVAL, "setting bounds is not compatible with prefix search.");
- WT_ERR(__wt_config_gets(session, cfg, "action", &cval));
- if (WT_STRING_MATCH("set", cval.str, cval.len)) {
- WT_ERR(__wt_config_gets(session, cfg, "inclusive", &cval));
- inclusive = cval.val != 0;
+ if (config == NULL || config[0] == '\0')
+ WT_ERR_MSG(session, EINVAL, "an empty config is not valid when setting or clearing bounds");
- /* Check that bound is set with action set configuration. */
- WT_ERR(__wt_config_gets(session, cfg, "bound", &cval));
- if (cval.len == 0)
- WT_ERR_MSG(session, EINVAL, "setting bounds must require the bound configuration set");
+ /* Action is default to "set". */
+ if (CONFIG_VALUE_FOR(config, "action", cfg) != NULL)
+ have_action = true;
+ if (!have_action || WT_PREFIX_MATCH(cfg, "set")) {
if (WT_CURSOR_IS_POSITIONED(cbt))
WT_ERR_MSG(session, EINVAL, "setting bounds on a positioned cursor is not allowed");
/* The cursor must have a key set to place the lower or upper bound. */
WT_ERR(__cursor_checkkey(cursor));
- if (WT_STRING_MATCH("upper", cval.str, cval.len)) {
+
+ /* Inclusive is true by default. */
+ if (CONFIG_VALUE_FOR(config, "inclusive", cfg) != NULL && !WT_PREFIX_MATCH(cfg, "true"))
+ inclusive = false;
+
+ if (CONFIG_VALUE_FOR(config, "bound", cfg) == NULL)
+ WT_ERR_MSG(session, EINVAL,
+ "a bound must be specified when setting bounds, either \"lower\" or \"upper\"");
+ else if (WT_PREFIX_MATCH(cfg, "upper")) {
/*
* If the lower bounds are set, make sure that the upper bound is greater than the lower
* bound.
@@ -1238,7 +1275,7 @@ __wt_cursor_bound(WT_CURSOR *cursor, const char *config)
else
F_CLR(cursor, WT_CURSTD_BOUND_UPPER_INCLUSIVE);
WT_ERR(__wt_buf_set(session, &cursor->upper_bound, key.data, key.size));
- } else if (WT_STRING_MATCH("lower", cval.str, cval.len)) {
+ } else if (WT_PREFIX_MATCH(cfg, "lower")) {
/*
* If the upper bounds are set, make sure that the lower bound is less than the upper
* bound.
@@ -1266,30 +1303,16 @@ __wt_cursor_bound(WT_CURSOR *cursor, const char *config)
WT_ERR(__wt_buf_set(session, &cursor->lower_bound, key.data, key.size));
} else
WT_ERR_MSG(session, EINVAL,
- "setting bounds only accepts \"upper\" or \"lower\" as the configuration");
-
- } else if (WT_STRING_MATCH("clear", cval.str, cval.len)) {
- /* Inclusive should not be supplied from the application with action clear configuration. */
- if (__wt_config_getones(session, config, "inclusive", &cval) != WT_NOTFOUND)
- WT_ERR_MSG(session, EINVAL,
- "clearing bounds is not compatible with the inclusive configuration");
-
- /*
- * Check if there is a lower or upper specified bound config. If there are no specified
- * bounds, both the upper and lower bound will be cleared.
- */
- WT_ERR(__wt_config_gets(session, cfg, "bound", &cval));
- if (cval.len == 0 || WT_STRING_MATCH("upper", cval.str, cval.len)) {
- F_CLR(cursor, WT_CURSTD_BOUND_UPPER | WT_CURSTD_BOUND_UPPER_INCLUSIVE);
- __wt_buf_free(session, &cursor->upper_bound);
- WT_CLEAR(cursor->upper_bound);
- }
- if (cval.len == 0 || WT_STRING_MATCH("lower", cval.str, cval.len)) {
- F_CLR(cursor, WT_CURSTD_BOUND_LOWER | WT_CURSTD_BOUND_LOWER_INCLUSIVE);
- __wt_buf_free(session, &cursor->lower_bound);
- WT_CLEAR(cursor->lower_bound);
- }
- }
+ "a bound must be specified when setting bounds, either \"lower\" or \"upper\"");
+ } else if (have_action && WT_PREFIX_MATCH(cfg, "clear")) {
+ F_CLR(cursor, WT_CURSTD_BOUND_ALL);
+ __wt_buf_free(session, &cursor->upper_bound);
+ __wt_buf_free(session, &cursor->lower_bound);
+ WT_CLEAR(cursor->upper_bound);
+ WT_CLEAR(cursor->lower_bound);
+ } else
+ WT_ERR_MSG(session, EINVAL,
+ "an action of either \"clear\" or \"set\" should be specified when setting bounds");
err:
API_END_RET_STAT(session, ret, cursor_bound);
}
diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in
index e103766eed4..f1e66e10ad7 100644
--- a/src/third_party/wiredtiger/src/include/wiredtiger.in
+++ b/src/third_party/wiredtiger/src/include/wiredtiger.in
@@ -684,18 +684,14 @@ struct __wt_cursor {
* @configstart{WT_CURSOR.bound, see dist/api_data.py}
* @config{action, configures whether this call into the API will set or clear range bounds
* on the given cursor. It takes one of two values\, "set" or "clear". If "set" is
- * specified then "bound" must also be specified. If "clear" is specified without any
- * bounds then both bounds will be cleared. The keys relevant to the given bound must have
- * been set prior to the call using WT_CURSOR::set_key. This configuration is currently a
- * work in progress and should not be used., a string\, chosen from the following options:
- * \c "clear"\, \c "set"; default \c set.}
+ * specified then "bound" must also be specified. The keys relevant to the given bound must
+ * have been set prior to the call using WT_CURSOR::set_key., a string\, chosen from the
+ * following options: \c "clear"\, \c "set"; default \c set.}
* @config{bound, configures which bound is being operated on. It takes one of two values\,
- * "lower" or "upper". This configuration is currently a work in progress and should not be
- * used., a string\, chosen from the following options: \c "lower"\, \c "upper"; default
- * empty.}
- * @config{inclusive, configures whether the given bound is inclusive or not. This
- * configuration is currently a work in progress and should not be used., a boolean flag;
- * default \c true.}
+ * "lower" or "upper"., a string\, chosen from the following options: \c "lower"\, \c
+ * "upper"; default empty.}
+ * @config{inclusive, configures whether the given bound is inclusive or not., a boolean
+ * flag; default \c true.}
* @configend
* @errors
*/
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_bound01.py b/src/third_party/wiredtiger/test/suite/test_cursor_bound01.py
index cf24f1e14e1..ca18364ea04 100644
--- a/src/third_party/wiredtiger/test/suite/test_cursor_bound01.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor_bound01.py
@@ -81,11 +81,11 @@ class test_cursor_bound01(bound_base):
# LSM format is not supported with range cursors.
if self.uri == 'lsm:':
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: cursor.bound("bound=lower"),
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: cursor.bound("action=set,bound=lower"),
'/Operation not supported/')
return
if self.value_format == '8t':
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: cursor.bound("bound=lower"),
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: cursor.bound("action=set,bound=lower"),
'/Invalid argument/')
return
@@ -95,15 +95,9 @@ class test_cursor_bound01(bound_base):
# Check that bound configuration works properly.
cursor.set_key(self.gen_key(1))
- cursor.bound("bound=lower")
+ cursor.bound("action=set,bound=lower")
cursor.set_key(self.gen_key(10))
- cursor.bound("bound=upper")
-
- # Clear and inclusive configuration are not compatible with each other.
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: cursor.bound("action=clear,inclusive=true"),
- '/Invalid argument/')
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: cursor.bound("action=clear,inclusive=false"),
- '/Invalid argument/')
+ cursor.bound("action=set,bound=upper")
# Check that clear with bound configuration works properly.
cursor.bound("action=clear")
@@ -112,7 +106,7 @@ class test_cursor_bound01(bound_base):
# Check that largest key doesn't work with bounded cursors.
cursor.set_key(self.gen_key(1))
- cursor.bound("bound=lower")
+ cursor.bound("action=set,bound=lower")
self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: cursor.largest_key(),
'/Invalid argument/')
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_bound02.py b/src/third_party/wiredtiger/test/suite/test_cursor_bound02.py
index 459c9aabd85..ce308dbe473 100644
--- a/src/third_party/wiredtiger/test/suite/test_cursor_bound02.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor_bound02.py
@@ -208,16 +208,6 @@ class test_cursor_bound02(bound_base):
cursor.set_key(self.gen_key(90))
self.assertEqual(self.set_bounds(cursor, 90, "upper"), 0)
- # Test bound API: Test that clearing the lower bound works.
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.set_bounds(cursor, 10, "upper"), '/Invalid argument/')
- self.assertEqual(cursor.bound("action=clear,bound=lower"), 0)
- self.assertEqual(self.set_bounds(cursor, 10, "upper"), 0)
-
- # Test bound API: Test that clearing the upper bound works.
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.set_bounds(cursor, 99, "lower"), '/Invalid argument/')
- self.assertEqual(cursor.bound("action=clear,bound=upper"), 0)
- self.assertEqual(self.set_bounds(cursor, 99, "lower"), 0)
-
# Test bound API: Test that clearing both of the bounds works.
cursor.reset()
self.assertEqual(self.set_bounds(cursor, 50, "upper"), 0)
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_bound03.py b/src/third_party/wiredtiger/test/suite/test_cursor_bound03.py
index 76f074d4b7e..ac9c6b1c877 100644
--- a/src/third_party/wiredtiger/test/suite/test_cursor_bound03.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor_bound03.py
@@ -123,14 +123,6 @@ class test_cursor_bound03(bound_base):
self.assertEqual(cursor.bound("action=clear"), 0)
self.cursor_traversal_bound(cursor, None, None, True)
self.assertEqual(cursor.reset(), 0)
-
- # Test bound api: Test upper bound clearing with only lower bounds.
- self.set_bounds(cursor, 50, "lower")
- cursor.bound("action=clear,bound=upper")
- self.cursor_traversal_bound(cursor, None, None, self.direction, self.end_key - 49)
-
- cursor.bound("action=clear,bound=lower")
- self.cursor_traversal_bound(cursor, None, None)
# Test bound api: Test that changing upper bounds works.
self.set_bounds(cursor, 50, "upper", self.upper_inclusive)
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_bound04.py b/src/third_party/wiredtiger/test/suite/test_cursor_bound04.py
index 0dd1849d39c..f1ec5c5ae8c 100644
--- a/src/third_party/wiredtiger/test/suite/test_cursor_bound04.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor_bound04.py
@@ -68,17 +68,9 @@ class test_cursor_bound04(bound_base):
def test_bound_special_scenario(self):
cursor = self.create_session_and_cursor()
- # Test bound api: Test upper bound clearing with only lower bounds.
+ # Test bound api: Test lower bound clearing works.
self.set_bounds(cursor, 45, "lower")
- cursor.bound("action=clear,bound=upper")
- self.assertEqual(cursor.next(), 0)
- key = cursor.get_key()
- self.assertEqual(key, self.check_key(45))
- cursor.reset()
-
- # Test bound api: Test lower bound clearing with lower bounds works.
- self.set_bounds(cursor, 45, "lower")
- cursor.bound("action=clear,bound=lower")
+ cursor.bound("action=clear")
self.assertEqual(cursor.next(), 0)
key = cursor.get_key()
self.assertEqual(key, self.check_key(self.start_key))