diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-07-30 17:03:03 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-07-30 17:03:03 +1000 |
commit | e19efc8a25b1444803b6eccaf3ce4fec6d27fb6c (patch) | |
tree | f619a346a3c9aa107096d712f8dad8d74cda9a56 | |
parent | 7ab7511c5b456d03cbff0b450b410674aabcedbf (diff) | |
download | mongo-e19efc8a25b1444803b6eccaf3ce4fec6d27fb6c.tar.gz |
One simple optimization for __wt_config_get: don't process unused values.
-rw-r--r-- | src/config/config.c | 190 |
1 files changed, 102 insertions, 88 deletions
diff --git a/src/config/config.c b/src/config/config.c index 0ff4ef2629e..f160e6056b2 100644 --- a/src/config/config.c +++ b/src/config/config.c @@ -14,7 +14,7 @@ static int __config_err(WT_CONFIG *conf, const char *msg, int err) { - WT_RET_MSG(conf->session, err == 0 ? EINVAL : err, + WT_RET_MSG(conf->session, err, "Error parsing '%.*s' at byte %u: %s", (int)(conf->end - conf->orig), conf->orig, (u_int)(conf->cur - conf->orig), msg); @@ -73,7 +73,8 @@ __wt_config_subinit( if (conf->depth == conf->top) { \ if (out->len > 0) \ return (__config_err(conf, \ - "New value starts without a separator", 0));\ + "New value starts without a separator", \ + EINVAL)); \ out->type = (t); \ out->str = (conf->cur + (i)); \ } \ @@ -333,87 +334,11 @@ static int8_t goesc[256] = { }; /* - * __process_value - * Deal with special config values like true / false. + * __config_next -- + * Get the next config item in the string without processing the value. */ static int -__process_value(WT_CONFIG *conf, WT_CONFIG_ITEM *value) -{ - char *endptr; - - /* Empty values are okay: we can't do anything interesting with them. */ - if (value->len == 0) - return (0); - - if (value->type == ITEM_ID) { - if (strncasecmp(value->str, "true", value->len) == 0) { - value->type = ITEM_NUM; - value->val = 1; - } else if (strncasecmp(value->str, "false", value->len) == 0) { - value->type = ITEM_NUM; - value->val = 0; - } - } else if (value->type == ITEM_NUM) { - errno = 0; - value->val = strtoll(value->str, &endptr, 10); - - /* Check any leftover characters. */ - while (endptr < value->str + value->len) - switch (*endptr++) { - case 'b': - case 'B': - /* Byte: no change. */ - break; - case 'k': - case 'K': - value->val <<= 10; - break; - case 'm': - case 'M': - value->val <<= 20; - break; - case 'g': - case 'G': - value->val <<= 30; - break; - case 't': - case 'T': - value->val <<= 40; - break; - case 'p': - case 'P': - value->val <<= 50; - break; - default: - /* - * We didn't get a well-formed number. That - * might be okay, the required type will be - * checked by __wt_config_check. - */ - value->type = ITEM_ID; - break; - } - - /* - * If we parsed the the whole string but the number is out of - * range, report an error. Don't report an error for strings - * that aren't well-formed integers: if an integer is expected, - * that will be caught by __wt_config_check. - */ - if (value->type == ITEM_NUM && errno == ERANGE) - return ( - __config_err(conf, "Number out of range", ERANGE)); - } - - return (0); -} - -/* - * __wt_config_next -- - * Get the next config item in the string. - */ -int -__wt_config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) +__config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) { WT_CONFIG_ITEM *out = key; int utf8_remain = 0; @@ -433,7 +358,8 @@ __wt_config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) break; case A_BAD: - return (__config_err(conf, "Unexpected character", 0)); + return (__config_err( + conf, "Unexpected character", EINVAL)); case A_DOWN: --conf->depth; @@ -455,7 +381,7 @@ __wt_config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) */ if (out == value && *conf->cur != ':') return (__config_err(conf, - "Value already complete", 0)); + "Value already complete", EINVAL)); out = value; } break; @@ -467,7 +393,7 @@ __wt_config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) */ if (conf->depth == conf->top && key->len > 0) { ++conf->cur; - goto val; + return (0); } else break; @@ -536,14 +462,101 @@ __wt_config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) /* Did we find something? */ if (conf->depth <= conf->top && key->len > 0) -val: return (__process_value(conf, value)); + return (0); /* We're either at the end of the string or we failed to parse. */ if (conf->depth == 0) return (WT_NOTFOUND); return (__config_err(conf, - "Closing brackets missing from config string", 0)); + "Closing brackets missing from config string", EINVAL)); +} + +/* + * __config_process_value + * Deal with special config values like true / false. + */ +static int +__config_process_value(WT_CONFIG *conf, WT_CONFIG_ITEM *value) +{ + char *endptr; + + /* Empty values are okay: we can't do anything interesting with them. */ + if (value->len == 0) + return (0); + + if (value->type == ITEM_ID) { + if (strncasecmp(value->str, "true", value->len) == 0) { + value->type = ITEM_NUM; + value->val = 1; + } else if (strncasecmp(value->str, "false", value->len) == 0) { + value->type = ITEM_NUM; + value->val = 0; + } + } else if (value->type == ITEM_NUM) { + errno = 0; + value->val = strtoll(value->str, &endptr, 10); + + /* Check any leftover characters. */ + while (endptr < value->str + value->len) + switch (*endptr++) { + case 'b': + case 'B': + /* Byte: no change. */ + break; + case 'k': + case 'K': + value->val <<= 10; + break; + case 'm': + case 'M': + value->val <<= 20; + break; + case 'g': + case 'G': + value->val <<= 30; + break; + case 't': + case 'T': + value->val <<= 40; + break; + case 'p': + case 'P': + value->val <<= 50; + break; + default: + /* + * We didn't get a well-formed number. That + * might be okay, the required type will be + * checked by __wt_config_check. + */ + value->type = ITEM_ID; + break; + } + + /* + * If we parsed the the whole string but the number is out of + * range, report an error. Don't report an error for strings + * that aren't well-formed integers: if an integer is expected, + * that will be caught by __wt_config_check. + */ + if (value->type == ITEM_NUM && errno == ERANGE) + return ( + __config_err(conf, "Number out of range", ERANGE)); + } + + return (0); +} + +/* + * __wt_config_next -- + * Get the next config item in the string and process the value. + */ +int +__wt_config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) +{ + WT_RET(__config_next(conf, key, value)); + return (__config_process_value(conf, value)); } /* @@ -559,7 +572,7 @@ __wt_config_getraw( int found; found = 0; - while ((ret = __wt_config_next(cparser, &k, &v)) == 0) { + while ((ret = __config_next(cparser, &k, &v)) == 0) { if ((k.type == ITEM_STRING || k.type == ITEM_ID) && key->len == k.len && strncasecmp(key->str, k.str, k.len) == 0) { @@ -568,7 +581,8 @@ __wt_config_getraw( } } - return (found && ret == WT_NOTFOUND ? 0 : ret); + return ((found && ret == WT_NOTFOUND) ? + __config_process_value(cparser, value) : ret); } /* |