summaryrefslogtreecommitdiff
path: root/bench/wtperf/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'bench/wtperf/config.c')
-rw-r--r--bench/wtperf/config.c140
1 files changed, 118 insertions, 22 deletions
diff --git a/bench/wtperf/config.c b/bench/wtperf/config.c
index 5b14a4cdf68..e4eee66e4cb 100644
--- a/bench/wtperf/config.c
+++ b/bench/wtperf/config.c
@@ -215,6 +215,7 @@ config_threads(WTPERF *wtperf, const char *config, size_t len)
return (EINVAL);
}
workp = &wtperf->workload[wtperf->workload_cnt++];
+ workp->table_index = INT32_MAX;
while ((ret = scan->next(scan, &k, &v)) == 0) {
if (STRING_MATCH("count", k.str, k.len)) {
@@ -233,12 +234,28 @@ config_threads(WTPERF *wtperf, const char *config, size_t len)
goto err;
continue;
}
+ if (STRING_MATCH("pause", k.str, k.len)) {
+ if ((workp->pause = v.val) < 0)
+ goto err;
+ continue;
+ }
if (STRING_MATCH("read", k.str, k.len) ||
STRING_MATCH("reads", k.str, k.len)) {
if ((workp->read = v.val) < 0)
goto err;
continue;
}
+ if (STRING_MATCH("read_range", k.str, k.len)) {
+ if ((workp->read_range = v.val) < 0)
+ goto err;
+ continue;
+ }
+ if (STRING_MATCH("table", k.str, k.len)) {
+ if (v.val <= 0)
+ goto err;
+ workp->table_index = (int32_t)v.val - 1;
+ continue;
+ }
if (STRING_MATCH("throttle", k.str, k.len)) {
workp->throttle = (uint64_t)v.val;
continue;
@@ -421,14 +438,13 @@ config_opt(WTPERF *wtperf, WT_CONFIG_ITEM *k, WT_CONFIG_ITEM *v)
return (EINVAL);
}
strp = (char **)valueloc;
- newlen = v->len + 1;
if (*strp == NULL)
begin = newstr = dstrdup(v->str);
else {
- newlen += strlen(*strp) + 1;
- newstr = dcalloc(newlen, sizeof(char));
- snprintf(newstr, newlen,
- "%s,%*s", *strp, (int)v->len, v->str);
+ newlen = strlen(*strp) + v->len + strlen(",") + 1;
+ newstr = dmalloc(newlen);
+ testutil_check(__wt_snprintf(newstr, newlen,
+ "%s,%.*s", *strp, (int)v->len, v->str));
/* Free the old value now we've copied it. */
free(*strp);
begin = &newstr[(newlen - 1) - v->len];
@@ -622,17 +638,9 @@ config_opt_str(WTPERF *wtperf, const char *optstr)
return (ret);
}
- /*
- * Append the current line to our copy of the config. The config is
- * stored in the order it is processed, so added options will be after
- * any parsed from the original config. We allocate len + 1 to allow for
- * a null byte to be added.
- */
- config_line = dcalloc(sizeof(CONFIG_QUEUE_ENTRY), 1);
- config_line->string = dstrdup(optstr);
- TAILQ_INSERT_TAIL(&opts->config_head, config_line, q);
-
while (ret == 0) {
+ size_t pos;
+
if ((ret = scan->next(scan, &k, &v)) != 0) {
/* Any parse error has already been reported. */
if (ret == WT_NOTFOUND)
@@ -640,6 +648,46 @@ config_opt_str(WTPERF *wtperf, const char *optstr)
break;
}
ret = config_opt(wtperf, &k, &v);
+
+ /*
+ * Append the key-value pair to our copy of the config.
+ * The config is stored in the order it is processed, so added
+ * options will be after any parsed from the original config.
+ */
+ config_line = dcalloc(sizeof(CONFIG_QUEUE_ENTRY), 1);
+ /*
+ * If key or value is a string, consider extra space for the
+ * quotes. Add 2 to the required space for '=' and the ending
+ * null character in "key=value".
+ */
+ config_line->string = dcalloc(
+ k.len + (k.type == WT_CONFIG_ITEM_STRING ? 2 : 0) +
+ v.len + (v.type == WT_CONFIG_ITEM_STRING ? 2 : 0) + 2, 1);
+ pos = 0;
+ if (k.type == WT_CONFIG_ITEM_STRING) {
+ config_line->string[pos] = '"';
+ pos++;
+ }
+ strncpy(config_line->string + pos, k.str, k.len);
+ pos += k.len;
+ if (k.type == WT_CONFIG_ITEM_STRING) {
+ config_line->string[pos] = '"';
+ pos++;
+ }
+ config_line->string[pos] = '=';
+ pos++;
+ if (v.type == WT_CONFIG_ITEM_STRING) {
+ config_line->string[pos] = '"';
+ pos++;
+ }
+ strncpy(config_line->string + pos, v.str, v.len);
+ pos += v.len;
+ if (v.type == WT_CONFIG_ITEM_STRING) {
+ config_line->string[pos] = '"';
+ pos++;
+ }
+ config_line->string[pos] = '\0';
+ TAILQ_INSERT_TAIL(&opts->config_head, config_line, q);
}
if ((t_ret = scan->close(scan)) != 0) {
lprintf(wtperf, ret, 0, "Error in config_scan_end");
@@ -663,7 +711,7 @@ config_opt_name_value(WTPERF *wtperf, const char *name, const char *value)
/* name="value" */
len = strlen(name) + strlen(value) + 4;
optstr = dmalloc(len);
- snprintf(optstr, len, "%s=\"%s\"", name, value);
+ testutil_check(__wt_snprintf(optstr, len, "%s=\"%s\"", name, value));
ret = config_opt_str(wtperf, optstr);
free(optstr);
return (ret);
@@ -728,16 +776,33 @@ config_sanity(WTPERF *wtperf)
opts->value_sz_min = opts->value_sz;
}
- if (opts->readonly && wtperf->workload != NULL)
+ if (wtperf->workload != NULL)
for (i = 0, workp = wtperf->workload;
- i < wtperf->workload_cnt; ++i, ++workp)
- if (workp->insert != 0 || workp->update != 0 ||
- workp->truncate != 0) {
+ i < wtperf->workload_cnt; ++i, ++workp) {
+ if (opts->readonly &&
+ (workp->insert != 0 || workp->update != 0 ||
+ workp->truncate != 0)) {
fprintf(stderr,
"Invalid workload: insert, update or "
"truncate specified with readonly\n");
return (EINVAL);
}
+ if (workp->insert != 0 &&
+ workp->table_index != INT32_MAX) {
+ fprintf(stderr,
+ "Invalid workload: Cannot insert into "
+ "specific table only\n");
+ return (EINVAL);
+ }
+ if (workp->table_index != INT32_MAX &&
+ workp->table_index >= (int32_t)opts->table_count) {
+ fprintf(stderr,
+ "Workload table index %" PRId32
+ " is larger than table count %" PRId32,
+ workp->table_index, opts->table_count);
+ return (EINVAL);
+ }
+ }
return (0);
}
@@ -754,8 +819,11 @@ config_consolidate(CONFIG_OPTS *opts)
/*
* This loop iterates over the config queue and for each entry checks if
- * a later queue entry has the same key. If there's a match, the current
- * queue entry is removed and we continue.
+ * a later queue entry has the same key. If there's a match, and key is
+ * "conn_config" or "table_config", the later queue entry is replaced
+ * with a concatenated entry of the two queue entries, the current queue
+ * entry is removed. For any other key, if there is a match, the current
+ * queue entry is removed.
*/
conf_line = TAILQ_FIRST(&opts->config_head);
while (conf_line != NULL) {
@@ -771,6 +839,34 @@ config_consolidate(CONFIG_OPTS *opts)
if (strncmp(conf_line->string, test_line->string,
(size_t)((string_key - conf_line->string) + 1))
== 0) {
+ if ((strncmp("conn_config=", conf_line->string,
+ (size_t)((string_key - conf_line->string) +
+ 1)) == 0) ||
+ (strncmp("table_config=", conf_line->string,
+ (size_t)((string_key - conf_line->string) +
+ 1)) == 0)) {
+ char *concat_str, *val_pointer;
+
+ /*
+ * To concatenate the two config
+ * strings, copy the first string to a
+ * new one, replace the ending '"' with
+ * a ',' and then concatenate the second
+ * string's value after its starting '"'
+ */
+ val_pointer =
+ strchr(test_line->string, '=') + 2;
+ concat_str =
+ dmalloc(strlen(conf_line->string) +
+ strlen(val_pointer) + 1);
+ strcpy(concat_str, conf_line->string);
+ concat_str[strlen(concat_str) - 1] =
+ ',';
+ strcat(concat_str, val_pointer);
+ free(test_line->string);
+ test_line->string = concat_str;
+ }
+
TAILQ_REMOVE(&opts->config_head, conf_line, q);
free(conf_line->string);
free(conf_line);