diff options
| author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2014-10-18 15:28:02 +0000 | 
|---|---|---|
| committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2014-10-18 15:28:02 +0000 | 
| commit | 72ec01c5f6d23405f30614d63fafa048279ca13d (patch) | |
| tree | 0441106c7b49b806517009aaccbdf4b7271ef8c1 /src | |
| parent | 45e0c726f05d8a658600b7ca74db42f252f126e9 (diff) | |
XPath: Extend the descendant-or-self optimization
Use descendant-or-self::node() transformation for self, descendant and
descendant-or-self axis. Self axis should be semi-frequent; descendant
axes should not really be used with // but if they ever are the complexity
of the step becomes quadratic so it's better to optimize this if possible.
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1063 99668b35-9821-0410-8761-19e4c4f06640
Diffstat (limited to 'src')
| -rw-r--r-- | src/pugixml.cpp | 9 | 
1 files changed, 7 insertions, 2 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 71c3f5d..1d9dcfe 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -9613,12 +9613,17 @@ PUGI__NS_BEGIN  			// Replace descendant-or-self::node()/child::foo with descendant::foo  			// The former is a full form of //foo, the latter is much faster since it executes the node test immediately +			// Do a similar kind of replacement for self/descendant/descendant-or-self axes  			// Note that we only replace positionally invariant steps (//foo[1] != /descendant::foo[1]) -			if (_type == ast_step && _axis == axis_child && _left && +			if (_type == ast_step && (_axis == axis_child || _axis == axis_self || _axis == axis_descendant || _axis == axis_descendant_or_self) && _left &&  				_left->_type == ast_step && _left->_axis == axis_descendant_or_self && _left->_test == nodetest_type_node && !_left->_right &&  				is_posinv_step())  			{ -				_axis = axis_descendant; +				if (_axis == axis_child || _axis == axis_descendant) +					_axis = axis_descendant; +				else +					_axis = axis_descendant_or_self; +  				_left = _left->_left;  			}  | 
