diff --git a/nova/api/validation/parameter_types.py b/nova/api/validation/parameter_types.py index 8c54c1993d58..57f8fb1e63f8 100644 --- a/nova/api/validation/parameter_types.py +++ b/nova/api/validation/parameter_types.py @@ -16,6 +16,7 @@ Common parameter types for validating request Body. """ import copy +import functools import re import unicodedata @@ -24,6 +25,27 @@ import six from nova.i18n import _ from nova.objects import tag +_REGEX_RANGE_CACHE = {} + + +def memorize(func): + + @functools.wraps(func) + def memorizer(*args, **kwargs): + global _REGEX_RANGE_CACHE + key = "%s:%s:%s" % (func.__name__, hash(str(args)), hash(str(kwargs))) + value = _REGEX_RANGE_CACHE.get(key) + if value is None: + value = func(*args, **kwargs) + _REGEX_RANGE_CACHE[key] = value + return value + return memorizer + + +def _reset_cache(): + global _REGEX_RANGE_CACHE + _REGEX_RANGE_CACHE = {} + def single_param(schema): """Macro function for use in JSONSchema to support query parameters that @@ -83,6 +105,7 @@ def _get_all_chars(): # constraint fails and this causes issues for some unittests when # PYTHONHASHSEED is set randomly. +@memorize def _build_regex_range(ws=True, invert=False, exclude=None): """Build a range regex for a set of characters in utf8. diff --git a/nova/tests/unit/test_api_validation.py b/nova/tests/unit/test_api_validation.py index 7c6bad7424da..db202276c899 100644 --- a/nova/tests/unit/test_api_validation.py +++ b/nova/tests/unit/test_api_validation.py @@ -95,7 +95,9 @@ class ValidationRegex(test.NoDBTestCase): self.useFixture(fixtures.MonkeyPatch( 'nova.api.validation.parameter_types._get_all_chars', _get_all_chars)) - + # note that since we use only the ascii range in the tests + # we have to clear the cache to recompute them. + parameter_types._reset_cache() r = parameter_types._build_regex_range(ws=False) self.assertEqual(r, re.escape('!') + '-' + re.escape('~'))