add some optimisations

This commit is contained in:
2015-12-22 22:06:14 +01:00
parent 93ce93e529
commit df233d3165
6 changed files with 123 additions and 106 deletions

View File

@ -101,23 +101,26 @@ class Base(StorageBase):
allow_empty_list=undefined):
if not valid_name(name): # pragma: optional cover
raise ValueError(_("invalid name: {0} for option").format(name))
if requires is not None:
calc_properties, requires = validate_requires_arg(
requires, name)
else:
calc_properties = frozenset()
requires = undefined
if not multi and default_multi is not None: # pragma: optional cover
raise ValueError(_("default_multi is set whereas multi is False"
" in option: {0}").format(name))
if multi is True:
is_multi = True
_multi = 0
elif multi is False:
is_multi = False
_multi = 1
elif multi is submulti:
is_multi = True
_multi = submulti
else:
raise ValueError(_('invalid multi value'))
if requires is not None:
calc_properties, requires = validate_requires_arg(is_multi,
requires, name)
else:
calc_properties = frozenset()
requires = undefined
if properties is None:
properties = tuple()
if not isinstance(properties, tuple): # pragma: optional cover
@ -139,8 +142,8 @@ class Base(StorageBase):
allow_empty_list)
if multi is not False and default is None:
default = []
self.impl_validate(default, is_multi=_multi != 1)
self._set_default_values(default, default_multi, _multi != 1)
self.impl_validate(default, is_multi=is_multi)
self._set_default_values(default, default_multi, is_multi)
##callback is False in optiondescription
if callback is not False:
self.impl_set_callback(callback, callback_params, _init=True)
@ -792,7 +795,7 @@ class Option(OnlyOption):
"is calculated").format(self.impl_getname()))
def validate_requires_arg(requires, name):
def validate_requires_arg(multi, requires, name):
"""check malformed requirements
and tranform dict to internal tuple
@ -848,6 +851,10 @@ def validate_requires_arg(requires, name):
if not isinstance(option, Option): # pragma: optional cover
raise ValueError(_('malformed requirements '
'must be an option in option {0}').format(name))
if not multi and option.impl_is_multi():
raise ValueError(_('malformed requirements '
'multi option must not set '
'as requires of non multi option {0}').format(name))
if expected is not None:
try:
option._validate(expected)
@ -911,7 +918,7 @@ class SymLinkOption(OnlyOption):
del(self._stated)
except AttributeError: # pragma: optional cover
pass
self._set_readonly()
self._set_readonly(True)
def impl_get_information(self, key, default=undefined):
return self._impl_getopt().impl_get_information(key, default)

View File

@ -78,7 +78,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
_setattr(self, '_cache_consistencies', None)
# the group_type is useful for filtering OptionDescriptions in a config
_setattr(self, '_group_type', groups.default)
_setattr(self, '_is_build_cache', False)
def impl_getdoc(self):
return self.impl_get_information('doc')
@ -93,16 +92,25 @@ class OptionDescription(BaseOption, StorageOptionDescription):
"""
return _impl_getpaths(self, include_groups, _currpath)
def impl_build_cache_consistency(self, _consistencies=None, cache_option=None):
if _consistencies is None:
def impl_build_cache(self, _consistencies=None, cache_option=None):
"""validate duplicate option and set option has readonly option
"""
if cache_option is None:
init = True
_consistencies = {}
cache_option = []
else:
init = False
for option in self._impl_getchildren(dyn=False):
#FIXME specifique id for sqlalchemy?
#FIXME avec sqlalchemy ca marche le multi parent ? (dans des configs différentes)
cache_option.append(option._get_id())
if not isinstance(option, OptionDescription):
if isinstance(option, OptionDescription):
option._set_readonly(False)
option.impl_build_cache(_consistencies, cache_option)
#cannot set multi option as OptionDescription requires
else:
option._set_readonly(True)
for func, all_cons_opts, params in option._get_consistencies():
all_cons_opts[0]._valid_consistencies(all_cons_opts[1:])
for opt in all_cons_opts:
@ -110,53 +118,46 @@ class OptionDescription(BaseOption, StorageOptionDescription):
[]).append((func,
all_cons_opts,
params))
else:
option.impl_build_cache_consistency(_consistencies, cache_option)
if init and _consistencies != {}:
self._cache_consistencies = {}
for opt, cons in _consistencies.items():
if opt._get_id() not in cache_option: # pragma: optional cover
raise ConfigError(_('consistency with option {0} '
'which is not in Config').format(
opt.impl_getname()))
self._cache_consistencies[opt] = tuple(cons)
def impl_validate_options(self, cache_option=None):
"""validate duplicate option and set option has readonly option
"""
if cache_option is None:
init = True
cache_option = []
else:
init = False
for option in self._impl_getchildren(dyn=False):
#FIXME specifique id for sqlalchemy?
#FIXME avec sqlalchemy ca marche le multi parent ? (dans des configs différentes)
oid = option._get_id()
cache_option.append(oid)
option._set_readonly()
if isinstance(option, OptionDescription):
option.impl_validate_options(cache_option)
if option.impl_getrequires() != []:
for requires in option.impl_getrequires():
for require in requires:
if require[0].impl_is_multi():
if option.impl_is_master_slaves('slave') and require[0].impl_is_master_slaves():
if option.impl_get_master_slaves() != require[0].impl_get_master_slaves():
raise ValueError(_('malformed requirements option {0} '
'must be in same master/slaves for {1}').format(
require[0].impl_getname(), option.impl_getname()))
else:
raise ValueError(_('malformed requirements option {0} '
'must not be a multi for {1}').format(
require[0].impl_getname(), option.impl_getname()))
is_slave = None
if option.impl_is_multi():
all_requires = option.impl_getrequires()
if all_requires != tuple():
for requires in all_requires:
for require in requires:
#if option in require is a multi:
# * option in require must be a master or a slave
# * current option must be a slave (and only a slave)
# * option in require and current option must be in same master/slaves
require_opt = require[0]
if require_opt.impl_is_multi():
if is_slave is None:
is_slave = option.impl_is_master_slaves('slave')
if is_slave:
masterslaves = option.impl_get_master_slaves()
if is_slave and require_opt.impl_is_master_slaves():
if masterslaves != require_opt.impl_get_master_slaves():
raise ValueError(_('malformed requirements option {0} '
'must be in same master/slaves for {1}').format(
require_opt.impl_getname(), option.impl_getname()))
else:
raise ValueError(_('malformed requirements option {0} '
'must not be a multi for {1}').format(
require_opt.impl_getname(), option.impl_getname()))
if init:
if len(cache_option) != len(set(cache_option)):
for idx in xrange(1, len(cache_option) + 1):
opt = cache_option.pop(0)
if opt in cache_option:
raise ConflictError(_('duplicate option: {0}').format(opt))
self._set_readonly()
if _consistencies != {}:
self._cache_consistencies = {}
for opt, cons in _consistencies.items():
if opt._get_id() not in cache_option: # pragma: optional cover
raise ConfigError(_('consistency with option {0} '
'which is not in Config').format(
opt.impl_getname()))
self._cache_consistencies[opt] = tuple(cons)
self._set_readonly(False)
# ____________________________________________________________
def impl_set_group_type(self, group_type):
@ -182,8 +183,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
:param descr: parent :class:`tiramisu.option.OptionDescription`
"""
if descr is None:
#FIXME faut le desactiver ?
#self.impl_build_cache_consistency()
self.impl_build_cache_option()
descr = self
super(OptionDescription, self)._impl_getstate(descr)