xmlbuilder: A couple optimizations

This brings the test suite back to pre-refactor speeds
This commit is contained in:
Cole Robinson 2013-09-19 13:25:52 -04:00
parent 0be727e6bb
commit 1aaf41b201
1 changed files with 28 additions and 33 deletions

View File

@ -263,6 +263,7 @@ class XMLChildProperty(property):
self.child_classes = util.listify(child_classes) self.child_classes = util.listify(child_classes)
self.relative_xpath = relative_xpath self.relative_xpath = relative_xpath
self.is_single = is_single self.is_single = is_single
self._propname = None
if self.is_single and len(self.child_classes) > 1: if self.is_single and len(self.child_classes) > 1:
raise RuntimeError("programming error: Can't specify multiple " raise RuntimeError("programming error: Can't specify multiple "
@ -274,10 +275,14 @@ class XMLChildProperty(property):
return "<XMLChildProperty %s %s>" % (str(self.child_classes), id(self)) return "<XMLChildProperty %s %s>" % (str(self.child_classes), id(self))
def _findpropname(self, xmlbuilder): def _findpropname(self, xmlbuilder):
for key, val in xmlbuilder._all_child_props().items(): if self._propname is None:
if val is self: for key, val in xmlbuilder._all_child_props().items():
return key if val is self:
raise RuntimeError("Didn't find expected property=%s" % self) self._propname = key
break
if self._propname is None:
raise RuntimeError("Didn't find expected property=%s" % self)
return self._propname
def _get(self, xmlbuilder): def _get(self, xmlbuilder):
propname = self._findpropname(xmlbuilder) propname = self._findpropname(xmlbuilder)
@ -369,6 +374,7 @@ class XMLProperty(property):
self._name = name or xpath self._name = name or xpath
if not self._name: if not self._name:
raise RuntimeError("XMLProperty: name or xpath must be passed.") raise RuntimeError("XMLProperty: name or xpath must be passed.")
self._propname = None
self._is_bool = is_bool self._is_bool = is_bool
self._is_int = is_int self._is_int = is_int
@ -412,10 +418,14 @@ class XMLProperty(property):
Map the raw property() instance to the param name it's exposed Map the raw property() instance to the param name it's exposed
as in the XMLBuilder class. This is just for debug purposes. as in the XMLBuilder class. This is just for debug purposes.
""" """
for key, val in xmlbuilder._all_xml_props().items(): if self._propname is None:
if val is self: for key, val in xmlbuilder._all_xml_props().items():
return key if val is self:
raise RuntimeError("Didn't find expected property=%s" % self) self._propname = key
break
if self._propname is None:
raise RuntimeError("Didn't find expected property=%s" % self)
return self._propname
def _xpath_for_getter(self, xmlbuilder): def _xpath_for_getter(self, xmlbuilder):
ret = self._xpath ret = self._xpath
@ -763,6 +773,9 @@ class XMLBuilder(object):
parsexml, parsexmlnode, parsexml, parsexmlnode,
parent_xpath, relative_object_xpath) parent_xpath, relative_object_xpath)
self._initial_child_parse()
def _initial_child_parse(self):
# Walk the XML tree and hand of parsing to any registered # Walk the XML tree and hand of parsing to any registered
# child classes # child classes
for xmlprop in self._all_child_props().values(): for xmlprop in self._all_child_props().values():
@ -791,6 +804,7 @@ class XMLBuilder(object):
parent_xpath=self.get_root_xpath(), parent_xpath=self.get_root_xpath(),
relative_object_xpath=(prop_path + idxstr)) relative_object_xpath=(prop_path + idxstr))
xmlprop.append(self, obj) xmlprop.append(self, obj)
self._set_child_xpaths() self._set_child_xpaths()
@ -908,13 +922,15 @@ class XMLBuilder(object):
def _set_parent_xpath(self, xpath): def _set_parent_xpath(self, xpath):
self._xmlstate.set_parent_xpath(xpath) self._xmlstate.set_parent_xpath(xpath)
for p in self._all_subelement_props(): for propname in self._all_child_props():
p._set_parent_xpath(self.get_root_xpath()) for p in util.listify(getattr(self, propname, [])):
p._set_parent_xpath(self.get_root_xpath())
def _set_relative_object_xpath(self, xpath): def _set_relative_object_xpath(self, xpath):
self._xmlstate.set_relative_object_xpath(xpath) self._xmlstate.set_relative_object_xpath(xpath)
for p in self._all_subelement_props(): for propname in self._all_child_props():
p._set_parent_xpath(self.get_root_xpath()) for p in util.listify(getattr(self, propname, [])):
p._set_parent_xpath(self.get_root_xpath())
def _find_child_prop(self, child_class): def _find_child_prop(self, child_class):
xmlprops = self._all_child_props() xmlprops = self._all_child_props()
@ -959,27 +975,6 @@ class XMLBuilder(object):
_remove_xpath_node(self._xmlstate.xml_ctx, xpath, dofree=False) _remove_xpath_node(self._xmlstate.xml_ctx, xpath, dofree=False)
self._set_child_xpaths() self._set_child_xpaths()
def _all_subelement_props(self):
"""
Return a list of all sub element properties this class tracks.
A sub element is an XMLBuilder that is tracked explicitly in
a parent class, which alters the parent XML.
VirtualDevice.address is an example.
"""
xmlprops = self._all_xml_props()
childprops = self._all_child_props()
ret = []
propmap = {}
for propname in self._XML_PROP_ORDER:
if propname not in xmlprops:
propmap[propname] = getattr(self, propname)
for propname in childprops:
propmap[propname] = getattr(self, propname)
for objs in propmap.values():
ret.extend(util.listify(objs))
return ret
################################# #################################
# Private XML building routines # # Private XML building routines #