optimize
This commit is contained in:
parent
4df36a5548
commit
620e8bbf2e
10 changed files with 231 additions and 219 deletions
|
@ -709,7 +709,7 @@ def test_groups_with_leader_importation():
|
|||
maconfig = OptionDescription('toto', '', [interface1])
|
||||
api = Config(maconfig)
|
||||
api.property.read_write()
|
||||
api.value.importation((('ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0',), (None, (0, 1)), (('192.168.1.1', '192.168.1.0'), ('255.255.255.255', '255.255.255.0')), ('user', ('user', 'user'))))
|
||||
api.value.importation([['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'], [None, [0, 1]], [['192.168.1.1', '192.168.1.0'], ['255.255.255.255', '255.255.255.0']], ['user', ['user', 'user']]])
|
||||
api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1', '192.168.1.0']
|
||||
api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.255'
|
||||
api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == '255.255.255.0'
|
||||
|
|
133
tiramisu/api.py
133
tiramisu/api.py
|
@ -101,12 +101,12 @@ class CommonTiramisu(TiramisuHelp):
|
|||
raise APIError('index must be set only with a follower option')
|
||||
self._length = self._subconfig.cfgimpl_get_length_leadership(self._option_bag)
|
||||
if index >= self._length:
|
||||
raise LeadershipError(_('index "{}" is higher than the leadership length "{}" '
|
||||
raise LeadershipError(_('index "{}" is greater than the leadership length "{}" '
|
||||
'for option "{}"').format(index,
|
||||
self._length,
|
||||
option.impl_get_display_name()))
|
||||
if not self._allow_optiondescription and option.impl_is_optiondescription():
|
||||
raise APIError(_('option must not be an optiondescription'))
|
||||
if not self._allow_optiondescription and option.impl_is_optiondescription():
|
||||
raise APIError(_('option must not be an optiondescription'))
|
||||
return option
|
||||
|
||||
|
||||
|
@ -118,7 +118,8 @@ class CommonTiramisuOption(CommonTiramisu):
|
|||
def __init__(self,
|
||||
name: str,
|
||||
subconfig: Union[KernelConfig, SubConfig],
|
||||
option_bag: OptionBag) -> None:
|
||||
option_bag: OptionBag,
|
||||
config: 'Config'=None) -> None:
|
||||
self._option_bag = option_bag
|
||||
self._name = name
|
||||
self._subconfig = subconfig
|
||||
|
@ -136,7 +137,7 @@ class CommonTiramisuOption(CommonTiramisu):
|
|||
raise APIError(_('index must be set with the follower option "{}"').format(self._option_bag.path))
|
||||
|
||||
def __getattr__(self, name):
|
||||
raise APIError(_('unknown method {}').format(name))
|
||||
raise APIError(_('unknown method {} in {}').format(name, self.__class__.__name__))
|
||||
|
||||
|
||||
class _TiramisuOptionOptionDescription(CommonTiramisuOption):
|
||||
|
@ -144,6 +145,14 @@ class _TiramisuOptionOptionDescription(CommonTiramisuOption):
|
|||
_allow_optiondescription = True
|
||||
_follower_need_index = False
|
||||
|
||||
def __init__(self,
|
||||
name: str,
|
||||
subconfig: Union[KernelConfig, SubConfig],
|
||||
option_bag: OptionBag,
|
||||
config: "Subconfig") -> None:
|
||||
super().__init__(name, subconfig, option_bag)
|
||||
self._config = config
|
||||
|
||||
def get(self):
|
||||
"""Get Tiramisu option"""
|
||||
return self._option_bag.option
|
||||
|
@ -195,27 +204,22 @@ class _TiramisuOptionOptionDescription(CommonTiramisuOption):
|
|||
only_raises=False):
|
||||
"""Get properties for an option"""
|
||||
settings = self._option_bag.config_bag.context.cfgimpl_get_settings()
|
||||
properties = settings.getproperties(self._option_bag,
|
||||
apply_requires=False)
|
||||
if not only_raises:
|
||||
return properties
|
||||
return settings.getproperties(self._option_bag,
|
||||
apply_requires=False)
|
||||
# do not check cache properties/permissives which are not save (unrestraint, ...)
|
||||
return settings.calc_raises_properties(properties,
|
||||
settings.get_context_properties(),
|
||||
settings.get_context_properties())
|
||||
return settings.calc_raises_properties(self._option_bag,
|
||||
apply_requires=False)
|
||||
|
||||
def __call__(self,
|
||||
path: str,
|
||||
name: str,
|
||||
index: Optional[int]=None) -> 'TiramisuOption':
|
||||
"""Select an option by path"""
|
||||
subpath = self._option_bag.option.impl_getname() + '.' + path
|
||||
subconfig, name = self._subconfig.cfgimpl_get_home_by_path(subpath,
|
||||
self._option_bag.config_bag)
|
||||
path = self._option_bag.path + '.' + path
|
||||
path = self._option_bag.path + '.' + name
|
||||
return TiramisuOption(name,
|
||||
path,
|
||||
index,
|
||||
subconfig,
|
||||
self._config,
|
||||
self._option_bag.config_bag)
|
||||
|
||||
|
||||
|
@ -288,18 +292,18 @@ class TiramisuOptionOption(CommonTiramisuOption):
|
|||
def __new__(cls,
|
||||
name,
|
||||
subconfig,
|
||||
option_bag):
|
||||
option = subconfig.cfgimpl_get_description().get_child(name,
|
||||
option_bag.config_bag,
|
||||
subconfig.cfgimpl_get_path())
|
||||
if option.impl_is_optiondescription():
|
||||
option_bag,
|
||||
config):
|
||||
if option_bag.option.impl_is_optiondescription():
|
||||
return _TiramisuOptionOptionDescription(name=name,
|
||||
subconfig=subconfig,
|
||||
option_bag=option_bag)
|
||||
option_bag=option_bag,
|
||||
config=config)
|
||||
else:
|
||||
return _TiramisuOptionOption(name=name,
|
||||
subconfig=subconfig,
|
||||
option_bag=option_bag)
|
||||
option_bag=option_bag,
|
||||
config=config)
|
||||
|
||||
|
||||
class TiramisuOptionOwner(CommonTiramisuOption):
|
||||
|
@ -309,7 +313,8 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
|||
def __init__(self,
|
||||
name: str,
|
||||
subconfig: Union[KernelConfig, SubConfig],
|
||||
option_bag: OptionBag) -> None:
|
||||
option_bag: OptionBag,
|
||||
config: Optional['SubConfig']) -> None:
|
||||
|
||||
super().__init__(name,
|
||||
subconfig,
|
||||
|
@ -348,7 +353,8 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
|||
def __init__(self,
|
||||
name: str,
|
||||
subconfig: Union[KernelConfig, SubConfig],
|
||||
option_bag: OptionBag) -> None:
|
||||
option_bag: OptionBag,
|
||||
config: Optional['SubConfig']) -> None:
|
||||
super().__init__(name,
|
||||
subconfig,
|
||||
option_bag)
|
||||
|
@ -360,13 +366,10 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
|||
"""Get properties for an option"""
|
||||
option = self._option_bag.option
|
||||
self._test_follower_index()
|
||||
properties = self._option_bag.properties
|
||||
if not only_raises:
|
||||
return properties
|
||||
return self._option_bag.properties
|
||||
# do not check cache properties/permissives which are not save (unrestraint, ...)
|
||||
return self._settings.calc_raises_properties(properties,
|
||||
self._settings.get_context_properties(),
|
||||
self._settings.get_context_properties())
|
||||
return self._settings.calc_raises_properties(self._option_bag)
|
||||
|
||||
def add(self, prop):
|
||||
"""Add new property for an option"""
|
||||
|
@ -406,7 +409,8 @@ class TiramisuOptionPermissive(CommonTiramisuOption):
|
|||
def __init__(self,
|
||||
name: str,
|
||||
subconfig: Union[KernelConfig, SubConfig],
|
||||
option_bag: OptionBag) -> None:
|
||||
option_bag: OptionBag,
|
||||
config: Optional['SubConfig']) -> None:
|
||||
super().__init__(name,
|
||||
subconfig,
|
||||
option_bag)
|
||||
|
@ -554,6 +558,7 @@ class _TiramisuOptionValueChoiceOption:
|
|||
|
||||
|
||||
class _TiramisuOptionValueOptionDescription:
|
||||
|
||||
def dict(self,
|
||||
flatten=False,
|
||||
withvalue=undefined,
|
||||
|
@ -583,32 +588,35 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
|||
def __new__(cls,
|
||||
name,
|
||||
subconfig,
|
||||
option_bag):
|
||||
if subconfig is not None:
|
||||
option_bag,
|
||||
config):
|
||||
types = [CommonTiramisuOption]
|
||||
if option_bag.option and option_bag.option.impl_is_optiondescription():
|
||||
types.append(_TiramisuOptionValueOptionDescription)
|
||||
elif subconfig is not None:
|
||||
option = subconfig.cfgimpl_get_description().get_child(name,
|
||||
option_bag.config_bag,
|
||||
subconfig.cfgimpl_get_path())
|
||||
else:
|
||||
option = None
|
||||
types = [CommonTiramisuOption]
|
||||
if option:
|
||||
if option.impl_is_optiondescription():
|
||||
types.append(_TiramisuOptionValueOptionDescription)
|
||||
else:
|
||||
types.append(_TiramisuOptionValueOption)
|
||||
if isinstance(option, ChoiceOption):
|
||||
types.append(_TiramisuOptionValueChoiceOption)
|
||||
if option.impl_is_leader():
|
||||
types.append(_TiramisuOptionValueLeader)
|
||||
elif option.impl_is_follower():
|
||||
types.append(_TiramisuOptionValueFollower)
|
||||
types.append(_TiramisuOptionValueOption)
|
||||
if isinstance(option, ChoiceOption):
|
||||
types.append(_TiramisuOptionValueChoiceOption)
|
||||
if option.impl_is_leader():
|
||||
types.append(_TiramisuOptionValueLeader)
|
||||
elif option.impl_is_follower():
|
||||
types.append(_TiramisuOptionValueFollower)
|
||||
if option_bag.config_bag.context.impl_type == 'group':
|
||||
types.append(_TiramisuOptionValueGroup)
|
||||
new_type_dict = {'_allow_optiondescription': cls._allow_optiondescription,
|
||||
'_follower_need_index': cls._follower_need_index}
|
||||
new_type = type('TiramisuOptionValue', tuple(types), new_type_dict)(name=name,
|
||||
subconfig=subconfig,
|
||||
option_bag=option_bag)
|
||||
if option_bag.option and option_bag.option.impl_is_optiondescription():
|
||||
new_type = type('TiramisuOptionValue', tuple(types), new_type_dict)(name=name,
|
||||
subconfig=subconfig,
|
||||
option_bag=option_bag,
|
||||
config=config)
|
||||
else:
|
||||
new_type = type('TiramisuOptionValue', tuple(types), new_type_dict)(name=name,
|
||||
subconfig=subconfig,
|
||||
option_bag=option_bag)
|
||||
new_type.__doc__ = cls.__doc__
|
||||
return new_type
|
||||
|
||||
|
@ -642,14 +650,31 @@ class _TiramisuOption(CommonTiramisu):
|
|||
self._option_bag.index = self._index
|
||||
self._option_bag.config_bag = self._config_bag
|
||||
self._tiramisu_dict = None
|
||||
self._config = None
|
||||
if not self._registers:
|
||||
_registers(self._registers, 'TiramisuOption')
|
||||
|
||||
def _get_config(self):
|
||||
if self._config is None and self._subconfig is not None:
|
||||
self._config = self._subconfig.get_subconfig(self._option_bag)
|
||||
return self._config
|
||||
|
||||
def __getattr__(self, subfunc: str) -> Any:
|
||||
if subfunc in self._registers:
|
||||
subconfig = self._subconfig
|
||||
if subconfig:
|
||||
option_bag = self._option_bag
|
||||
option = self._get_option()
|
||||
if option.impl_is_optiondescription() and subfunc == 'option':
|
||||
config = self._get_config()
|
||||
else:
|
||||
config = None
|
||||
else:
|
||||
config = None
|
||||
return self._registers[subfunc](self._name,
|
||||
self._subconfig,
|
||||
self._option_bag)
|
||||
subconfig,
|
||||
self._option_bag,
|
||||
config)
|
||||
raise APIError(_('please specify a valid sub function ({})').format(subfunc)) # pragma: no cover
|
||||
|
||||
|
||||
|
@ -1240,7 +1265,7 @@ class _TiramisuContextConfigReset():
|
|||
"""Remove all datas to current config (informations, values, properties, ...)"""
|
||||
# Option's values
|
||||
context_owner = self._config_bag.context.cfgimpl_get_values().get_context_owner()
|
||||
self._config_bag.context.cfgimpl_get_values()._p_.importation((tuple(), tuple(), tuple(), tuple()))
|
||||
self._config_bag.context.cfgimpl_get_values()._p_.importation(([], [], [], []))
|
||||
self._config_bag.context.cfgimpl_get_values()._p_.setvalue(None,
|
||||
None,
|
||||
context_owner,
|
||||
|
|
|
@ -254,18 +254,20 @@ def carry_out_calculation(option,
|
|||
if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \
|
||||
option.impl_is_follower():
|
||||
if args or kwargs:
|
||||
raise LeadershipError(_('function "{}" with arguments "{}" and "{}" '
|
||||
'return the list "{}" for the follower option "{}"'
|
||||
raise LeadershipError(_('the "{}" function with positional arguments "{}" '
|
||||
'and keyword arguments "{}" must not return '
|
||||
'a list ("{}") for the follower option "{}"'
|
||||
'').format(callback.__name__,
|
||||
args,
|
||||
kwargs,
|
||||
ret,
|
||||
option.impl_get_display_name()))
|
||||
else:
|
||||
raise LeadershipError(_('function "{}" return the list "{}" for the follower option "{}"'
|
||||
raise LeadershipError(_('the "{}" function must not return a list ("{}") '
|
||||
'for the follower option "{}"'
|
||||
'').format(callback.__name__,
|
||||
ret,
|
||||
option.impl_getname()))
|
||||
option.impl_get_display_name()))
|
||||
return ret
|
||||
|
||||
|
||||
|
|
|
@ -281,7 +281,8 @@ class SubConfig(object):
|
|||
|
||||
def getattr(self,
|
||||
name,
|
||||
option_bag):
|
||||
option_bag,
|
||||
from_follower=False):
|
||||
"""
|
||||
attribute notation mechanism for accessing the value of an option
|
||||
:param name: attribute name
|
||||
|
@ -310,17 +311,18 @@ class SubConfig(object):
|
|||
return context.getattr(soption_bag.path,
|
||||
soption_bag)
|
||||
|
||||
self.cfgimpl_get_settings().validate_properties(option_bag)
|
||||
if not from_follower or option_bag.option.impl_getrequires():
|
||||
self.cfgimpl_get_settings().validate_properties(option_bag)
|
||||
|
||||
if option.impl_is_follower():
|
||||
if option.impl_is_follower() and not from_follower:
|
||||
length = self.cfgimpl_get_length_leadership(option_bag)
|
||||
follower_len = self.cfgimpl_get_values()._p_.get_max_length(option_bag.path)
|
||||
if follower_len > length:
|
||||
raise LeadershipError(_('follower option "{}" has higher length "{}" than the leader '
|
||||
'length "{}"').format(option.impl_get_display_name(),
|
||||
follower_len,
|
||||
length,
|
||||
option_bag.index))
|
||||
raise LeadershipError(_('the follower option "{}" has greater length ({}) than the leader '
|
||||
'length ({})').format(option.impl_get_display_name(),
|
||||
follower_len,
|
||||
length,
|
||||
option_bag.index))
|
||||
if option.impl_is_follower() and option_bag.index is None:
|
||||
value = []
|
||||
for idx in range(length):
|
||||
|
@ -332,7 +334,8 @@ class SubConfig(object):
|
|||
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
|
||||
try:
|
||||
value.append(self.getattr(name,
|
||||
soption_bag))
|
||||
soption_bag,
|
||||
from_follower=True))
|
||||
except PropertiesOptionError as err:
|
||||
value.append(err)
|
||||
else:
|
||||
|
|
|
@ -54,7 +54,7 @@ class BroadcastOption(Option):
|
|||
warnings_only,
|
||||
context):
|
||||
if len(vals) != 3:
|
||||
raise ConfigError(_('invalid len for vals'))
|
||||
raise ConfigError(_('invalid broadcast consistency, a network and a netmask are needed'))
|
||||
if None in vals:
|
||||
return
|
||||
broadcast, network, netmask = vals
|
||||
|
|
|
@ -121,6 +121,7 @@ class OptionBag:
|
|||
'config_bag',
|
||||
'ori_option', # original option (for example useful for symlinkoption)
|
||||
'properties', # properties of current option
|
||||
'properties_setted',
|
||||
'apply_requires', # apply requires or not for this option
|
||||
'fromconsistency' # history for consistency
|
||||
)
|
||||
|
@ -151,8 +152,15 @@ class OptionBag:
|
|||
return self.option
|
||||
elif key == 'apply_requires':
|
||||
return True
|
||||
elif key == 'properties_setted':
|
||||
return False
|
||||
raise KeyError('unknown key {} for OptionBag'.format(key)) # pragma: no cover
|
||||
|
||||
def __setattr__(self, key, val):
|
||||
super().__setattr__(key, val)
|
||||
if key == 'properties':
|
||||
self.properties_setted = True
|
||||
|
||||
def __delattr__(self, key):
|
||||
if key in ['properties', 'permissives']:
|
||||
try:
|
||||
|
@ -379,12 +387,12 @@ class Settings(object):
|
|||
# get properties and permissive methods
|
||||
|
||||
def get_context_properties(self):
|
||||
is_cached, props = self._p_.getcache(None,
|
||||
None,
|
||||
None,
|
||||
{},
|
||||
{},
|
||||
'context_props')
|
||||
is_cached, props, validated = self._p_.getcache(None,
|
||||
None,
|
||||
None,
|
||||
{},
|
||||
{},
|
||||
'context_props')
|
||||
if not is_cached:
|
||||
props = self._p_.getproperties(None,
|
||||
self.default_properties)
|
||||
|
@ -392,7 +400,8 @@ class Settings(object):
|
|||
None,
|
||||
props,
|
||||
{},
|
||||
props)
|
||||
props,
|
||||
True)
|
||||
return props
|
||||
|
||||
def getproperties(self,
|
||||
|
@ -410,12 +419,12 @@ class Settings(object):
|
|||
|
||||
if apply_requires:
|
||||
props = config_bag.properties
|
||||
is_cached, props = self._p_.getcache(path,
|
||||
config_bag.expiration_time,
|
||||
index,
|
||||
props,
|
||||
{},
|
||||
'self_props')
|
||||
is_cached, props, validated = self._p_.getcache(path,
|
||||
config_bag.expiration_time,
|
||||
index,
|
||||
props,
|
||||
{},
|
||||
'self_props')
|
||||
else:
|
||||
is_cached = False
|
||||
if not is_cached:
|
||||
|
@ -431,7 +440,8 @@ class Settings(object):
|
|||
index,
|
||||
props,
|
||||
props,
|
||||
config_bag.properties)
|
||||
config_bag.properties,
|
||||
True)
|
||||
return props
|
||||
|
||||
def get_context_permissives(self):
|
||||
|
@ -744,13 +754,18 @@ class Settings(object):
|
|||
#____________________________________________________________
|
||||
# validate properties
|
||||
def calc_raises_properties(self,
|
||||
option_properties,
|
||||
config_properties,
|
||||
config_permissives):
|
||||
properties = option_properties & config_properties - SPECIAL_PROPERTIES
|
||||
option_bag,
|
||||
apply_requires=True):
|
||||
raises_properties = option_bag.config_bag.properties - SPECIAL_PROPERTIES
|
||||
# remove global permissive properties
|
||||
if properties and ('permissive' in config_properties):
|
||||
properties -= config_permissives
|
||||
if raises_properties and ('permissive' in raises_properties):
|
||||
raises_properties -= option_bag.config_bag.permissives
|
||||
if apply_requires and option_bag.properties_setted:
|
||||
option_properties = option_bag.properties
|
||||
else:
|
||||
option_properties = self.getproperties(option_bag,
|
||||
apply_requires=apply_requires)
|
||||
properties = option_properties & raises_properties
|
||||
# at this point an option should not remain in properties
|
||||
return properties
|
||||
|
||||
|
@ -764,11 +779,9 @@ class Settings(object):
|
|||
was present
|
||||
"""
|
||||
config_bag = option_bag.config_bag
|
||||
if not config_bag.properties: # pragma: no cover
|
||||
if not config_bag.properties or config_bag.properties == frozenset(['cache']): # pragma: no cover
|
||||
return
|
||||
properties = self.calc_raises_properties(option_bag.properties,
|
||||
config_bag.properties,
|
||||
config_bag.permissives)
|
||||
properties = self.calc_raises_properties(option_bag)
|
||||
if properties != frozenset():
|
||||
raise PropertiesOptionError(option_bag,
|
||||
properties,
|
||||
|
|
4
tiramisu/storage/cache/dictionary.py
vendored
4
tiramisu/storage/cache/dictionary.py
vendored
|
@ -22,8 +22,8 @@ class Cache(object):
|
|||
def __init__(self):
|
||||
self._cache = {}
|
||||
|
||||
def _setcache(self, path, index, val, time):
|
||||
self._cache.setdefault(path, {})[index] = (val, int(time))
|
||||
def _setcache(self, path, index, val, time, validated):
|
||||
self._cache.setdefault(path, {})[index] = (val, int(time), validated)
|
||||
|
||||
def _getcache(self, path, index):
|
||||
values = self._cache.get(path)
|
||||
|
|
|
@ -20,6 +20,8 @@ from ...setting import undefined
|
|||
from ...i18n import _
|
||||
from ...log import log
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
|
||||
class Values(Cache):
|
||||
__slots__ = ('_values',
|
||||
|
@ -30,7 +32,7 @@ class Values(Cache):
|
|||
"""init plugin means create values storage
|
||||
"""
|
||||
#(('path1',), (index1,), (value1,), ('owner1'))
|
||||
self._values = (tuple(), tuple(), tuple(), tuple())
|
||||
self._values = ([], [], [], [])
|
||||
self._informations = {}
|
||||
# should init cache too
|
||||
super(Values, self).__init__(storage)
|
||||
|
@ -38,33 +40,30 @@ class Values(Cache):
|
|||
def commit(self):
|
||||
pass
|
||||
|
||||
def _setvalue_info(self, nb, idx, value, values, index, vidx):
|
||||
lst = list(self._values[nb])
|
||||
if idx is None:
|
||||
if index is None or nb == 0:
|
||||
lst.append(value)
|
||||
else:
|
||||
lst.append((value,))
|
||||
def _setvalue_info(self, nb, idx, value, index, follower_idx=None):
|
||||
lst = self._values[nb]
|
||||
if index is None or nb == 0:
|
||||
# not follower or path
|
||||
lst[idx] = value
|
||||
else:
|
||||
if index is None or nb == 0:
|
||||
lst[idx] = value
|
||||
# follower
|
||||
if nb == 1 and index in lst[idx]:
|
||||
follower_idx = lst[idx].index(index)
|
||||
tval = list(lst[idx])
|
||||
if follower_idx is None:
|
||||
tval.append(value)
|
||||
else:
|
||||
if nb == 1:
|
||||
if index in lst[idx]:
|
||||
vidx = lst[idx].index(index)
|
||||
else:
|
||||
vidx = None
|
||||
if vidx is None:
|
||||
tval = list(lst[idx])
|
||||
tval.append(value)
|
||||
lst[idx] = tuple(tval)
|
||||
elif nb != 1:
|
||||
tval = list(lst[idx])
|
||||
tval[vidx] = value
|
||||
lst[idx] = tuple(tval)
|
||||
lst[idx] = tuple(lst[idx])
|
||||
values.append(tuple(lst))
|
||||
return vidx
|
||||
tval[follower_idx] = value
|
||||
lst[idx] = tval
|
||||
return follower_idx
|
||||
|
||||
def _add_new_value(self, index, nb, value):
|
||||
if index is None or nb == 0:
|
||||
# not follower or path
|
||||
self._values[nb].append(value)
|
||||
else:
|
||||
# follower
|
||||
self._values[nb].append([value])
|
||||
|
||||
# value
|
||||
def setvalue(self,
|
||||
|
@ -77,20 +76,20 @@ class Values(Cache):
|
|||
a specified value must be associated to an owner
|
||||
"""
|
||||
log.debug('setvalue %s %s %s %s %s', path, value, owner, index, id(self))
|
||||
values = []
|
||||
vidx = None
|
||||
|
||||
#if isinstance(value, list):
|
||||
# value = value
|
||||
if path in self._values[0]:
|
||||
idx = self._values[0].index(path)
|
||||
self._setvalue_info(0, idx, path, index)
|
||||
follower_idx = self._setvalue_info(1, idx, index, index)
|
||||
self._setvalue_info(2, idx, value, index, follower_idx)
|
||||
self._setvalue_info(3, idx, owner, index, follower_idx)
|
||||
else:
|
||||
idx = None
|
||||
vidx = self._setvalue_info(0, idx, path, values, index, vidx)
|
||||
vidx = self._setvalue_info(1, idx, index, values, index, vidx)
|
||||
if isinstance(value, list):
|
||||
value = tuple(value)
|
||||
vidx = self._setvalue_info(2, idx, value, values, index, vidx)
|
||||
self._setvalue_info(3, idx, owner, values, index, vidx)
|
||||
self._values = tuple(values)
|
||||
self._add_new_value(index, 0, path)
|
||||
self._add_new_value(index, 1, index)
|
||||
self._add_new_value(index, 2, value)
|
||||
self._add_new_value(index, 3, owner)
|
||||
|
||||
def hasvalue(self, path, index=None):
|
||||
"""if path has a value
|
||||
|
@ -114,16 +113,8 @@ class Values(Cache):
|
|||
path_idx = self._values[0].index(path)
|
||||
# get the "index" position
|
||||
subidx = self._values[1][path_idx].index(index)
|
||||
# transform tuple to list
|
||||
values = list(self._values)
|
||||
values_idx = list(values[1])
|
||||
lvalues = list(values_idx[path_idx])
|
||||
# reduce to one the index
|
||||
lvalues[subidx] = lvalues[subidx] - 1
|
||||
# store modification
|
||||
values_idx[path_idx] = tuple(lvalues)
|
||||
values[1] = tuple(values_idx)
|
||||
self._values = tuple(values)
|
||||
self._values[1][path_idx][subidx] -= 1
|
||||
|
||||
def resetvalue_index(self,
|
||||
path,
|
||||
|
@ -131,23 +122,16 @@ class Values(Cache):
|
|||
commit):
|
||||
log.debug('resetvalue_index %s %s %s', path, index, id(self))
|
||||
def _resetvalue(nb):
|
||||
values_idx = list(values[nb])
|
||||
del(values_idx[path_idx])
|
||||
values[nb] = tuple(values_idx)
|
||||
del self._values[nb][path_idx]
|
||||
|
||||
def _resetvalue_index(nb):
|
||||
values_idx = list(values[nb])
|
||||
lvalues = list(values_idx[path_idx])
|
||||
del(lvalues[subidx])
|
||||
values_idx[path_idx] = tuple(lvalues)
|
||||
values[nb] = tuple(values_idx)
|
||||
del self._values[nb][path_idx][subidx]
|
||||
|
||||
path_idx = self._values[0].index(path)
|
||||
indexes = self._values[1][path_idx]
|
||||
if index in indexes:
|
||||
subidx = indexes.index(index)
|
||||
values = list(self._values)
|
||||
if len(values[1][path_idx]) == 1:
|
||||
if len(self._values[1][path_idx]) == 1:
|
||||
_resetvalue(0)
|
||||
_resetvalue(1)
|
||||
_resetvalue(2)
|
||||
|
@ -156,7 +140,6 @@ class Values(Cache):
|
|||
_resetvalue_index(1)
|
||||
_resetvalue_index(2)
|
||||
_resetvalue_index(3)
|
||||
self._values = tuple(values)
|
||||
|
||||
def resetvalue(self,
|
||||
path,
|
||||
|
@ -165,17 +148,13 @@ class Values(Cache):
|
|||
"""
|
||||
log.debug('resetvalue %s %s', path, id(self))
|
||||
def _resetvalue(nb):
|
||||
lst = list(self._values[nb])
|
||||
lst.pop(idx)
|
||||
values.append(tuple(lst))
|
||||
values = []
|
||||
self._values[nb].pop(idx)
|
||||
if path in self._values[0]:
|
||||
idx = self._values[0].index(path)
|
||||
_resetvalue(0)
|
||||
_resetvalue(1)
|
||||
_resetvalue(2)
|
||||
_resetvalue(3)
|
||||
self._values = tuple(values)
|
||||
|
||||
# owner
|
||||
def setowner(self,
|
||||
|
@ -186,14 +165,10 @@ class Values(Cache):
|
|||
"""
|
||||
idx = self._values[0].index(path)
|
||||
if index is None:
|
||||
vidx = None
|
||||
follower_idx = None
|
||||
else:
|
||||
vidx = self._values[1][idx].index(index)
|
||||
values = []
|
||||
self._setvalue_info(3, idx, owner, values, index, vidx)
|
||||
lst = list(self._values)
|
||||
lst[3] = tuple(values[0])
|
||||
self._values = tuple(lst)
|
||||
follower_idx = self._values[1][idx].index(index)
|
||||
self._setvalue_info(3, idx, owner, index, follower_idx)
|
||||
|
||||
def get_max_length(self,
|
||||
path):
|
||||
|
@ -293,10 +268,10 @@ class Values(Cache):
|
|||
self._informations = {}
|
||||
|
||||
def exportation(self):
|
||||
return self._values
|
||||
return deepcopy(self._values)
|
||||
|
||||
def importation(self, export):
|
||||
self._values = export
|
||||
self._values = deepcopy(export)
|
||||
|
||||
|
||||
def delete_session(session_id):
|
||||
|
|
|
@ -31,22 +31,16 @@ class Cache(DictCache):
|
|||
self._storage = storage
|
||||
super().__init__()
|
||||
|
||||
def setcache(self, path, index, val, self_props, props):
|
||||
def setcache(self, path, index, val, self_props, props, validated):
|
||||
"""add val in cache for a specified path
|
||||
if follower, add index
|
||||
"""
|
||||
if 'cache' in props or 'cache' in self_props:
|
||||
log.debug('setcache {} with index {} and value {} in {} ({})'.format(path, index, val,
|
||||
_display_classname(self),
|
||||
id(self)))
|
||||
self._setcache(path, index, val, time())
|
||||
log.debug('not setcache {} with index {} and value {} and props {} and {} in {} ({})'.format(path,
|
||||
index,
|
||||
val,
|
||||
props,
|
||||
self_props,
|
||||
_display_classname(self),
|
||||
id(self)))
|
||||
log.debug('setcache %s with index %s and value %s in %s (%s)',
|
||||
path, index, val, _display_classname(self), id(self))
|
||||
self._setcache(path, index, val, time(), validated)
|
||||
log.debug('not setcache %s with index %s and value %s and props %s and %s in %s (%s)',
|
||||
path, index, val, props, self_props, _display_classname(self), id(self))
|
||||
|
||||
def getcache(self,
|
||||
path,
|
||||
|
@ -55,12 +49,12 @@ class Cache(DictCache):
|
|||
props,
|
||||
self_props,
|
||||
type_):
|
||||
no_cache = False, None
|
||||
no_cache = False, None, False
|
||||
if 'cache' in props or type_ == 'context_props':
|
||||
indexed = self._getcache(path, index)
|
||||
if indexed is None:
|
||||
return no_cache
|
||||
value, timestamp = indexed
|
||||
value, timestamp, validated = indexed
|
||||
if type_ == 'context_props':
|
||||
# cached value is settings properties so value is props
|
||||
props = value
|
||||
|
@ -77,18 +71,18 @@ class Cache(DictCache):
|
|||
if timestamp + expiration_time >= ntime:
|
||||
log.debug('getcache in cache (1) %s %s %s %s %s', path, value, _display_classname(self),
|
||||
id(self), index)
|
||||
return True, value
|
||||
#else:
|
||||
# log.debug('getcache expired value for path {} < {}'.format(
|
||||
# timestamp + expiration_time, ntime))
|
||||
# # if expired, remove from cache
|
||||
# #self.delcache(path)
|
||||
return True, value, validated
|
||||
else:
|
||||
log.debug('getcache expired value for path %s < %s',
|
||||
timestamp + expiration_time, ntime)
|
||||
# if expired, remove from cache
|
||||
# self.delcache(path)
|
||||
else:
|
||||
log.debug('getcache in cache (2) %s %s %s %s %s', path, value, _display_classname(self),
|
||||
id(self), index)
|
||||
return True, value
|
||||
log.debug('getcache {} with index {} not in {} cache'.format(path, index,
|
||||
_display_classname(self)))
|
||||
return True, value, validated
|
||||
log.debug('getcache %s with index %s not in %s cache',
|
||||
path, index, _display_classname(self))
|
||||
return no_cache
|
||||
|
||||
def delcache(self, path):
|
||||
|
@ -108,5 +102,5 @@ class Cache(DictCache):
|
|||
please only use it in test purpose
|
||||
example: {'path1': {'index1': ('value1', 'time1')}, 'path2': {'index2': ('value2', 'time2', )}}
|
||||
"""
|
||||
log.debug('get_chached {} for {} ({})'.format(self._cache, _display_classname(self), id(self)))
|
||||
log.debug('get_chached %s for %s (%s)', self._cache, _display_classname(self), id(self))
|
||||
return self._get_cached()
|
||||
|
|
|
@ -62,32 +62,32 @@ class Values(object):
|
|||
"""
|
||||
# try to retrive value in cache
|
||||
setting_properties = option_bag.config_bag.properties
|
||||
is_cached, value = self._p_.getcache(option_bag.path,
|
||||
option_bag.config_bag.expiration_time,
|
||||
option_bag.index,
|
||||
setting_properties,
|
||||
option_bag.properties,
|
||||
'value')
|
||||
|
||||
if not is_cached:
|
||||
is_cached, value, validated = self._p_.getcache(option_bag.path,
|
||||
option_bag.config_bag.expiration_time,
|
||||
option_bag.index,
|
||||
setting_properties,
|
||||
option_bag.properties,
|
||||
'value')
|
||||
if not validated:
|
||||
# no cached value so get value
|
||||
value = self.getvalue(option_bag)
|
||||
# validate value
|
||||
opt = option_bag.option
|
||||
opt.impl_validate(value,
|
||||
option_bag,
|
||||
check_error=True)
|
||||
# validate value
|
||||
option_bag.option.impl_validate(value,
|
||||
option_bag,
|
||||
check_error=True)
|
||||
# store value in cache
|
||||
validator = 'validator' in option_bag.config_bag.properties
|
||||
if not is_cached or validator:
|
||||
self._p_.setcache(option_bag.path,
|
||||
option_bag.index,
|
||||
value,
|
||||
option_bag.properties,
|
||||
setting_properties,
|
||||
validator)
|
||||
if 'warnings' in setting_properties:
|
||||
opt.impl_validate(value,
|
||||
option_bag,
|
||||
check_error=False)
|
||||
# store value in cache
|
||||
if not is_cached:
|
||||
self._p_.setcache(option_bag.path,
|
||||
option_bag.index,
|
||||
value,
|
||||
option_bag.properties,
|
||||
setting_properties)
|
||||
option_bag.option.impl_validate(value,
|
||||
option_bag,
|
||||
check_error=False)
|
||||
if isinstance(value, list):
|
||||
# return a copy, so value cannot be modified
|
||||
return value.copy()
|
||||
|
@ -174,12 +174,12 @@ class Values(object):
|
|||
def _reset_cache(_value):
|
||||
if not 'expire' in option_bag.properties:
|
||||
return
|
||||
is_cache, cache_value = self._p_.getcache(option_bag.path,
|
||||
None,
|
||||
option_bag.index,
|
||||
option_bag.config_bag.properties,
|
||||
option_bag.properties,
|
||||
'value')
|
||||
is_cache, cache_value, validated = self._p_.getcache(option_bag.path,
|
||||
None,
|
||||
option_bag.index,
|
||||
option_bag.config_bag.properties,
|
||||
option_bag.properties,
|
||||
'value')
|
||||
if not is_cache or cache_value == _value:
|
||||
# calculation return same value as previous value,
|
||||
# so do not invalidate cache
|
||||
|
@ -508,7 +508,7 @@ class Values(object):
|
|||
current_value = self.get_cached_value(option_bag)
|
||||
length = len(current_value)
|
||||
if index >= length:
|
||||
raise IndexError(_('index "{}" is higher than the length "{}" '
|
||||
raise IndexError(_('index {} is greater than the length {} '
|
||||
'for option "{}"').format(index,
|
||||
length,
|
||||
option_bag.option.impl_get_display_name()))
|
||||
|
|
Loading…
Reference in a new issue