Skip to content

Commit b71f09c

Browse files
committed
parser: Fix performance regression when parsing namespaces
The namespace hash table didn't reuse deleted buckets, leading to quadratic behavior. Also ignore deleted buckets when resizing. Fixes #726.
1 parent 0b6d813 commit b71f09c

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

parser.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,7 +1489,7 @@ xmlParserNsStartElement(xmlParserNsData *nsdb) {
14891489
static int
14901490
xmlParserNsLookup(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
14911491
xmlParserNsBucket **bucketPtr) {
1492-
xmlParserNsBucket *bucket;
1492+
xmlParserNsBucket *bucket, *tombstone;
14931493
unsigned index, hashValue;
14941494

14951495
if (prefix->name == NULL)
@@ -1501,10 +1501,13 @@ xmlParserNsLookup(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
15011501
hashValue = prefix->hashValue;
15021502
index = hashValue & (ctxt->nsdb->hashSize - 1);
15031503
bucket = &ctxt->nsdb->hash[index];
1504+
tombstone = NULL;
15041505

15051506
while (bucket->hashValue) {
1506-
if ((bucket->hashValue == hashValue) &&
1507-
(bucket->index != INT_MAX)) {
1507+
if (bucket->index == INT_MAX) {
1508+
if (tombstone == NULL)
1509+
tombstone = bucket;
1510+
} else if (bucket->hashValue == hashValue) {
15081511
if (ctxt->nsTab[bucket->index * 2] == prefix->name) {
15091512
if (bucketPtr != NULL)
15101513
*bucketPtr = bucket;
@@ -1521,7 +1524,7 @@ xmlParserNsLookup(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
15211524
}
15221525

15231526
if (bucketPtr != NULL)
1524-
*bucketPtr = bucket;
1527+
*bucketPtr = tombstone ? tombstone : bucket;
15251528
return(INT_MAX);
15261529
}
15271530

@@ -1758,7 +1761,7 @@ xmlParserNsPush(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
17581761
unsigned hv = ctxt->nsdb->hash[i].hashValue;
17591762
unsigned newIndex;
17601763

1761-
if (hv == 0)
1764+
if ((hv == 0) || (ctxt->nsdb->hash[i].index == INT_MAX))
17621765
continue;
17631766
newIndex = hv & (newSize - 1);
17641767

0 commit comments

Comments
 (0)