summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2013-04-11 15:58:42 -0400
committerKeith Bostic <keith@wiredtiger.com>2013-04-11 15:58:42 -0400
commit5488e656fa88b46ac187cef6533a6e4cb3cc62cc (patch)
tree9377cb34d9852a5d1872f81b3f3814bdac5e70c0
parentdb2ce0c4e6dbef194573c40d600e1ed3e7cc8835 (diff)
downloadmongo-5488e656fa88b46ac187cef6533a6e4cb3cc62cc.tar.gz
More work on data-source configuration support.
We can't stack a random set of entries into a cfg[] because we don't want to allocate memory in the API. Instead, whenever a method's arguments are reconfigured, re-build the base configuration string by appending the new configuration, and re-build the checks array, that way we always have a single base configuration string and a single checks array. Re-work how we're handling lists, we can't expect the application to crack them, they can be seriously messy. If it's a list, create an array of NULL-terminated refrences to nul-terminated strings (create an "argv" array, in other words). It's ugly, and the user has to free the memory, but I don't see an alternative.
-rw-r--r--dist/api_config.py41
-rw-r--r--dist/s_string.ok1
-rw-r--r--examples/c/ex_data_source.c107
-rw-r--r--src/bloom/bloom.c2
-rw-r--r--src/config/config.c50
-rw-r--r--src/config/config_check.c279
-rw-r--r--src/config/config_def.c128
-rw-r--r--src/conn/conn_api.c12
-rw-r--r--src/conn/conn_dhandle.c2
-rw-r--r--src/conn/conn_handle.c8
-rw-r--r--src/cursor/cur_dump.c2
-rw-r--r--src/cursor/cur_table.c2
-rw-r--r--src/docs/custom_data.dox10
-rw-r--r--src/include/api.h4
-rw-r--r--src/include/config.h11
-rw-r--r--src/include/connection.h11
-rw-r--r--src/include/extern.h7
-rw-r--r--src/include/wiredtiger.in4
-rw-r--r--src/include/wiredtiger_ext.h40
-rw-r--r--src/lsm/lsm_cursor.c2
-rw-r--r--src/lsm/lsm_merge.c4
-rw-r--r--src/lsm/lsm_stat.c4
-rw-r--r--src/lsm/lsm_tree.c6
-rw-r--r--src/lsm/lsm_worker.c4
-rw-r--r--src/meta/meta_table.c2
-rw-r--r--src/meta/meta_turtle.c2
-rw-r--r--src/schema/schema_create.c8
-rw-r--r--src/session/session_api.c2
28 files changed, 420 insertions, 335 deletions
diff --git a/dist/api_config.py b/dist/api_config.py
index 0b56cc41d54..1b163149bcf 100644
--- a/dist/api_config.py
+++ b/dist/api_config.py
@@ -251,10 +251,9 @@ for name in sorted(api_data.methods.keys()):
max(1, 6 - int ((len('WT_CONFIG_ENTRY_' + name)) / 8)) + \
"%2s" % str(slot) + '\n'
- # Write the method name, the uri and the value.
+ # Write the method name and base.
tfile.write('''
\t{ "%(name)s",
-\t NULL,
%(config)s,''' % {
'config' : '\n'.join('\t "%s"' % line
for line in w.wrap(','.join('%s=%s' % (c.name, get_default(c))
@@ -269,23 +268,45 @@ for name in sorted(api_data.methods.keys()):
else:
tfile.write('NULL')
- # Write the extended reference, always NULL initially, this slot is
- # used when the information is extended at run-time.
- tfile.write(',\n\t NULL\n\t},')
+ tfile.write('\n\t},')
# Write a NULL as a terminator for iteration.
-tfile.write('\n\t{ NULL, NULL, NULL, NULL, NULL }')
+tfile.write('\n\t{ NULL, NULL, NULL }')
tfile.write('\n};\n')
# Write the routine that connects the WT_CONNECTION_IMPL structure to the list
# of configuration entry structures.
tfile.write('''
-void
+int
__wt_conn_config_init(WT_SESSION_IMPL *session)
{
- S2C(session)->config_entries = config_entries;
- S2C(session)->config_entries_count =
- sizeof(config_entries)/sizeof(config_entries[0]);
+\tWT_CONNECTION_IMPL *conn;
+\tconst WT_CONFIG_ENTRY *ep, **epp;
+
+\tconn = S2C(session);
+
+\t/* Build a list of pointers to the configuration information. */
+\tWT_RET(__wt_calloc_def(session,
+\t sizeof(config_entries) / sizeof(config_entries[0]), &epp));
+\tconn->config_entries = epp;
+
+\t/* Fill in the list to reference the default information. */
+\tfor (ep = config_entries;;) {
+\t\t*epp++ = ep++;
+\t\tif (ep->method == NULL)
+\t\t\tbreak;
+\t}
+\treturn (0);
+}
+
+void
+__wt_conn_config_discard(WT_SESSION_IMPL *session)
+{
+\tWT_CONNECTION_IMPL *conn;
+
+\tconn = S2C(session);
+
+\t__wt_free(session, conn->config_entries);
}
''')
diff --git a/dist/s_string.ok b/dist/s_string.ok
index 0286e166657..9030ca2890f 100644
--- a/dist/s_string.ok
+++ b/dist/s_string.ok
@@ -411,6 +411,7 @@ fixup
flcs
fmt
fnv
+foc
fopen
fp
fprintf
diff --git a/examples/c/ex_data_source.c b/examples/c/ex_data_source.c
index 5ebc1c2aacb..05732aedfa7 100644
--- a/examples/c/ex_data_source.c
+++ b/examples/c/ex_data_source.c
@@ -27,9 +27,10 @@
* ex_data_source.c
* demonstrates how to create and access a data source
*/
+#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
#include <wiredtiger.h>
/*! [WT_EXTENSION_API declaration] */
@@ -52,11 +53,39 @@ my_create(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
{
/* Unused parameters */
(void)dsrc;
- (void)session;
(void)uri;
(void)exclusive;
(void)config;
+ {
+ const char *msg = "string";
+ /*! [WT_EXTENSION_API err_printf] */
+ (void)wt_api->err_printf(session, "extension error message: %s", msg);
+ /*! [WT_EXTENSION_API err_printf] */
+ }
+
+ {
+ const char *msg = "string";
+ /*! [WT_EXTENSION_API msg_printf] */
+ (void)wt_api->msg_printf(session, "extension message: %s", msg);
+ /*! [WT_EXTENSION_API msg_printf] */
+ }
+
+ {
+ /*! [WT_EXTENSION_API scr_alloc] */
+ void *buffer;
+ if ((buffer = wt_api->scr_alloc(session, 512)) == NULL) {
+ (void)wt_api->err_printf(session,
+ "buffer allocation: %s", wiredtiger_strerror(ENOMEM));
+ return (ENOMEM);
+ }
+ /*! [WT_EXTENSION_API scr_alloc] */
+
+ /*! [WT_EXTENSION_API scr_free] */
+ wt_api->scr_free(session, buffer);
+ /*! [WT_EXTENSION_API scr_free] */
+ }
+
return (0);
}
@@ -121,6 +150,10 @@ my_open_cursor(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
WT_EXTENSION_CONFIG value;
int my_data_source_overwrite;
+ /*
+ * Retrieve the value of the boolean type configuration string
+ * "overwrite".
+ */
if ((ret =
wt_api->config(session, "overwrite", config, &value)) != 0) {
(void)wt_api->err_printf(session,
@@ -136,6 +169,10 @@ my_open_cursor(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
WT_EXTENSION_CONFIG value;
int64_t my_data_source_page_size;
+ /*
+ * Retrieve the value of the integer type configuration string
+ * "page_size".
+ */
if ((ret =
wt_api->config(session, "page_size", config, &value)) != 0) {
(void)wt_api->err_printf(session,
@@ -151,6 +188,10 @@ my_open_cursor(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
WT_EXTENSION_CONFIG value;
const char *my_data_source_key;
+ /*
+ * Retrieve the value of the string type configuration string
+ * "key_format".
+ */
if ((ret =
wt_api->config(session, "key_format", config, &value)) != 0) {
(void)wt_api->err_printf(session,
@@ -159,8 +200,8 @@ my_open_cursor(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
}
/*
- * Strings returned from WT_EXTENSION_API::config are not necessarily
- * nul-terminated; the associated length must be used instead.
+ * Values returned from WT_EXTENSION_API::config in the str field are
+ * not nul-terminated; the associated length must be used instead.
*/
if (value.len == 1 && value.str[0] == 'r')
my_data_source_key = "recno";
@@ -172,45 +213,26 @@ my_open_cursor(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
{
/*! [WT_EXTENSION_CONFIG list] */
WT_EXTENSION_CONFIG value;
- size_t cnt;
- char **ap, **argv, *copy, *p, *t;
+ char **argv;
- if ((ret =
- wt_api->config(session, "paths", config, &value)) != 0) {
+ /*
+ * Retrieve the value of the list type configuration string "paths".
+ */
+ if ((ret = wt_api->config(session, "paths", config, &value)) != 0) {
(void)wt_api->err_printf(session,
"paths configuration: %s", wiredtiger_strerror(ret));
return (ret);
}
/*
- * Strings returned from WT_EXTENSION_API::config are not necessarily
- * nul-terminated; the associated length must be used instead.
- *
- * The strsep function requires nul-termination of the list. Allocate
- * memory and copy the list so it's nul-terminated. Parse the list,
- * counting entries.
- *
- * Allocate an array of pointers large enough to hold a reference to
- * each list element, then re-parse the list, this time filling in the
- * array. Strsep nul-terminates each element in the list, so there's
- * no addition work required.
- *
- * Finally, display the list.
+ * Strings returned from WT_EXTENSION_API::config in the argv array are
+ * nul-terminated. The array and memory it references must be freed.
*/
- copy = calloc(1, value.len + 1);
- memcpy(copy, value.str, value.len);
- for (p = copy, cnt = 0; (t = strsep(&p, ",\t ")) != NULL;)
- if (*t != '\0')
- ++cnt;
-
- memcpy(copy, value.str, value.len);
- argv = calloc(sizeof(char *), cnt + 1);
- for (ap = argv, p = copy; (*ap = strsep(&p, ",\t ")) != NULL;)
- if (**ap != '\0')
- ++ap;
-
- for (ap = argv; *ap != NULL; ++ap)
- printf("%s\n", *ap);
+ for (argv = value.argv; *argv != NULL; ++argv)
+ printf("%s\n", *argv);
+ for (argv = value.argv; *argv != NULL; ++argv)
+ free(*argv);
+ free(argv);
/*! [WT_EXTENSION_CONFIG list] */
}
@@ -347,21 +369,22 @@ main(void)
/*! [WT_DATA_SOURCE configure string with checking] */
/*
- * Limit target to one of /device, /home or /target; default to /home.
+ * Limit the target string to one of /device, /home or /target; default
+ * to /home.
*/
ret = conn->configure_method(conn,
- "session.open_cursor", NULL,
- "target=/home", "string", "choices=[/device, /home, /target]");
+ "session.open_cursor", NULL, "target=\"/home\"", "string",
+ "choices=[\"/device\", \"/home\", \"/target\"]");
/*! [WT_DATA_SOURCE configure string with checking] */
/*! [WT_DATA_SOURCE configure list with checking] */
/*
- * The paths are optional, so there's no default; limit paths to one or
- * more of /device, /home, /mnt or /target.
+ * Limit the paths list to one or more of /device, /home, /mnt or
+ * /target; default to /mnt.
*/
ret = conn->configure_method(conn,
- "session.open_cursor", NULL,
- "paths", "list", "choices=[/device, /home, /mnt, /target]");
+ "session.open_cursor", NULL, "paths=[\"/mnt\"]", "list",
+ "choices=[\"/device\", \"/home\", \"/mnt\", \"/target\"]");
/*! [WT_DATA_SOURCE configure list with checking] */
(void)conn->close(conn, NULL);
diff --git a/src/bloom/bloom.c b/src/bloom/bloom.c
index 5dced03e204..6af709cb760 100644
--- a/src/bloom/bloom.c
+++ b/src/bloom/bloom.c
@@ -124,7 +124,7 @@ __wt_bloom_open(WT_SESSION_IMPL *session,
WT_RET(__bloom_init(session, uri, NULL, &bloom));
/* Find the largest key, to get the size of the filter. */
- cfg[0] = WT_CONFIG_NAME(session, session_open_cursor);
+ cfg[0] = WT_CONFIG_BASE(session, session_open_cursor);
cfg[1] = bloom->config;
cfg[2] = NULL;
c = NULL;
diff --git a/src/config/config.c b/src/config/config.c
index 261e70ca88e..f94f063e1a4 100644
--- a/src/config/config.c
+++ b/src/config/config.c
@@ -660,17 +660,57 @@ int
__wt_ext_config(WT_SESSION *wt_session,
const char *key, void *cfg, WT_EXTENSION_CONFIG *value)
{
- WT_CONFIG_ITEM v;
+ WT_CONFIG conf;
+ WT_CONFIG_ITEM cval, k, v;
+ WT_DECL_RET;
WT_SESSION_IMPL *session;
+ int cnt;
+ char **argv, **ap;
session = (WT_SESSION_IMPL *)wt_session;
+ argv = NULL;
+
+ memset(value, 0, sizeof(value));
- WT_RET(__wt_config_gets(session, cfg, key, &v));
+ WT_RET(__wt_config_gets(session, cfg, key, &cval));
- value->str = v.str;
- value->len = v.len;
- value->value = v.val;
+ value->str = cval.str;
+ value->len = cval.len;
+ value->value = cval.val;
+
+ /*
+ * Parse lists into a NULL-terminated array of nul-terminated strings.
+ */
+ if (cval.type == ITEM_STRUCT && cval.len != 0) {
+ /* Count out how many slots we'll need. */
+ WT_RET(__wt_config_subinit(session, &conf, &cval));
+ for (cnt = 0;
+ (ret = __wt_config_next(&conf, &k, &v)) == 0; ++cnt)
+ ;
+ if (ret != WT_NOTFOUND)
+ WT_RET(ret);
+
+ /* Allocate the argv array and fill it in. */
+ WT_RET(__wt_calloc_def(session, cnt + 1, &argv));
+
+ WT_RET(__wt_config_subinit(session, &conf, &cval));
+ for (cnt = 0;
+ (ret = __wt_config_next(&conf, &k, &v)) == 0; ++cnt)
+ WT_ERR(
+ __wt_strndup(session, k.str, k.len, &argv[cnt]));
+ if (ret != WT_NOTFOUND)
+ WT_ERR(ret);
+
+ value->argv = argv;
+ }
return (0);
+
+err: if (argv != NULL) {
+ for (ap = argv; *ap != NULL; ++ap)
+ __wt_free(session, *ap);
+ __wt_free(session, argv);
+ }
+ return (ret);
}
/*
diff --git a/src/config/config_check.c b/src/config/config_check.c
index a0b5da9f29a..fe23811aedc 100644
--- a/src/config/config_check.c
+++ b/src/config/config_check.c
@@ -11,63 +11,70 @@ static int config_check(
WT_SESSION_IMPL *, const WT_CONFIG_CHECK *, const char *, size_t);
/*
- * configure_copy --
- * Copy the default configuration in preparation for an extension.
+ * __wt_conn_foc_add --
+ * Add a new entry into the connection's free-on-close list.
*/
static int
-configure_copy(WT_SESSION_IMPL *session)
+__wt_conn_foc_add(WT_SESSION_IMPL *session, ...)
{
WT_CONNECTION_IMPL *conn;
+ va_list ap;
+ size_t cnt;
+ void *p;
conn = S2C(session);
/*
- * Unless the application extends the configuration information, we
- * use a shared, read-only copy. If the application wants to extend
- * it, make a local copy and replace the original. Our caller is
- * holding the (probably unnecessary) lock to avoid a race.
+ * Instead of using locks to protect configuration information, assume
+ * we can atomically update a pointer to a chunk of memory, and because
+ * a pointer is never partially written, readers will correctly see the
+ * original or new versions of the memory. Readers might be using the
+ * old version as it's being updated, though, which means we cannot free
+ * the old chunk of memory until all possible readers have finished.
+ * Currently, that's on connection close: in other words, we can use
+ * this because it's small amounts of memory, and we really, really do
+ * not want to acquire locks every time we access configuration strings,
+ * since that's done on every API call.
+ *
+ * Our caller is expected to be holding any locks we need.
*/
- WT_RET(__wt_calloc_def(
- session, conn->config_entries_count, &conn->config_entries_copy));
- memcpy(conn->config_entries_copy, conn->config_entries,
- conn->config_entries_count * sizeof(WT_CONFIG_ENTRY));
- conn->config_entries = conn->config_entries_copy;
+ /* Count the slots. */
+ va_start(ap, session);
+ for (cnt = 0; va_arg(ap, void *) != NULL; ++cnt)
+ ;
+ va_end(ap);
+
+ if (conn->foc_cnt + cnt >= conn->foc_size) {
+ WT_RET(__wt_realloc(session, NULL,
+ (conn->foc_size + cnt + 20) * sizeof(void *), &conn->foc));
+ conn->foc_size += cnt + 20;
+ }
+ va_start(ap, session);
+ while ((p = va_arg(ap, void *)) != NULL)
+ conn->foc[conn->foc_cnt++] = p;
+ va_end(ap);
return (0);
}
/*
- * __wt_conn_config_discard --
- * Discard the connection's configuration table.
+ * __wt_conn_foc_discard --
+ * Discard any memory the connection accumulated.
*/
void
-__wt_conn_config_discard(WT_SESSION_IMPL *session)
+__wt_conn_foc_discard(WT_SESSION_IMPL *session)
{
WT_CONNECTION_IMPL *conn;
- WT_CONFIG_ENTRY *ep, *f, *next;
+ size_t i;
conn = S2C(session);
/*
- * If we never extended the table, we never allocated a copy, we're
- * done.
+ * If we have a list of chunks to free, run through the list, then
+ * free the list itself.
*/
- if (conn->config_entries_copy == NULL)
- return;
-
- /* Free any extensions, then free the copied table. */
- for (ep = conn->config_entries_copy; ep->method != NULL; ++ep)
- for (f = ep->extend; f != NULL; f = next) {
- next = f->extend;
-
- __wt_free(session, f->method);
- __wt_free(session, f->uri);
- __wt_free(session, f->name);
- __wt_free(session, f->checks->name);
- __wt_free(session, f->checks->type);
- __wt_free(session, f->checks->checks);
- __wt_free(session, f);
- }
- __wt_free(session, conn->config_entries_copy);
+ for (i = 0; i < conn->foc_cnt; ++i)
+ __wt_free(session, conn->foc[i]);
+ __wt_free(session, conn->foc);
}
/*
@@ -77,24 +84,39 @@ __wt_conn_config_discard(WT_SESSION_IMPL *session)
int
__wt_configure_method(WT_SESSION_IMPL *session,
const char *method, const char *uri,
- const char *name, const char *type, const char *check)
+ const char *config, const char *type, const char *check)
{
+ const WT_CONFIG_CHECK *cp;
+ WT_CONFIG_CHECK *checks, *newcheck;
+ const WT_CONFIG_ENTRY **epp;
+ WT_CONFIG_ENTRY *entry;
WT_CONNECTION_IMPL *conn;
- WT_CONFIG_ENTRY *ep, *entry;
- WT_CONFIG_CHECK *checks;
WT_DECL_RET;
- char *p, *t;
+ size_t cnt;
+ char *newcheck_name, *p;
+
+ /*
+ * !!!
+ * We ignore the specified uri, that is, all new configuration options
+ * will be valid for all data sources. That's shouldn't be too bad
+ * as the worst that can happen is an application might specify some
+ * configuration option and not get an error -- the option should be
+ * ignored by the underlying implementation since it's unexpected, so
+ * there shouldn't be any real problems. Eventually I expect we will
+ * get the whole data-source thing sorted, at which time there may be
+ * configuration arrays for each data source, and that's when the uri
+ * will matter.
+ */
+ WT_UNUSED(uri);
conn = S2C(session);
+ checks = newcheck = NULL;
entry = NULL;
- checks = NULL;
+ newcheck_name = NULL;
- /*
- * Argument checking.
- * We only support a limited number of types.
- */
- if (name == NULL)
- WT_RET_MSG(session, EINVAL, "no configuration name specified");
+ /* Argument checking; we only support a limited number of types. */
+ if (config == NULL)
+ WT_RET_MSG(session, EINVAL, "no configuration specified");
if (type == NULL)
WT_RET_MSG(session, EINVAL, "no configuration type specified");
if (strcmp(type, "boolean") != 0 && strcmp(type, "int") != 0 &&
@@ -103,125 +125,112 @@ __wt_configure_method(WT_SESSION_IMPL *session,
"type must be one of \"boolean\", \"int\", \"list\" or "
"\"string\"");
- /*
- * If we haven't yet allocated our local copy of the configuration
- * information, do so now.
- */
- if (conn->config_entries_copy == NULL) {
- __wt_spin_lock(session, &conn->api_lock);
- ret = configure_copy(session);
- __wt_spin_unlock(session, &conn->api_lock);
- WT_RET(ret);
- }
-
- /* Find a match for the method. */
- for (ep = conn->config_entries_copy; ep->method != NULL; ++ep)
- if (strcmp(ep->method, method) == 0)
+ /* Find a match for the method name. */
+ for (epp = conn->config_entries; (*epp)->method != NULL; ++epp)
+ if (strcmp((*epp)->method, method) == 0)
break;
- if (ep == NULL)
+ if ((*epp)->method == NULL)
WT_RET_MSG(session,
WT_NOTFOUND, "no method matching %s found", method);
- /* Allocate an extension entry. */
+ /*
+ * Technically possible for threads to race, lock the connection while
+ * adding the new configuration information. We're holding the lock
+ * for an extended period of time, but configuration changes should be
+ * rare and only happen during startup.
+ */
+ __wt_spin_lock(session, &conn->api_lock);
+
+ /*
+ * Allocate new configuration entry and fill it in.
+ *
+ * The new base value is the previous base value, a separator and the
+ * new configuration string.
+ */
WT_ERR(__wt_calloc_def(session, 1, &entry));
- if (uri != NULL)
- WT_ERR(__wt_strdup(session, uri, &entry->uri));
- WT_ERR(__wt_strdup(session, name, &entry->name));
- WT_ERR(__wt_calloc_def(session, 2, &checks));
+ entry->method = (*epp)->method;
+ WT_ERR(__wt_calloc_def(session,
+ strlen((*epp)->base) + strlen(",") + strlen(config) + 1, &p));
+ (void)strcpy(p, (*epp)->base);
+ (void)strcat(p, ",");
+ (void)strcat(p, config);
+ entry->base = p;
+
/*
- * There may be a default value in the name specified, we don't that as
- * part of the checks name field.
+ * Build a new checks entry name field. There may be a default value
+ * in the config argument we're passed , we don't want that as part of
+ * the checks entry name field.
*/
- WT_ERR(__wt_strdup(session, name, &p));
- if ((t = strchr(p, '=')) != NULL)
- *t = '\0';
- checks->name = p;
- WT_ERR(__wt_strdup(session, type, &checks->type));
+ WT_ERR(__wt_strdup(session, config, &newcheck_name));
+ if ((p = strchr(newcheck_name, '=')) != NULL)
+ *p = '\0';
+
+ /*
+ * Build a new checks array. The new configuration name may replace
+ * an existing check with new information, in that case skip the old
+ * version.
+ */
+ for (cnt = 0, cp = (*epp)->checks; cp->name != NULL; ++cp)
+ ++cnt;
+ WT_ERR(__wt_calloc_def(session, cnt + 2, &checks));
+ for (cnt = 0, cp = (*epp)->checks; cp->name != NULL; ++cp)
+ if (strcmp(newcheck_name, cp->name) != 0)
+ checks[cnt++] = *cp;
+ newcheck = &checks[cnt];
+
+ newcheck->name = newcheck_name;
+ WT_ERR(__wt_strdup(session, type, &newcheck->type));
if (check != NULL)
- WT_ERR(__wt_strdup(session, check, &checks->checks));
+ WT_ERR(__wt_strdup(session, check, &newcheck->checks));
entry->checks = checks;
- /* Confirm the configuration string passes any checks we're given. */
- if (check != NULL)
- WT_ERR(config_check(session, checks, name, 0));
+ /* Confirm the configuration string passes the new set of checks. */
+ WT_ERR(config_check(session, entry->checks, config, 0));
/*
- * Technically possible for threads to race, lock the connection while
- * appending the new value to the method's linked list of configuration
- * information.
+ * The next time this configuration is updated, we don't want to figure
+ * out which of these pieces of memory were allocated and will need to
+ * be free'd on close, add them to the list now.
*/
- __wt_spin_lock(session, &conn->api_lock);
- while (ep->extend != NULL)
- ep = ep->extend;
- ep->extend = entry;
- __wt_spin_unlock(session, &conn->api_lock);
+ WT_ERR(__wt_conn_foc_add(session,
+ entry, entry->base,
+ checks, newcheck->name, newcheck->type, newcheck->checks, NULL));
- return (0);
+ *epp = entry;
-err: if (entry != NULL) {
- __wt_free(session, entry->method);
- __wt_free(session, entry->uri);
- __wt_free(session, entry->name);
- }
- if (checks != NULL) {
- __wt_free(session, checks->name);
- __wt_free(session, checks->type);
- __wt_free(session, checks->checks);
+ if (0) {
+err: if (entry != NULL) {
+ __wt_free(session, entry->base);
+ __wt_free(session, entry);
+ }
+ __wt_free(session, checks);
+ if (newcheck != NULL) {
+ __wt_free(session, newcheck->type);
+ __wt_free(session, newcheck->checks);
+ }
+ __wt_free(session, newcheck_name);
}
+
+ __wt_spin_unlock(session, &conn->api_lock);
return (ret);
}
/*
* __wt_config_check--
* Check the keys in an application-supplied config string match what is
- * specified in all of the entry's check strings.
+ * specified in an array of check strings.
*/
int
__wt_config_check(WT_SESSION_IMPL *session,
const WT_CONFIG_ENTRY *entry, const char *config, size_t config_len)
{
- const WT_CONFIG_CHECK *checks, *cp;
- const WT_CONFIG_ENTRY *ep;
- WT_CONFIG_CHECK *copy;
- WT_DECL_RET;
- size_t cnt;
-
- copy = NULL;
-
- /* It is always okay to not provide a configuration string. */
- if (config == NULL)
- return (0);
-
/*
- * If the call was ever extended build a combined set of checks. This
- * is slow, and it's per call to the configuration method, but I don't
- * see much reason to get fancy until this gets used a lot more than I
- * expect it will be.
- *
- * It's always okay to not provide any checks.
+ * Callers don't check, it's a fast call without a configuration or
+ * check array.
*/
- if (entry->extend == NULL) {
- if ((checks = entry->checks) == NULL)
- return (0);
- } else {
- for (cnt = 0, ep = entry; ep != NULL; ep = ep->extend)
- for (cp = ep->checks; cp->name != NULL; ++cp)
- ++cnt;
- if (cnt == 0)
- return (0);
- WT_RET(__wt_calloc_def(session, cnt + 1, &copy));
- for (cnt = 0, ep = entry; ep != NULL; ep = ep->extend)
- for (cp = ep->checks; cp->name != NULL; ++cp)
- copy[cnt++] = *cp;
- checks = copy;
- }
-
- ret = config_check(session, checks, config, config_len);
-
- if (copy != NULL)
- __wt_free(session, copy);
- return (ret);
+ return (config == NULL || entry->checks == NULL ?
+ 0 : config_check(session, entry->checks, config, config_len));
}
/*
diff --git a/src/config/config_def.c b/src/config/config_def.c
index 425cd9dd7d0..14993716a6d 100644
--- a/src/config/config_def.c
+++ b/src/config/config_def.c
@@ -250,69 +250,48 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = {
static const WT_CONFIG_ENTRY config_entries[] = {
{ "colgroup.meta",
- NULL,
"columns=,source=,type=file",
- confchk_colgroup_meta,
- NULL
+ confchk_colgroup_meta
},
{ "connection.add_collator",
- NULL,
"",
- NULL,
NULL
},
{ "connection.add_compressor",
- NULL,
"",
- NULL,
NULL
},
{ "connection.add_data_source",
- NULL,
"",
- NULL,
NULL
},
{ "connection.add_extractor",
- NULL,
"",
- NULL,
NULL
},
{ "connection.close",
- NULL,
"",
- NULL,
NULL
},
{ "connection.load_extension",
- NULL,
"entry=wiredtiger_extension_init,prefix=",
- confchk_connection_load_extension,
- NULL
+ confchk_connection_load_extension
},
{ "connection.open_session",
- NULL,
"isolation=read-committed",
- confchk_connection_open_session,
- NULL
+ confchk_connection_open_session
},
{ "connection.reconfigure",
- NULL,
"cache_size=100MB,error_prefix=,eviction_dirty_target=80,"
"eviction_target=80,eviction_trigger=95,shared_cache=(chunk=10MB,"
"name=pool,reserve=0,size=500MB),statistics=0,verbose=",
- confchk_connection_reconfigure,
- NULL
+ confchk_connection_reconfigure
},
{ "cursor.close",
- NULL,
"",
- NULL,
NULL
},
{ "file.meta",
- NULL,
"allocation_size=512B,block_compressor=,cache_resident=0,checkpoint=,"
"checksum=on,collator=,columns=,dictionary=0,format=btree,"
"huffman_key=,huffman_value=,internal_item_max=0,"
@@ -320,47 +299,33 @@ static const WT_CONFIG_ENTRY config_entries[] = {
",leaf_item_max=0,leaf_page_max=1MB,memory_page_max=5MB,"
"os_cache_dirty_max=0,os_cache_max=0,prefix_compression=,split_pct=75"
",value_format=u,version=(major=0,minor=0)",
- confchk_file_meta,
- NULL
+ confchk_file_meta
},
{ "index.meta",
- NULL,
"columns=,key_format=u,source=,type=file,value_format=u",
- confchk_index_meta,
- NULL
+ confchk_index_meta
},
{ "session.begin_transaction",
- NULL,
"isolation=,name=,priority=0,sync=full",
- confchk_session_begin_transaction,
- NULL
+ confchk_session_begin_transaction
},
{ "session.checkpoint",
- NULL,
"drop=,force=0,name=,target=",
- confchk_session_checkpoint,
- NULL
+ confchk_session_checkpoint
},
{ "session.close",
- NULL,
"",
- NULL,
NULL
},
{ "session.commit_transaction",
- NULL,
"",
- NULL,
NULL
},
{ "session.compact",
- NULL,
"trigger=30",
- confchk_session_compact,
- NULL
+ confchk_session_compact
},
{ "session.create",
- NULL,
"allocation_size=512B,block_compressor=,cache_resident=0,checksum=on,"
"colgroups=,collator=,columns=,dictionary=0,exclusive=0,format=btree,"
"huffman_key=,huffman_value=,internal_item_max=0,"
@@ -371,78 +336,54 @@ static const WT_CONFIG_ENTRY config_entries[] = {
"lsm_merge_threads=1,memory_page_max=5MB,os_cache_dirty_max=0,"
"os_cache_max=0,prefix_compression=,source=,split_pct=75,type=file,"
"value_format=u",
- confchk_session_create,
- NULL
+ confchk_session_create
},
{ "session.drop",
- NULL,
"force=0",
- confchk_session_drop,
- NULL
+ confchk_session_drop
},
{ "session.log_printf",
- NULL,
"",
- NULL,
NULL
},
{ "session.open_cursor",
- NULL,
"append=0,bulk=0,checkpoint=,dump=,next_random=0,overwrite=0,raw=0,"
"statistics_clear=0,statistics_fast=0,target=",
- confchk_session_open_cursor,
- NULL
+ confchk_session_open_cursor
},
{ "session.reconfigure",
- NULL,
"isolation=read-committed",
- confchk_session_reconfigure,
- NULL
+ confchk_session_reconfigure
},
{ "session.rename",
- NULL,
"",
- NULL,
NULL
},
{ "session.rollback_transaction",
- NULL,
"",
- NULL,
NULL
},
{ "session.salvage",
- NULL,
"force=0",
- confchk_session_salvage,
- NULL
+ confchk_session_salvage
},
{ "session.truncate",
- NULL,
"",
- NULL,
NULL
},
{ "session.upgrade",
- NULL,
"",
- NULL,
NULL
},
{ "session.verify",
- NULL,
"dump_address=0,dump_blocks=0,dump_pages=0",
- confchk_session_verify,
- NULL
+ confchk_session_verify
},
{ "table.meta",
- NULL,
"colgroups=,columns=,key_format=u,value_format=u",
- confchk_table_meta,
- NULL
+ confchk_table_meta
},
{ "wiredtiger_open",
- NULL,
"buffer_alignment=-1,cache_size=100MB,"
"checkpoint=(name=\"WiredTigerCheckpoint\",wait=0),create=0,"
"direct_io=,error_prefix=,eviction_dirty_target=80,eviction_target=80"
@@ -452,16 +393,39 @@ static const WT_CONFIG_ENTRY config_entries[] = {
"statistics=0,statistics_log=(clear=,path=\"WiredTigerStat.%H\","
"sources=,timestamp=\"%b %d %H:%M:%S\",wait=0),sync=,transactional=,"
"use_environment_priv=0,verbose=",
- confchk_wiredtiger_open,
- NULL
+ confchk_wiredtiger_open
},
- { NULL, NULL, NULL, NULL, NULL }
+ { NULL, NULL, NULL }
};
-void
+int
__wt_conn_config_init(WT_SESSION_IMPL *session)
{
- S2C(session)->config_entries = config_entries;
- S2C(session)->config_entries_count =
- sizeof(config_entries)/sizeof(config_entries[0]);
+ WT_CONNECTION_IMPL *conn;
+ const WT_CONFIG_ENTRY *ep, **epp;
+
+ conn = S2C(session);
+
+ /* Build a list of pointers to the configuration information. */
+ WT_RET(__wt_calloc_def(session,
+ sizeof(config_entries) / sizeof(config_entries[0]), &epp));
+ conn->config_entries = epp;
+
+ /* Fill in the list to reference the default information. */
+ for (ep = config_entries;;) {
+ *epp++ = ep++;
+ if (ep->method == NULL)
+ break;
+ }
+ return (0);
+}
+
+void
+__wt_conn_config_discard(WT_SESSION_IMPL *session)
+{
+ WT_CONNECTION_IMPL *conn;
+
+ conn = S2C(session);
+
+ __wt_free(session, conn->config_entries);
}
diff --git a/src/conn/conn_api.c b/src/conn/conn_api.c
index 84447f6d46f..cd4cb165c14 100644
--- a/src/conn/conn_api.c
+++ b/src/conn/conn_api.c
@@ -288,7 +288,7 @@ __conn_get_home(WT_CONNECTION *wt_conn)
*/
static int
__conn_configure_method(WT_CONNECTION *wt_conn, const char *method,
- const char *uri, const char *name, const char *type, const char *check)
+ const char *uri, const char *config, const char *type, const char *check)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
@@ -297,7 +297,7 @@ __conn_configure_method(WT_CONNECTION *wt_conn, const char *method,
conn = (WT_CONNECTION_IMPL *)wt_conn;
CONNECTION_API_CALL_NOCONF(conn, session, configure_method);
- ret = __wt_configure_method(session, method, uri, name, type, check);
+ ret = __wt_configure_method(session, method, uri, config, type, check);
err: API_END_NOTFOUND_MAP(session, ret);
}
@@ -586,7 +586,7 @@ __conn_config_file(WT_SESSION_IMPL *session, const char **cfg, WT_ITEM **cbufp)
/* Check the configuration string. */
WT_ERR(__wt_config_check(session,
- WT_CONFIG_CALL(session, wiredtiger_open), cbuf->data, 0));
+ WT_CONFIG_REF(session, wiredtiger_open), cbuf->data, 0));
/*
* The configuration file falls between the default configuration and
@@ -637,7 +637,7 @@ __conn_config_env(WT_SESSION_IMPL *session, const char **cfg)
/* Check the configuration string. */
WT_RET(__wt_config_check(session,
- WT_CONFIG_CALL(session, wiredtiger_open), env_config, 0));
+ WT_CONFIG_REF(session, wiredtiger_open), env_config, 0));
/*
* The environment setting comes second-to-last: it overrides the
@@ -888,8 +888,8 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler,
/* Check/set the configuration strings. */
WT_ERR(__wt_config_check(session,
- WT_CONFIG_CALL(session, wiredtiger_open), config, 0));
- cfg[0] = WT_CONFIG_NAME(session, wiredtiger_open);
+ WT_CONFIG_REF(session, wiredtiger_open), config, 0));
+ cfg[0] = WT_CONFIG_BASE(session, wiredtiger_open);
cfg[1] = config;
cfg[2] = NULL;
diff --git a/src/conn/conn_dhandle.c b/src/conn/conn_dhandle.c
index 367887498fd..99797c50d9b 100644
--- a/src/conn/conn_dhandle.c
+++ b/src/conn/conn_dhandle.c
@@ -258,7 +258,7 @@ __conn_btree_config_set(WT_SESSION_IMPL *session)
*/
WT_ERR(__wt_calloc_def(session, 3, &dhandle->cfg));
WT_ERR(__wt_strdup(
- session, WT_CONFIG_NAME(session, file_meta), &dhandle->cfg[0]));
+ session, WT_CONFIG_BASE(session, file_meta), &dhandle->cfg[0]));
dhandle->cfg[1] = metaconf;
metaconf = NULL;
return (0);
diff --git a/src/conn/conn_handle.c b/src/conn/conn_handle.c
index c237035c0aa..b7ea447a419 100644
--- a/src/conn/conn_handle.c
+++ b/src/conn/conn_handle.c
@@ -28,7 +28,7 @@ __wt_connection_init(WT_CONNECTION_IMPL *conn)
TAILQ_INIT(&conn->lsmqh); /* WT_LSM_TREE list */
/* Configuration. */
- __wt_conn_config_init(session);
+ WT_RET(__wt_conn_config_init(session));
/* Statistics. */
__wt_stat_init_connection_stats(&conn->stats);
@@ -84,8 +84,10 @@ __wt_connection_destroy(WT_CONNECTION_IMPL *conn)
TAILQ_REMOVE(&__wt_process.connqh, conn, q);
__wt_spin_unlock(session, &__wt_process.spinlock);
- /* Configuration. */
- __wt_conn_config_discard(session);
+ /* Configuration */
+ __wt_conn_config_discard(session); /* configuration */
+
+ __wt_conn_foc_discard(session); /* free-on-close */
__wt_spin_destroy(session, &conn->api_lock);
__wt_spin_destroy(session, &conn->fh_lock);
diff --git a/src/cursor/cur_dump.c b/src/cursor/cur_dump.c
index d11746cf9d7..1f29709a46c 100644
--- a/src/cursor/cur_dump.c
+++ b/src/cursor/cur_dump.c
@@ -327,7 +327,7 @@ __wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp)
/* __wt_cursor_init is last so we don't have to clean up on error. */
STATIC_ASSERT(offsetof(WT_CURSOR_DUMP, iface) == 0);
- cfg[0] = WT_CONFIG_NAME(session, session_open_cursor);
+ cfg[0] = WT_CONFIG_BASE(session, session_open_cursor);
cfg[1] = NULL;
WT_RET(__wt_cursor_init(cursor, NULL, owner, cfg, cursorp));
diff --git a/src/cursor/cur_table.c b/src/cursor/cur_table.c
index fd155a26e15..3f6a4f668af 100644
--- a/src/cursor/cur_table.c
+++ b/src/cursor/cur_table.c
@@ -691,7 +691,7 @@ __curtable_open_indices(WT_CURSOR_TABLE *ctable)
"Bulk load is not supported for tables with indices");
WT_RET(__wt_calloc_def(session, table->nindices, &ctable->idx_cursors));
- cfg[0] = WT_CONFIG_NAME(session, session_open_cursor);
+ cfg[0] = WT_CONFIG_BASE(session, session_open_cursor);
cfg[1] = NULL;
for (i = 0, cp = ctable->idx_cursors; i < table->nindices; i++, cp++)
WT_RET(__wt_open_cursor(session, table->indices[i]->source,
diff --git a/src/docs/custom_data.dox b/src/docs/custom_data.dox
index 2d756f800d7..51c65ed0161 100644
--- a/src/docs/custom_data.dox
+++ b/src/docs/custom_data.dox
@@ -182,11 +182,11 @@ could be used to extend the configuration arguments for a data source with
URIs beginning with the "my_data" prefix. A NULL value for the object type
implies all object types.
-- the name of the additional configuration string. The name can be supplied
-with a default value as well, by appending an equals sign and a value. For
-example, for a new configuration string with the name argument \c "device"
-the name arguments \c "device=/path" or \c "device=35" would give it default
-values.
+- the additional configuration string, which consists of the name of the
+configuration string and an optional default value. The default value
+is specified by appending an equals sign and a value. For example, for
+a new configuration string with the name \c "device", specifying either
+\c "device=/path" or \c "device=35" would configure the default values.
- the type of the additional configuration, which must one of \c "boolean",
\c "int", \c "list" or \c "string".
diff --git a/src/include/api.h b/src/include/api.h
index 90fbd48ca8f..1405fd67499 100644
--- a/src/include/api.h
+++ b/src/include/api.h
@@ -19,12 +19,12 @@
#define API_CALL(s, h, n, cur, dh, config, cfg) do { \
const char *cfg[] = \
- { WT_CONFIG_NAME(s, h##_##n), config, NULL }; \
+ { WT_CONFIG_BASE(s, h##_##n), config, NULL }; \
API_SESSION_INIT(s, h, n, cur, dh); \
WT_ERR(F_ISSET(S2C(s), WT_CONN_PANIC) ? __wt_panic(s) : 0); \
WT_ERR(((config) != NULL) ? \
__wt_config_check((s), \
- WT_CONFIG_CALL(session, h##_##n), (config), 0) : 0)
+ WT_CONFIG_REF(session, h##_##n), (config), 0) : 0)
#define API_END(s) \
if ((s) != NULL) { \
diff --git a/src/include/config.h b/src/include/config.h
index 35a047f48a1..2c794f328cb 100644
--- a/src/include/config.h
+++ b/src/include/config.h
@@ -29,18 +29,15 @@ struct __wt_config_check {
const WT_CONFIG_CHECK *subconfigs;
};
-#define WT_CONFIG_CALL(session, n) \
- (&S2C(session)->config_entries[WT_CONFIG_ENTRY_##n])
+#define WT_CONFIG_REF(session, n) \
+ (S2C(session)->config_entries[WT_CONFIG_ENTRY_##n])
struct __wt_config_entry {
const char *method; /* method name */
- const char *uri; /* uri or NULL if global */
-#define WT_CONFIG_NAME(session, n) (WT_CONFIG_CALL(session, n)->name)
- const char *name; /* configuration base */
+#define WT_CONFIG_BASE(session, n) (WT_CONFIG_REF(session, n)->base)
+ const char *base; /* configuration base */
const WT_CONFIG_CHECK *checks; /* check array */
-
- WT_CONFIG_ENTRY *extend; /* extended value */
};
/*
diff --git a/src/include/connection.h b/src/include/connection.h
index a5502bac1d8..f8ef5a8a7ea 100644
--- a/src/include/connection.h
+++ b/src/include/connection.h
@@ -66,10 +66,6 @@ struct __wt_named_data_source {
struct __wt_connection_impl {
WT_CONNECTION iface;
- u_int config_entries_count; /* Configuration table count and copy */
- const WT_CONFIG_ENTRY *config_entries;
- WT_CONFIG_ENTRY *config_entries_copy;
-
/* For operations without an application-supplied session */
WT_SESSION_IMPL *default_session;
WT_SESSION_IMPL dummy_session;
@@ -90,6 +86,13 @@ struct __wt_connection_impl {
int connection_initialized; /* Connection is initialized */
+ /* Configuration */
+ const WT_CONFIG_ENTRY **config_entries;
+
+ void **foc; /* Free-on-close array */
+ size_t foc_cnt; /* Array entries */
+ size_t foc_size; /* Array size */
+
WT_FH *lock_fh; /* Lock file handle */
pthread_t cache_evict_tid; /* Eviction server thread ID */
diff --git a/src/include/extern.h b/src/include/extern.h
index 3e493bc3e78..b9e25d206a1 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -495,11 +495,11 @@ extern int __wt_config_subgets(WT_SESSION_IMPL *session,
WT_CONFIG_ITEM *cfg,
const char *key,
WT_CONFIG_ITEM *value);
-extern void __wt_conn_config_discard(WT_SESSION_IMPL *session);
+extern void __wt_conn_foc_discard(WT_SESSION_IMPL *session);
extern int __wt_configure_method(WT_SESSION_IMPL *session,
const char *method,
const char *uri,
- const char *name,
+ const char *config,
const char *type,
const char *check);
extern int __wt_config_check(WT_SESSION_IMPL *session,
@@ -512,7 +512,8 @@ extern int __wt_config_collapse( WT_SESSION_IMPL *session,
extern int __wt_config_concat( WT_SESSION_IMPL *session,
const char **cfg,
const char **config_ret);
-extern void __wt_conn_config_init(WT_SESSION_IMPL *session);
+extern int __wt_conn_config_init(WT_SESSION_IMPL *session);
+extern void __wt_conn_config_discard(WT_SESSION_IMPL *session);
extern int __wt_conn_btree_sync_and_close(WT_SESSION_IMPL *session);
extern int __wt_conn_btree_get(WT_SESSION_IMPL *session,
const char *name,
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index dc88e9e3934..eb269fa81a3 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -1101,7 +1101,7 @@ struct __wt_connection {
* @param connection the connection handle
* @param method the name of the method
* @param uri the object type or NULL for all object types
- * @param name the additional configuration's name and default value
+ * @param config the additional configuration's name and default value
* @param type the additional configuration's type (must be one of
* \c "boolean"\, \c "int", \c "list" or \c "string")
* @param check the additional configuration check string, or NULL if
@@ -1110,7 +1110,7 @@ struct __wt_connection {
*/
int __F(configure_method)(WT_CONNECTION *connection,
const char *method, const char *uri,
- const char *name, const char *type, const char *check);
+ const char *config, const char *type, const char *check);
/*! Return if opening this handle created the database.
*
diff --git a/src/include/wiredtiger_ext.h b/src/include/wiredtiger_ext.h
index df7e8665555..0c756f8dfbe 100644
--- a/src/include/wiredtiger_ext.h
+++ b/src/include/wiredtiger_ext.h
@@ -18,28 +18,42 @@ extern "C" {
* WT_EXTENSION_API::config.
*/
struct __wt_extension_config {
- /*! The memory reference of a configuration string.
+ /*! The value of a configuration string.
*
- * Regardless of the type of the configuration string, the \c str field
- * will reference the value of the configuration string. Note the bytes
- * referenced by \c str <b>may not</b> be nul-terminated, use the \c len
- * field instead of a terminating nul byte.
+ * Regardless of the type of the configuration string (boolean, int,
+ * list or string), the \c str field will reference the value of the
+ * configuration string.
+ *
+ * The bytes referenced by \c str may <b>not</b> be nul-terminated,
+ * use the \c len field instead of a terminating nul byte.
*/
const char *str;
- /*! The number of bytes in the string referenced by \c str. */
+ /*! The number of bytes in the value referenced by \c str. */
size_t len;
/*! The value of a configuration boolean or integer.
*
- * If the configuration string is set to "true" or "false", the \c value
- * field will be set to 1 (true), or 0 (false).
+ * If the configuration string's value is "true" or "false", the
+ * \c value field will be set to 1 (true), or 0 (false).
*
* If the configuration string can be legally interpreted as an integer,
* using the strtoll function rules as specified in ISO/IEC 9899:1990
* ("ISO C90"), that integer will be stored in the \c value field.
*/
int64_t value;
+
+ /*! The value of a configuration list.
+ *
+ * If the configuration string type is of type list, the \c argv field
+ * will reference a NULL-terminated array of pointers to nul-terminated
+ * strings.
+ *
+ * The argv array, and each string it references, will be returned in
+ * allocated memory; both the strings and the array must be freed by
+ * the application to avoid memory leaks.
+ */
+ char **argv;
};
/*! @addtogroup wt_ext
@@ -86,6 +100,8 @@ struct __wt_extension_api {
* @param session the session handle
* @param fmt a printf-like format specification
* @errors
+ *
+ * @snippet ex_data_source.c WT_EXTENSION_API err_printf
*/
int (*err_printf)(WT_SESSION *session, const char *fmt, ...);
@@ -94,6 +110,8 @@ struct __wt_extension_api {
* @param session the session handle
* @param bytes the number of bytes of memory needed
* @returns A valid memory reference on success or NULL on error
+ *
+ * @snippet ex_data_source.c WT_EXTENSION_API scr_alloc
*/
void *(*scr_alloc)(WT_SESSION *session, size_t bytes);
@@ -101,6 +119,8 @@ struct __wt_extension_api {
*
* @param session the session handle
* @param ref a memory reference returned by WT_EXTENSION_API::scr_alloc
+ *
+ * @snippet ex_data_source.c WT_EXTENSION_API scr_free
*/
void (*scr_free)(WT_SESSION *session, void *ref);
@@ -109,6 +129,8 @@ struct __wt_extension_api {
* @param session the session handle
* @param fmt a printf-like format specification
* @errors
+ *
+ * @snippet ex_data_source.c WT_EXTENSION_API msg_printf
*/
int (*msg_printf)(WT_SESSION *session, const char *fmt, ...);
@@ -120,6 +142,8 @@ struct __wt_extension_api {
* WT_DATA_SOURCE:: method
* @param value the returned value
* @errors
+ *
+ * @snippet ex_data_source.c WT_EXTENSION_CONFIG string
*/
int (*config)(WT_SESSION *session,
const char *key, void *config, WT_EXTENSION_CONFIG *value);
diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c
index 6e5ec8b935f..a15028fcb6e 100644
--- a/src/lsm/lsm_cursor.c
+++ b/src/lsm/lsm_cursor.c
@@ -123,7 +123,7 @@ __clsm_open_cursors(
c = &clsm->iface;
chunk = NULL;
- cfg[0] = WT_CONFIG_NAME(session, session_open_cursor);
+ cfg[0] = WT_CONFIG_BASE(session, session_open_cursor);
cfg[1] = "checkpoint=WiredTigerCheckpoint,raw";
cfg[2] = NULL;
diff --git a/src/lsm/lsm_merge.c b/src/lsm/lsm_merge.c
index d8fc40f7b42..adc28a61db2 100644
--- a/src/lsm/lsm_merge.c
+++ b/src/lsm/lsm_merge.c
@@ -232,7 +232,7 @@ __wt_lsm_merge(
lsm_tree->bloom_hash_count, &bloom));
}
- cfg[0] = WT_CONFIG_NAME(session, session_open_cursor);
+ cfg[0] = WT_CONFIG_BASE(session, session_open_cursor);
cfg[1] = "bulk,raw";
cfg[2] = NULL;
WT_ERR(__wt_open_cursor(session, chunk->uri, NULL, cfg, &dest));
@@ -283,7 +283,7 @@ __wt_lsm_merge(
* enough internal pages in cache so that application threads don't
* stall and block each other reading them in.
*/
- cfg[0] = WT_CONFIG_NAME(session, session_open_cursor);
+ cfg[0] = WT_CONFIG_BASE(session, session_open_cursor);
cfg[1] = "checkpoint=WiredTigerCheckpoint,next_random";
cfg[2] = NULL;
WT_ERR(__wt_open_cursor(session, chunk->uri, NULL, cfg, &dest));
diff --git a/src/lsm/lsm_stat.c b/src/lsm/lsm_stat.c
index a72c9c18e4c..ef371a6f116 100644
--- a/src/lsm/lsm_stat.c
+++ b/src/lsm/lsm_stat.c
@@ -23,10 +23,10 @@ __wt_lsm_stat_init(WT_SESSION_IMPL *session,
uint64_t value;
u_int i;
int locked, stat_key;
- const char *cfg[] = { WT_CONFIG_NAME(
+ const char *cfg[] = { WT_CONFIG_BASE(
session, session_open_cursor), "statistics_fast=on", NULL };
const char *disk_cfg[] =
- { WT_CONFIG_NAME(session, session_open_cursor),
+ { WT_CONFIG_BASE(session, session_open_cursor),
"checkpoint=WiredTigerCheckpoint,statistics_fast=on", NULL };
const char *desc, *pvalue;
diff --git a/src/lsm/lsm_tree.c b/src/lsm/lsm_tree.c
index d248f0a8a6c..9cf5ddc22d1 100644
--- a/src/lsm/lsm_tree.c
+++ b/src/lsm/lsm_tree.c
@@ -210,7 +210,7 @@ __wt_lsm_tree_setup_chunk(
{
WT_ITEM buf;
const char *cfg[] =
- { WT_CONFIG_NAME(session, session_drop), "force", NULL };
+ { WT_CONFIG_BASE(session, session_drop), "force", NULL };
WT_CLEAR(buf);
@@ -295,7 +295,7 @@ __wt_lsm_tree_create(WT_SESSION_IMPL *session,
WT_DECL_RET;
WT_LSM_TREE *lsm_tree;
const char *cfg[] =
- { WT_CONFIG_NAME(session, session_create), config, NULL };
+ { WT_CONFIG_BASE(session, session_create), config, NULL };
const char *tmpconfig;
/* If the tree is open, it already exists. */
@@ -411,7 +411,7 @@ __lsm_tree_open_check(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
WT_CONFIG_ITEM cval;
uint64_t required;
uint32_t maxleafpage;
- const char *cfg[] = { WT_CONFIG_NAME(
+ const char *cfg[] = { WT_CONFIG_BASE(
session, session_create), lsm_tree->file_config, NULL };
WT_RET(__wt_config_gets(session, cfg, "leaf_page_max", &cval));
diff --git a/src/lsm/lsm_worker.c b/src/lsm/lsm_worker.c
index d6b2de29427..bc07c2253b3 100644
--- a/src/lsm/lsm_worker.c
+++ b/src/lsm/lsm_worker.c
@@ -293,7 +293,7 @@ __lsm_bloom_create(
lsm_tree->bloom_config, chunk->count,
lsm_tree->bloom_bit_count, lsm_tree->bloom_hash_count, &bloom));
- cfg[0] = WT_CONFIG_NAME(session, session_open_cursor);
+ cfg[0] = WT_CONFIG_BASE(session, session_open_cursor);
cfg[1] = "raw";
cfg[2] = NULL;
WT_ERR(__wt_open_cursor(session, chunk->uri, NULL, cfg, &src));
@@ -338,7 +338,7 @@ __lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
u_int i;
int locked, progress;
const char *drop_cfg[] =
- { WT_CONFIG_NAME(session, session_drop), NULL };
+ { WT_CONFIG_BASE(session, session_drop), NULL };
locked = progress = 0;
for (i = 0; i < lsm_tree->nold_chunks; i++) {
diff --git a/src/meta/meta_table.c b/src/meta/meta_table.c
index c9b65efad11..3bcf8e588db 100644
--- a/src/meta/meta_table.c
+++ b/src/meta/meta_table.c
@@ -107,7 +107,7 @@ __wt_metadata_cursor(
WT_DATA_HANDLE *saved_dhandle;
WT_DECL_RET;
const char *cfg[] =
- { WT_CONFIG_NAME(session, session_open_cursor), config, NULL };
+ { WT_CONFIG_BASE(session, session_open_cursor), config, NULL };
saved_dhandle = session->dhandle;
WT_ERR(__wt_metadata_open(session));
diff --git a/src/meta/meta_turtle.c b/src/meta/meta_turtle.c
index e82f86a6af7..fedd0ff01f8 100644
--- a/src/meta/meta_turtle.c
+++ b/src/meta/meta_turtle.c
@@ -40,7 +40,7 @@ __wt_meta_turtle_init(WT_SESSION_IMPL *session, int *existp)
WT_ERR(__wt_buf_fmt(session, buf,
"key_format=S,value_format=S,version=(major=%d,minor=%d)",
WT_BTREE_MAJOR_VERSION, WT_BTREE_MINOR_VERSION));
- cfg[0] = WT_CONFIG_NAME(session, file_meta);
+ cfg[0] = WT_CONFIG_BASE(session, file_meta);
cfg[1] = buf->data;
cfg[2] = NULL;
WT_ERR(__wt_config_collapse(session, cfg, &metaconf));
diff --git a/src/schema/schema_create.c b/src/schema/schema_create.c
index 07c5968b87e..f3ad20ecc7a 100644
--- a/src/schema/schema_create.c
+++ b/src/schema/schema_create.c
@@ -46,7 +46,7 @@ __create_file(WT_SESSION_IMPL *session,
WT_ERR(__wt_scr_alloc(session, 0, &val));
WT_ERR(__wt_buf_fmt(session, val, "version=(major=%d,minor=%d)",
WT_BTREE_MAJOR_VERSION, WT_BTREE_MINOR_VERSION));
- filecfg[0] = WT_CONFIG_NAME(session, file_meta);
+ filecfg[0] = WT_CONFIG_BASE(session, file_meta);
filecfg[1] = config;
filecfg[2] = val->data;
filecfg[3] = NULL;
@@ -117,7 +117,7 @@ __create_colgroup(WT_SESSION_IMPL *session,
WT_TABLE *table;
size_t tlen;
const char *cfg[4] =
- { WT_CONFIG_NAME(session, colgroup_meta), config, NULL, NULL };
+ { WT_CONFIG_BASE(session, colgroup_meta), config, NULL, NULL };
const char *sourcecfg[] = { config, NULL, NULL };
const char **cfgp;
const char *cgconf, *cgname, *sourceconf, *oldconf;
@@ -247,7 +247,7 @@ __create_index(WT_SESSION_IMPL *session,
WT_ITEM confbuf, extra_cols, fmt, namebuf;
WT_TABLE *table;
const char *cfg[4] =
- { WT_CONFIG_NAME(session, index_meta), NULL, NULL, NULL };
+ { WT_CONFIG_BASE(session, index_meta), NULL, NULL, NULL };
const char *sourcecfg[] = { config, NULL, NULL };
const char *sourceconf, *source, *idxconf, *idxname;
const char *tablename;
@@ -379,7 +379,7 @@ __create_table(WT_SESSION_IMPL *session,
int ncolgroups;
char *cgname;
const char *cfg[4] =
- { WT_CONFIG_NAME(session, table_meta), config, NULL, NULL };
+ { WT_CONFIG_BASE(session, table_meta), config, NULL, NULL };
const char *tableconf, *tablename;
cgname = NULL;
diff --git a/src/session/session_api.c b/src/session/session_api.c
index 85e64060fe2..08a63f56d97 100644
--- a/src/session/session_api.c
+++ b/src/session/session_api.c
@@ -260,7 +260,7 @@ __wt_session_create_strip(WT_SESSION *wt_session,
{
WT_SESSION_IMPL *session = (WT_SESSION_IMPL *)wt_session;
const char *cfg[] =
- { WT_CONFIG_NAME(session, session_create), v1, v2, NULL };
+ { WT_CONFIG_BASE(session, session_create), v1, v2, NULL };
return (__wt_config_collapse(session, cfg, value_ret));
}