0
0
mirror of https://github.com/zeux/pugixml.git synced 2024-12-31 00:13:01 +08:00

1068 Commits

Author SHA1 Message Date
Arseny Kapoulkine
72ec01c5f6 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
2014-10-18 15:28:02 +00:00
Arseny Kapoulkine
45e0c726f0 tests: Disable tests that rely on ceil() on CLR
CLR x64 JIT does not implement ceil() properly (ceil(-0.1) returns
positive zero instead of negative zero). Disable the relevant portions of
tests so that everything else is green...

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1062 99668b35-9821-0410-8761-19e4c4f06640
2014-10-16 06:41:04 +00:00
Arseny Kapoulkine
5da51dff27 XPath: Optimize attribute axis lookup
When looking for an attribute by name, finding the first attribute means
we can stop looking since attribute names are unique. This makes some
queries faster by 40%.

Another very common pattern in XPath queries is finding an attribute with
a specified value using a predicate (@name = 'value'). While we perform an
optimal amount of traversal in that case, there is a substantial overhead
with evaluating the nodes, saving and restoring the stack state, pushing
the attribute node into a set, etc. Detecting this pattern allows us to
use optimized code, resulting in up to 2x speedup for some queries.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1061 99668b35-9821-0410-8761-19e4c4f06640
2014-10-16 03:46:42 +00:00
Arseny Kapoulkine
883031fb45 XPath: Fix optimization bug with //name[last()]
The actual condition for the optimization is invariance from context list
-- this includes both position() and last().

Instead of splitting the posinv concept just include last() into
non-posinv expressions - this requires sorting for boolean predicates that
depend on last() and do not depend on position(). These cases should be
very rare.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1060 99668b35-9821-0410-8761-19e4c4f06640
2014-10-15 06:05:49 +00:00
Arseny Kapoulkine
87d4f03187 tests: Add a test for printing comments that contain --
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1059 99668b35-9821-0410-8761-19e4c4f06640
2014-10-14 04:11:26 +00:00
Arseny Kapoulkine
e7d2540c1a Adjust comment output to avoid malformed documents.
Comment value can not contain the string "--" or end with "-". Since
comments do not support escaping, we're handling this by adding an extra
space after the first "-". A string of "-" thus turns into "- - - ...".

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1058 99668b35-9821-0410-8761-19e4c4f06640
2014-10-14 04:11:17 +00:00
Arseny Kapoulkine
fcd1876a21 Fix compact mode for 64-bit architectures 2014-10-11 01:35:24 -07:00
Arseny Kapoulkine
52371bf5fe Compact implementation refactoring
Remove compact stats and tags, replace pointer hash with murmur3 32-bit
finalizer.
2014-10-11 00:55:39 -07:00
Arseny Kapoulkine
97451b2eee Merge branch 'master' into compact 2014-10-10 19:35:09 -07:00
Arseny Kapoulkine
ccf8adce05 Swap insert_attribute_* implementations
Make sure their order is consistent with the order of declaration in
header file.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1057 99668b35-9821-0410-8761-19e4c4f06640
2014-10-11 02:34:42 +00:00
Arseny Kapoulkine
7795f00fba tests: Reenable all tests for compact mode 2014-10-10 19:32:40 -07:00
Arseny Kapoulkine
e6dd761ca3 Split hash table operations into reserve and insert
Insert is now unsafe - since we don't have a way to handle rehash()
failures transparently we need to reserve space beforehand. Reserve is now
called before every tree-mutating operations and it guarantees that we
can perform 16 arbitrary pointer mutations after that.

