better cache
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2014-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -25,7 +25,7 @@ import sys
|
||||
from inspect import getargspec
|
||||
|
||||
from ..i18n import _
|
||||
from ..setting import log, undefined, debug
|
||||
from ..setting import log, undefined, debug, groups
|
||||
from ..autolib import carry_out_calculation
|
||||
from ..error import (ConfigError, ValueWarning, PropertiesOptionError,
|
||||
display_list)
|
||||
@ -58,7 +58,7 @@ def valid_name(name):
|
||||
return False
|
||||
|
||||
|
||||
def validate_callback(callback, callback_params, type_):
|
||||
def validate_callback(callback, callback_params, type_, callbackoption):
|
||||
if not isinstance(callback, FunctionType):
|
||||
raise ValueError(_('{0} must be a function').format(type_))
|
||||
if callback_params is not None:
|
||||
@ -94,6 +94,17 @@ def validate_callback(callback, callback_params, type_):
|
||||
' not a {} for second argument'
|
||||
).format(type_, type(
|
||||
force_permissive)))
|
||||
if isinstance(option, SymLinkOption):
|
||||
cur_opt = option._impl_getopt()
|
||||
else:
|
||||
cur_opt = option
|
||||
if cur_opt != callbackoption:
|
||||
if not getattr(cur_opt, '_dependencies', None):
|
||||
options = []
|
||||
else:
|
||||
options = list(cur_opt._dependencies)
|
||||
options.append(callbackoption)
|
||||
cur_opt._dependencies = tuple(options)
|
||||
#____________________________________________________________
|
||||
#
|
||||
|
||||
@ -127,7 +138,7 @@ class Base(StorageBase):
|
||||
if not is_multi and unique is True:
|
||||
raise ValueError(_('unique must be set only with multi value'))
|
||||
if requires is not None:
|
||||
calc_properties, requires = validate_requires_arg(is_multi,
|
||||
calc_properties, requires = validate_requires_arg(self, is_multi,
|
||||
requires, name)
|
||||
else:
|
||||
calc_properties = frozenset()
|
||||
@ -143,7 +154,7 @@ class Base(StorageBase):
|
||||
if multi: # and validator_params is None:
|
||||
validator_params = self._build_validator_params(validator, validator_params)
|
||||
|
||||
validate_callback(validator, validator_params, 'validator')
|
||||
validate_callback(validator, validator_params, 'validator', self)
|
||||
self._set_validator(validator, validator_params)
|
||||
self._set_has_dependency()
|
||||
if calc_properties != frozenset([]) and properties is not tuple():
|
||||
@ -217,7 +228,7 @@ class Base(StorageBase):
|
||||
"cannot set another one's").format(self.impl_getname()))
|
||||
self._validate_callback(callback, callback_params)
|
||||
if callback is not None:
|
||||
validate_callback(callback, callback_params, 'callback')
|
||||
validate_callback(callback, callback_params, 'callback', self)
|
||||
self._set_callback(callback, callback_params)
|
||||
|
||||
def impl_is_optiondescription(self):
|
||||
@ -239,6 +250,36 @@ class BaseOption(Base):
|
||||
|
||||
# ____________________________________________________________
|
||||
# serialize object
|
||||
def _impl_convert_dependencies(self, descr, load=False):
|
||||
"""export of the requires during the serialization process
|
||||
|
||||
:type descr: :class:`tiramisu.option.OptionDescription`
|
||||
:param load: `True` if we are at the init of the option description
|
||||
:type load: bool
|
||||
"""
|
||||
if not load and getattr(self, '_dependencies', None) is None:
|
||||
self._state_dependencies = None
|
||||
elif load and self._state_dependencies is None:
|
||||
del(self._state_dependencies)
|
||||
else:
|
||||
if load:
|
||||
self._dependencies = []
|
||||
for dependency in self._state_dependencies:
|
||||
option = descr.impl_get_opt_by_path(dependency)
|
||||
if option.impl_is_optiondescription() and \
|
||||
option.impl_get_group_type() == groups.master:
|
||||
master_path = dependency + '.' + dependency.split('.')[-1]
|
||||
option = descr.impl_get_opt_by_path(master_path).impl_get_master_slaves()
|
||||
self._dependencies.append(option)
|
||||
del(self._state_dependencies)
|
||||
else:
|
||||
self._state_dependencies = []
|
||||
for dependency in self._dependencies:
|
||||
if isinstance(dependency, MasterSlaves):
|
||||
self._state_dependencies.append('.'.join(descr.impl_get_path_by_opt(dependency._p_.master).split('.')[:-1]))
|
||||
else:
|
||||
self._state_dependencies.append(descr.impl_get_path_by_opt(dependency))
|
||||
|
||||
def _impl_convert_requires(self, descr, load=False):
|
||||
"""export of the requires during the serialization process
|
||||
|
||||
@ -417,6 +458,14 @@ class BaseOption(Base):
|
||||
name = name.encode('utf8')
|
||||
return name
|
||||
|
||||
def reset_cache(self, opt, obj, type_):
|
||||
context = obj._getcontext()
|
||||
path = self.impl_getpath(context)
|
||||
obj._p_.delcache(path)
|
||||
context.cfgimpl_reset_cache(only=(type_,),
|
||||
opt=self,
|
||||
path=path)
|
||||
|
||||
|
||||
class OnlyOption(BaseOption):
|
||||
__slots__ = tuple()
|
||||
@ -927,7 +976,7 @@ class Option(OnlyOption):
|
||||
"is calculated").format(self.impl_getname()))
|
||||
|
||||
|
||||
def validate_requires_arg(multi, requires, name):
|
||||
def validate_requires_arg(new_option, multi, requires, name):
|
||||
"""check malformed requirements
|
||||
and tranform dict to internal tuple
|
||||
|
||||
@ -936,6 +985,14 @@ def validate_requires_arg(multi, requires, name):
|
||||
know more about
|
||||
the description of the requires dictionary
|
||||
"""
|
||||
def set_dependency(option):
|
||||
if not getattr(option, '_dependencies', None):
|
||||
options = []
|
||||
else:
|
||||
options = list(option._dependencies)
|
||||
options.append(new_option)
|
||||
option._dependencies = tuple(options)
|
||||
|
||||
def get_option(require):
|
||||
option = require['option']
|
||||
if not isinstance(option, Option):
|
||||
@ -945,6 +1002,7 @@ def validate_requires_arg(multi, requires, name):
|
||||
raise ValueError(_('malformed requirements '
|
||||
'multi option must not set '
|
||||
'as requires of non multi option {0}').format(name))
|
||||
set_dependency(option)
|
||||
return option
|
||||
|
||||
def _set_expected(action, inverse, transitive, same_action, option, expected, operator):
|
||||
@ -970,6 +1028,7 @@ def validate_requires_arg(multi, requires, name):
|
||||
raise ValueError(_('malformed requirements expected must have '
|
||||
'option and value for option {0}').format(name))
|
||||
option = exp['option']
|
||||
set_dependency(option)
|
||||
if option is not None:
|
||||
err = option._validate(exp['value'])
|
||||
if err:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"master slave support"
|
||||
# Copyright (C) 2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2014-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -275,3 +275,8 @@ class MasterSlaves(object):
|
||||
raise SlaveError(_("invalid len for the slave: {0}"
|
||||
" which has {1} as master").format(
|
||||
name, self.getmaster(opt).impl_getname()))
|
||||
|
||||
def reset_cache(self, opt, values, type_):
|
||||
for slave in self.getslaves(opt):
|
||||
slave_path = slave.impl_getpath(values._getcontext())
|
||||
values._p_.delcache(slave_path)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"option types and option description"
|
||||
# Copyright (C) 2012-2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2012-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -49,7 +49,7 @@ class ChoiceOption(Option):
|
||||
:param values: is a list of values the option can possibly take
|
||||
"""
|
||||
if isinstance(values, FunctionType):
|
||||
validate_callback(values, values_params, 'values')
|
||||
validate_callback(values, values_params, 'values', self)
|
||||
else:
|
||||
if values_params is not None:
|
||||
raise ValueError(_('values is not a function, so values_params must be None'))
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2014-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -125,6 +125,13 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
cache_option, force_store_values)
|
||||
#cannot set multi option as OptionDescription requires
|
||||
else:
|
||||
if option.impl_is_master_slaves('master'):
|
||||
if not getattr(option, '_dependencies', None):
|
||||
options = []
|
||||
else:
|
||||
options = list(option._dependencies)
|
||||
options.append(option.impl_get_master_slaves())
|
||||
option._dependencies = tuple(options)
|
||||
option._set_readonly(True)
|
||||
is_multi = option.impl_is_multi()
|
||||
if not isinstance(option, SymLinkOption) and 'force_store_value' in option.impl_getproperties():
|
||||
@ -132,8 +139,8 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
for func, all_cons_opts, params in option._get_consistencies():
|
||||
option._valid_consistencies(all_cons_opts[1:], init=False)
|
||||
if func not in allowed_const_list and is_multi:
|
||||
is_slave = option.impl_is_master_slaves()
|
||||
if not is_slave:
|
||||
is_masterslaves = option.impl_is_master_slaves()
|
||||
if not is_masterslaves:
|
||||
raise ValueError(_('malformed consistency option "{0}" '
|
||||
'must be a master/slaves').format(
|
||||
option.impl_getname()))
|
||||
@ -178,7 +185,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
'must not be a multi for {1}').format(
|
||||
require_opt.impl_getname(), option.impl_getname()))
|
||||
if init:
|
||||
session = config._impl_values._p_.getsession()
|
||||
if len(cache_option) != len(set(cache_option)):
|
||||
for idx in xrange(1, len(cache_option) + 1):
|
||||
opt = cache_option.pop(0)
|
||||
@ -194,7 +200,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
self._cache_consistencies[opt] = tuple(cons)
|
||||
self._cache_force_store_values = force_store_values
|
||||
self._set_readonly(False)
|
||||
del(session)
|
||||
|
||||
|
||||
def impl_build_force_store_values(self, config):
|
||||
@ -408,8 +413,7 @@ class SynDynOptionDescription(object):
|
||||
def _impl_getchildren(self, dyn=True, context=undefined):
|
||||
children = []
|
||||
for child in self._opt._impl_getchildren():
|
||||
children.append(self._opt._impl_get_dynchild(child, self._suffix))
|
||||
return children
|
||||
yield(self._opt._impl_get_dynchild(child, self._suffix))
|
||||
|
||||
def impl_getchildren(self):
|
||||
return self._impl_getchildren()
|
||||
|
Reference in New Issue
Block a user