From 93bb5dcb43a8f80044a12fab962ba546bcb5df6a Mon Sep 17 00:00:00 2001 From: "arseny.kapoulkine" Date: Thu, 22 Jul 2010 07:54:34 +0000 Subject: XPath: Restored document order sorting optimization (it's now automatic for nodes that were loaded and not significantly altered), minor traversal optimizations git-svn-id: http://pugixml.googlecode.com/svn/trunk@613 99668b35-9821-0410-8761-19e4c4f06640 --- src/pugixml.cpp | 14 ++++++++++-- src/pugixml.hpp | 6 ++--- src/pugixpath.cpp | 67 +++++++++++++++++++++++++------------------------------ 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 3f37e65..3792c40 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -3216,8 +3216,13 @@ namespace pugi return (_attr && _attr->value) ? _attr->value : PUGIXML_TEXT(""); } - unsigned int xml_attribute::document_order() const + const void* xml_attribute::document_order() const { + if (!_attr) return 0; + + if ((_attr->header & xml_memory_page_name_allocated_mask) == 0) return _attr->name; + if ((_attr->header & xml_memory_page_value_allocated_mask) == 0) return _attr->value; + return 0; } @@ -4014,8 +4019,13 @@ namespace pugi return walker.end(arg_end); } - unsigned int xml_node::document_order() const + const void* xml_node::document_order() const { + if (!_root) return 0; + + if (_root->name && (_root->header & xml_memory_page_name_allocated_mask) == 0) return _root->name; + if (_root->value && (_root->header & xml_memory_page_value_allocated_mask) == 0) return _root->value; + return 0; } diff --git a/src/pugixml.hpp b/src/pugixml.hpp index 281a0ea..81f5769 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -646,8 +646,7 @@ namespace pugi bool as_bool() const; /// \internal Document order or 0 if not set - /// \deprecated This function is deprecated - PUGIXML_DEPRECATED unsigned int document_order() const; + const void* document_order() const; public: /** @@ -1466,8 +1465,7 @@ namespace pugi #endif /// \internal Document order or 0 if not set - /// \deprecated This function is deprecated - PUGIXML_DEPRECATED unsigned int document_order() const; + const void* document_order() const; /** * Print subtree to writer diff --git a/src/pugixpath.cpp b/src/pugixpath.cpp index 775706c..e9b7bc0 100644 --- a/src/pugixpath.cpp +++ b/src/pugixpath.cpp @@ -143,28 +143,22 @@ namespace xml_node cur = n.first_child(); - if (cur) + while (cur && cur != n) { - do + if (cur.type() == node_pcdata || cur.type() == node_cdata) + result += cur.value(); + + if (cur.first_child()) + cur = cur.first_child(); + else if (cur.next_sibling()) + cur = cur.next_sibling(); + else { - if (cur.type() == node_pcdata || cur.type() == node_cdata) - result += cur.value(); - - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - // Borland C++ workaround - while (!cur.next_sibling() && cur != n && (bool)cur.parent()) - cur = cur.parent(); - - if (cur != n) - cur = cur.next_sibling(); - } + while (!cur.next_sibling() && cur != n) + cur = cur.parent(); + + if (cur != n) cur = cur.next_sibling(); } - while (cur && cur != n); } return result; @@ -228,6 +222,11 @@ namespace { xml_node ln = lhs.node(), rn = rhs.node(); + const void* lo = lhs.attribute() ? lhs.attribute().document_order() : ln.document_order(); + const void* ro = rhs.attribute() ? rhs.attribute().document_order() : rn.document_order(); + + if (lo && ro) return lo < ro; + if (lhs.attribute() && rhs.attribute()) { if (lhs.parent() == rhs.parent()) @@ -1642,27 +1641,21 @@ namespace pugi xml_node cur = n.first_child(); - if (cur) + while (cur && cur != n) { - do + step_push(ns, cur); + + if (cur.first_child()) + cur = cur.first_child(); + else if (cur.next_sibling()) + cur = cur.next_sibling(); + else { - step_push(ns, cur); - - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - // Borland C++ workaround - while (!cur.next_sibling() && cur != n && (bool)cur.parent()) - cur = cur.parent(); - - if (cur != n) - cur = cur.next_sibling(); - } + while (!cur.next_sibling() && cur != n) + cur = cur.parent(); + + if (cur != n) cur = cur.next_sibling(); } - while (cur && cur != n); } break; -- cgit v1.2.3