This fixes all test crashes with compact mode.
2014-10-10 19:31:30 -07:00
Arseny Kapoulkine
fbaab4dcad Move compact_hash_table before xml_allocator.
This helps streamline class dependencies and will make subsequent changes
smaller.
2014-10-10 19:29:25 -07:00
Arseny Kapoulkine
89575f352a Merge branch 'master' into compact 2014-10-10 19:27:25 -07:00
Arseny Kapoulkine
f4f55051d6 Refactor node/attribute tree operations
All ad-hoc attribute operations are now implemented as explicit low-level
functions, and xml_node just uses them. Additionally extract commonly used
is_attribute_of and move detaching of node from append_node to remove_node
- append_node now only works on detached nodes (small increase in parsing
  performance).

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1056 99668b35-9821-0410-8761-19e4c4f06640
2014-10-11 02:16:41 +00:00
Arseny Kapoulkine
d69127d78e Fix Borland C++ compilation errors/warnings
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1055 99668b35-9821-0410-8761-19e4c4f06640
2014-10-10 02:22:49 +00:00
Arseny Kapoulkine
224e702d1f Change compact_pointer_parent to use 2 bytes
Parent pointers need to be able to reach everywhere within a page to
minimize shared parent pointer reuse unless it's absolutely necessary.
This reduces parent hash utilization on all test cases to <1%.

Rename compact_parent to compact_shared_parent.
2014-10-09 08:45:35 -07:00
Arseny Kapoulkine
58282fd36f Optimize compact_pointer_parent
We now no longer need the compact_alignment type so replace it with a
constant.
2014-10-08 08:42:37 -07:00
Arseny Kapoulkine
80d6f5a7d0 Rework compact_pointer implementation
Split the implementation into a generic one with adjustable range and a
special implementation for parent (may need to use 2 bytes on that one
later).

Optimize compact_string and compact_pointer to use minimal amount of math
and move slow hash paths into no-inline functions so that compiler can
inline the fast-paths.

Merge compact_pointer_generic and compact_pointer_forward and optimize.
2014-10-07 21:14:38 -07:00
Arseny Kapoulkine
43622107d7 Remove PUGI__COMPACT helper
Also remove get() methods on pointer wrappers - this makes the surface
area smaller so we can create more of them easier.
2014-10-07 20:01:19 -07:00
Arseny Kapoulkine
edb57c96a8 Switch to a 3-byte representation for compact strings
To make this possible name and value in the node structure had to be
merged into one contents field. Not sure what to do with node_pi, since it
is the only type that required both.
2014-10-06 22:25:49 -07:00
Arseny Kapoulkine
5d7ec0a178 tests: Temporarily disable tests that are failing in compact mode 2014-10-05 23:58:41 -07:00
Arseny Kapoulkine
45a1b74335 Initial compact storage prototype
The storage uses one hash table for fallbacks and simple difference
encoding for node and string pointers.

This is a work in progress implementation - while node pointers seem to
work properly, string encoding is inefficient and parent pointers could
use more tuning.

No performance or compatibility work has been done either.
2014-10-05 23:58:02 -07:00
Arseny Kapoulkine
9e6dcc292d tests: Add XPath sorting test
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1054 99668b35-9821-0410-8761-19e4c4f06640
2014-10-05 08:39:44 +00:00
Arseny Kapoulkine
89f2f00da4 XPath: Store string length inside string object
When xpath_string is heap-allocated we always know the length of the
string at some point - it is now stored in the object. This reduces
redundant string length calculations and makes string_value() much faster
in case it has to concatenate strings.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1053 99668b35-9821-0410-8761-19e4c4f06640
2014-10-05 07:58:05 +00:00
Arseny Kapoulkine
5239fcbd00 XPath: Implement optimized translate()
translate() with constant arguments now uses a 128-byte table and a table
lookup instead of searching characters in the source string. The table is
generated during query optimization.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1052 99668b35-9821-0410-8761-19e4c4f06640
2014-10-05 07:57:58 +00:00
Arseny Kapoulkine
b17501c3fb tests: Add XPath sorting tests and a simple test for numeric predicates
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1051 99668b35-9821-0410-8761-19e4c4f06640
2014-10-05 04:20:52 +00:00
Arseny Kapoulkine
a3b23751ae Optimize XPath document order comparator
Node ancestor search now terminates early if ancestor is found before the
document root (only happens if nodes were at the same depth).

Sibling search now steps synchronously for left and right nodes to avoid
worst-case performance when we go in the wrong direction and have to scan
a big list (this comes at the cost of average performance since in the
best case we do 2x more operations).

Node comparison is now done using node pointers to elide some null
comparisons since the structure of the search guarantees that they are
handled properly.

