better performance in find_firsts

_is_build_cache not set in dictionary storage
This commit is contained in:
Emmanuel Garette 2014-11-10 21:00:30 +01:00
parent 4217508f3f
commit f03cbeadb7
4 changed files with 57 additions and 34 deletions

View file

@ -18,6 +18,13 @@ def make_description():
return OptionDescription('od1', '', [u1, u2, u3])
def test_cache_config():
od1 = make_description()
assert od1.impl_already_build_caches() == False
c = Config(od1)
assert od1.impl_already_build_caches() == True
def test_cache():
od1 = make_description()
c = Config(od1)

View file

@ -153,12 +153,17 @@ def test_meta_meta_set():
meta2.setattrs('od1.i6', 7)
assert conf1.od1.i1 == conf2.od1.i1 == 7
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
assert [conf1, conf2] == meta2.find_firsts(byname='i1', byvalue=7)
assert [conf1, conf2] == meta2.find_firsts(byname='i1', byvalue=7, type_='config')
assert ['od1.i1', 'od1.i1'] == meta2.find_firsts(byname='i1', byvalue=7, type_='path')
conf1.od1.i1 = 8
assert [conf1, conf2] == meta2.find_firsts(byname='i1')
assert [conf2] == meta2.find_firsts(byname='i1', byvalue=7)
assert [conf1] == meta2.find_firsts(byname='i1', byvalue=8)
assert [conf1, conf2] == meta2.find_firsts(byname='i5', byvalue=2)
assert [conf1, conf2] == meta2.find_firsts(byname='i1', type_='config')
assert ['od1.i1', 'od1.i1'] == meta2.find_firsts(byname='i1', type_='path')
assert [conf2] == meta2.find_firsts(byname='i1', byvalue=7, type_='config')
assert ['od1.i1'] == meta2.find_firsts(byname='i1', byvalue=7, type_='path')
assert [conf1] == meta2.find_firsts(byname='i1', byvalue=8, type_='config')
assert ['od1.i1'] == meta2.find_firsts(byname='i1', byvalue=8, type_='path')
assert [conf1, conf2] == meta2.find_firsts(byname='i5', byvalue=2, type_='config')
assert ['od1.i5', 'od1.i5'] == meta2.find_firsts(byname='i5', byvalue=2, type_='path')
raises(AttributeError, "meta2.find_firsts(byname='i1', byvalue=10)")
raises(AttributeError, "meta2.find_firsts(byname='not', byvalue=10)")
raises(AttributeError, "meta2.find_firsts(byname='i6')")
@ -179,6 +184,16 @@ def test_not_meta():
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
def test_group_find_firsts():
i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1])
conf1 = Config(od2)
conf2 = Config(od2)
meta = GroupConfig([conf1, conf2])
conf1, conf2 = meta.find_firsts(byname='i1')
def test_meta_path():
meta = make_description()
assert meta._impl_path is None

View file

@ -313,7 +313,7 @@ class SubConfig(object):
def _find(self, bytype, byname, byvalue, first, type_='option',
_subpath=None, check_properties=True, display_error=True,
force_permissive=False):
force_permissive=False, only_path=undefined):
"""
convenience method for finding an option that lives only in the subtree
@ -341,9 +341,15 @@ class SubConfig(object):
# if value and/or check_properties are set, need all avalaible option
# If first one has no good value or not good property check second one
# and so on
only_first = first is True and byvalue is None and check_properties is None
only_first = first is True and byvalue is None and \
check_properties is None
if only_path is not undefined:
option = self.unwrap_from_path(only_path)
options = [(only_path, option)]
else:
options = self.cfgimpl_get_description().impl_get_options_paths(
bytype, byname, _subpath, only_first, self._cfgimpl_get_context())
bytype, byname, _subpath, only_first,
self._cfgimpl_get_context())
for path, option in options:
if not _filter_by_value():
continue
@ -670,15 +676,15 @@ class GroupConfig(_CommonConfig):
except PropertiesOptionError:
pass
def find_firsts(self, byname=None, bypath=None, byvalue=undefined,
type_='path', display_error=True):
def find_firsts(self, byname=None, bypath=undefined, byvalue=undefined,
type_='option', display_error=True):
"""Find first not in current GroupConfig, but in each children
"""
ret = []
#if MetaConfig, all children have same OptionDescription as context
#so search only one time for all children
#if MetaConfig, all children have same OptionDescription in context
#so search only one time the option for all children
try:
if bypath is None and byname is not None and \
if bypath is undefined and byname is not None and \
isinstance(self, MetaConfig):
bypath = self._find(bytype=None, byvalue=undefined, byname=byname,
first=True, type_='path',
@ -686,33 +692,27 @@ class GroupConfig(_CommonConfig):
display_error=display_error)
byname = None
except AttributeError:
pass
return self._find_return_results([], True)
for child in self._impl_children:
try:
if not isinstance(child, MetaConfig):
if bypath is not None:
#if byvalue is None, try if not raise
value = getattr(child, bypath)
if byvalue is not undefined:
if isinstance(value, Multi):
if byvalue in value:
ret.append(child)
else:
if value == byvalue:
ret.append(child)
else:
ret.append(child)
else:
ret.append(child.find_first(byname=byname,
byvalue=byvalue,
type_=type_,
display_error=False))
else:
if isinstance(child, GroupConfig):
ret.extend(child.find_firsts(byname=byname,
bypath=bypath,
byvalue=byvalue,
type_=type_,
display_error=False))
else:
if type_ == 'config':
f_type = 'path'
else:
f_type = type_
f_ret = child._find(None, byname, byvalue, first=True,
type_=f_type, display_error=False,
only_path=bypath)
if type_ == 'config':
ret.append(child)
else:
ret.append(f_ret)
except AttributeError:
pass
return self._find_return_results(ret, display_error)

View file

@ -399,6 +399,7 @@ class StorageOptionDescription(StorageBase):
_currpath.pop()
if save:
self._cache_paths = (tuple(cache_option), tuple(cache_path))
self._is_build_cache = True
def impl_get_options_paths(self, bytype, byname, _subpath, only_first, context):
find_results = []