All of the above results in ~2x faster document order comparison on
complex documents.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1050 99668b35-9821-0410-8761-19e4c4f06640
2014-10-05 04:20:47 +00:00
Arseny Kapoulkine
e66356715c Optimize XPath sorting for sorted sequences
XPath evaluation frequently produces sequences that are sorted but are not
tagged as such (area for improvement...). Doing a linear scan before
sorting is cheap and results in tremendous speedup for already sorted
sequences (especially if document_buffer_order optimization does not
apply).

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1049 99668b35-9821-0410-8761-19e4c4f06640
2014-10-05 04:20:38 +00:00
Arseny Kapoulkine
42219590f3 Optimize unrolled scanning for MSVC
While gcc and clang can eliminate dependency on s in the inner loop of
PUGI__SCANWHILE_UNROLL, MSVC emits a series of register increments.
Rewriting the code to explicitly remove the dependency keeps similar
codegen on gcc/clang but improves codegen on MSVC for a 10% performance
boost.

Also use unrolled scanning in text_output_escaped (2% faster).

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1048 99668b35-9821-0410-8761-19e4c4f06640
2014-10-04 05:03:33 +00:00
Arseny Kapoulkine
8a402b480f Fix whitespace indentation
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1047 99668b35-9821-0410-8761-19e4c4f06640
2014-10-03 05:23:07 +00:00
Arseny Kapoulkine
c4ecc406d2 Reorganize xml_memory_page structure
The page no longer contains 'data' field to use sizeof everywhere instead
of offsetof/sizeof inconsistency (that is required because some compilers
don't recognize offsetof as compile-time constant).

The page no longer contains 'memory' field that is now encoded as an
offset byte before the page - this allows us to save one pointer from the
static page in the document to keep the size the same as in v1.2 (binary
compatibility).

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1046 99668b35-9821-0410-8761-19e4c4f06640
2014-10-03 05:18:03 +00:00
Arseny Kapoulkine
daa48183f9 Remove document buffer order flag from document node
Use the same flag that is used for marking name/value in nodes/attributes
as shared. This reduces document structure size and makes some amount of
sense (although admittedly is a bit of a hack).

We need to bring document _memory size back down to 192 bytes and this is
the first step.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1045 99668b35-9821-0410-8761-19e4c4f06640
2014-10-03 05:17:56 +00:00
Arseny Kapoulkine
f3b220ca4e tests: Fix MSVC6 compilation
Also fixes PUGIXML_NO_STL compilation and makes it possible to build with
any version of new Windows SDK.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1044 99668b35-9821-0410-8761-19e4c4f06640
2014-10-03 02:40:11 +00:00
Arseny Kapoulkine
04913dc358 Optimize node_copy_tree by switching to pointers
xml_node objects carry an overhead since they perform NULL checks - in
case of copying a hierarchy we know that we only traverse valid nodes so
we don't need to do this. This makes copyless copy 16% faster.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1043 99668b35-9821-0410-8761-19e4c4f06640
2014-10-03 02:37:29 +00:00
Arseny Kapoulkine
f729fee60a Refactor accessing node type into a macro
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1042 99668b35-9821-0410-8761-19e4c4f06640
2014-10-03 02:37:22 +00:00
Arseny Kapoulkine
e376ba731f Fix copy behavior when out-of-memory
Also remove accidentally committed pragma pack :-/

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1041 99668b35-9821-0410-8761-19e4c4f06640
2014-10-02 16:28:50 +00:00
Arseny Kapoulkine
59409f70ef tests: Add a test for out-of-memory during copy
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1040 99668b35-9821-0410-8761-19e4c4f06640
2014-10-02 16:19:55 +00:00
Arseny Kapoulkine
4d39ae9e45 tests: Add a test to verify that xml_document object works with any valid pointer alignment
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1039 99668b35-9821-0410-8761-19e4c4f06640
2014-10-02 03:07:08 +00:00
Arseny Kapoulkine
3fcc530b34 tests: Add missing tests to increase code coverage
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1038 99668b35-9821-0410-8761-19e4c4f06640
2014-10-02 03:06:59 +00:00
Arseny Kapoulkine
00e1219bec Remove redundant condition from text_output_indent
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1037 99668b35-9821-0410-8761-19e4c4f06640
2014-10-02 03:06:52 +00:00
Arseny Kapoulkine
d5dcba7558 Use append_new_node in node_copy_tree
This bypasses the allow_insert check (which is redundant for copying since
we're mirroring an existing node structure that must be valid) and does
not cause an extra allocation for new declaration nodes. Overall results
in 15% faster copying,

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1036 99668b35-9821-0410-8761-19e4c4f06640
2014-10-01 14:19:35 +00:00
Arseny Kapoulkine
290bf521fa tests: Add XPath sorting tests for move/append_buffer
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1035 99668b35-9821-0410-8761-19e4c4f06640
2014-10-01 07:03:12 +00:00
Arseny Kapoulkine
b3f4277082 Disable document_order optimization after move/append_buffer.
Moving nodes results in node order being different from order of allocated
names/values; since move is O(1) we can't mark the moved nodes in a
subtree so we have to disable the optimization for the entire document.

Similarly, if a node is composed of multiple buffers, comparing nodes in
different buffers does not result in meaningful order.

Since we value correctness over performance, mark the entire document in
these cases to disable sorting optimization.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1034 99668b35-9821-0410-8761-19e4c4f06640
2014-10-01 07:03:06 +00:00
Arseny Kapoulkine
3ae516abe2 tests: Add tests for copyless copy and related potential bugs
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1033 99668b35-9821-0410-8761-19e4c4f06640
2014-10-01 07:02:59 +00:00
Arseny Kapoulkine
febe4f0209 Implement copyless copy
Now copying nodes or attributes does not copy names/values if the source
strings are in a document buffer. As a result, several nodes can now share
the same string in document buffer - to support this we 'taint' both
source and destination with a special 'shared' bit.

Tainting disables offset_debug() and fast-path document order comparison;
it also prevents strcpy_insitu from reusing the document buffer memory for
the copied node.

The downsides include slower XPath queries in some (rare) cases and
slightly higher memory consumption in some (rare) cases.

XPath queries can execute slower if a lot of old nodes were copied to new
nodes *and* a query only touches old nodes (so it used to benefit a lot
from fast comparison path) *and* a query produces unsorted node sets that
need to be sorted later (both are relatively rare).

Higher memory consumption is possible if a lot of nodes were copied and
all nodes (both new and old) have their contents modified 'in place' --
previously we could modify the old node in place and the new node required
one allocation on copy, and now both nodes have to have their data
allocated during modification. This should also be rare.

On the bright side, in a lot of cases copying of string data can be
avoided - this makes the copy much faster and the document now occupies
less memory. For example, some uses of append_buffer are now actually slower
compared to building up a document by copying a template from the same
document and modifying the copy slightly.

In one of the internal benchmarks copying is now 4x faster (the difference
can be more dramatic with more string contents and less markup).

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1032 99668b35-9821-0410-8761-19e4c4f06640
2014-10-01 07:02:52 +00:00
Arseny Kapoulkine
89d19df43d Add header bit for 'name or value is shared' flag
This is required to make it possible to use a pointer to one of the
buffers with the document data in nodes but keep offset_debug and (more
importantly) XPath document order comparison optimization working.

The change increases memory page alignment to 64 bytes (so requires +32
bytes for every page allocation, which should not be a problem - even with
non-default 4k pages this is <1% extra cost, with default 32k pages the
overhead is 0.1%)

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1031 99668b35-9821-0410-8761-19e4c4f06640
2014-10-01 07:02:45 +00:00
Arseny Kapoulkine
0c1a4f40fe tests: Fix allocator.cpp indentation
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1030 99668b35-9821-0410-8761-19e4c4f06640
2014-10-01 07:02:39 +00:00
Arseny Kapoulkine
947f043fa0 Remove redundant reference indirection for internal functions.
Since xml_node/attribute are pointer wrappers it's cheaper to pass them by
value. This makes XPath evaluation 4% faster and node printing 2% faster.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1029 99668b35-9821-0410-8761-19e4c4f06640
2014-09-28 23:36:18 +00:00
Arseny Kapoulkine
d519f7a473 tests: Add a test for stackless copy
This test has previously caused a stack overflow on x86/MSVC.

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1028 99668b35-9821-0410-8761-19e4c4f06640
2014-09-28 23:23:35 +00:00