Commit 316a5c39 authored by Daniel Veillard's avatar Daniel Veillard
Browse files

added xmlHashCreateDict where the hash reuses the dictionnary for internal

* hash.c include/libxml/hash.h: added xmlHashCreateDict where
  the hash reuses the dictionnary for internal strings
* entities.c valid.c parser.c: reuse that new API, leads to a decent
  speedup when parsing for example DocBook documents.
Daniel
parent 7da92709
Sun Jan 23 23:54:39 CET 2005 Daniel Veillard <daniel@veillard.com>
* hash.c include/libxml/hash.h: added xmlHashCreateDict where
the hash reuses the dictionnary for internal strings
* entities.c valid.c parser.c: reuse that new API, leads to a decent
speedup when parsing for example DocBook documents.
Sun Jan 23 21:14:20 CET 2005 Daniel Veillard <daniel@veillard.com>
 
* parser.c: small speedup in skipping blanks characters
......
......@@ -161,13 +161,13 @@ xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
if (dtd->entities == NULL)
dtd->entities = xmlHashCreate(0);
dtd->entities = xmlHashCreateDict(0, dict);
table = dtd->entities;
break;
case XML_INTERNAL_PARAMETER_ENTITY:
case XML_EXTERNAL_PARAMETER_ENTITY:
if (dtd->pentities == NULL)
dtd->pentities = xmlHashCreate(0);
dtd->pentities = xmlHashCreateDict(0, dict);
table = dtd->pentities;
break;
case XML_INTERNAL_PREDEFINED_ENTITY:
......@@ -726,6 +726,7 @@ xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
* xmlCreateEntitiesTable:
*
* create and initialize an empty entities hash table.
* This really doesn't make sense and should be deprecated
*
* Returns the xmlEntitiesTablePtr just created or NULL in case of error.
*/
......
......@@ -52,6 +52,7 @@ struct _xmlHashTable {
struct _xmlHashEntry *table;
int size;
int nbElems;
xmlDictPtr dict;
};
/*
......@@ -149,6 +150,7 @@ xmlHashCreate(int size) {
table = xmlMalloc(sizeof(xmlHashTable));
if (table) {
table->dict = NULL;
table->size = size;
table->nbElems = 0;
table->table = xmlMalloc(size * sizeof(xmlHashEntry));
......@@ -161,6 +163,27 @@ xmlHashCreate(int size) {
return(NULL);
}
/**
* xmlHashCreateDict:
* @size: the size of the hash table
* @dict: a dictionary to use for the hash
*
* Create a new xmlHashTablePtr which will use @dict as the internal dictionary
*
* Returns the newly created object, or NULL if an error occured.
*/
xmlHashTablePtr
xmlHashCreateDict(int size, xmlDictPtr dict) {
xmlHashTablePtr table;
table = xmlHashCreate(size);
if (table != NULL) {
table->dict = dict;
xmlDictReference(dict);
}
return(table);
}
/**
* xmlHashGrow:
* @table: the hash table
......@@ -282,12 +305,14 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
next = iter->next;
if ((f != NULL) && (iter->payload != NULL))
f(iter->payload, iter->name);
if (iter->name)
xmlFree(iter->name);
if (iter->name2)
xmlFree(iter->name2);
if (iter->name3)
xmlFree(iter->name3);
if (table->dict == NULL) {
if (iter->name)
xmlFree(iter->name);
if (iter->name2)
xmlFree(iter->name2);
if (iter->name3)
xmlFree(iter->name3);
}
iter->payload = NULL;
if (!inside_table)
xmlFree(iter);
......@@ -299,6 +324,8 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
}
xmlFree(table->table);
}
if (table->dict)
xmlDictFree(table->dict);
xmlFree(table);
}
......@@ -463,9 +490,30 @@ xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
xmlHashEntryPtr entry;
xmlHashEntryPtr insert;
if ((table == NULL) || name == NULL)
if ((table == NULL) || (name == NULL))
return(-1);
/*
* If using a dict internalize if needed
*/
if (table->dict) {
if (!xmlDictOwns(table->dict, name)) {
name = xmlDictLookup(table->dict, name, -1);
if (name == NULL)
return(-1);
}
if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
name2 = xmlDictLookup(table->dict, name2, -1);
if (name2 == NULL)
return(-1);
}
if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
name3 = xmlDictLookup(table->dict, name3, -1);
if (name3 == NULL)
return(-1);
}
}
/*
* Check for duplicate and insertion location.
*/
......@@ -473,18 +521,33 @@ xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
if (table->table[key].valid == 0) {
insert = NULL;
} else {
for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if (table->dict) {
for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if ((insert->name == name) &&
(insert->name2 == name2) &&
(insert->name3 == name3))
return(-1);
len++;
}
if ((insert->name == name) &&
(insert->name2 == name2) &&
(insert->name3 == name3))
return(-1);
} else {
for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
(xmlStrEqual(insert->name3, name3)))
return(-1);
len++;
}
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
(xmlStrEqual(insert->name3, name3)))
return(-1);
len++;
}
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
(xmlStrEqual(insert->name3, name3)))
return(-1);
}
if (insert == NULL) {
......@@ -495,9 +558,15 @@ xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
return(-1);
}
entry->name = xmlStrdup(name);
entry->name2 = xmlStrdup(name2);
entry->name3 = xmlStrdup(name3);
if (table->dict != NULL) {
entry->name = (xmlChar *) name;
entry->name2 = (xmlChar *) name2;
entry->name3 = (xmlChar *) name3;
} else {
entry->name = xmlStrdup(name);
entry->name2 = xmlStrdup(name2);
entry->name3 = xmlStrdup(name3);
}
entry->payload = userdata;
entry->next = NULL;
entry->valid = 1;
......@@ -540,6 +609,27 @@ xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
if ((table == NULL) || name == NULL)
return(-1);
/*
* If using a dict internalize if needed
*/
if (table->dict) {
if (!xmlDictOwns(table->dict, name)) {
name = xmlDictLookup(table->dict, name, -1);
if (name == NULL)
return(-1);
}
if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
name2 = xmlDictLookup(table->dict, name2, -1);
if (name2 == NULL)
return(-1);
}
if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
name3 = xmlDictLookup(table->dict, name3, -1);
if (name3 == NULL)
return(-1);
}
}
/*
* Check for duplicate and insertion location.
*/
......@@ -547,8 +637,38 @@ xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
if (table->table[key].valid == 0) {
insert = NULL;
} else {
for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if (table ->dict) {
for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if ((insert->name == name) &&
(insert->name2 == name2) &&
(insert->name3 == name3)) {
if (f)
f(insert->payload, insert->name);
insert->payload = userdata;
return(0);
}
}
if ((insert->name == name) &&
(insert->name2 == name2) &&
(insert->name3 == name3)) {
if (f)
f(insert->payload, insert->name);
insert->payload = userdata;
return(0);
}
} else {
for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
(xmlStrEqual(insert->name3, name3))) {
if (f)
f(insert->payload, insert->name);
insert->payload = userdata;
return(0);
}
}
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
(xmlStrEqual(insert->name3, name3))) {
......@@ -558,14 +678,6 @@ xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
return(0);
}
}
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
(xmlStrEqual(insert->name3, name3))) {
if (f)
f(insert->payload, insert->name);
insert->payload = userdata;
return(0);
}
}
if (insert == NULL) {
......@@ -576,9 +688,15 @@ xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
return(-1);
}
entry->name = xmlStrdup(name);
entry->name2 = xmlStrdup(name2);
entry->name3 = xmlStrdup(name3);
if (table->dict != NULL) {
entry->name = (xmlChar *) name;
entry->name2 = (xmlChar *) name2;
entry->name3 = (xmlChar *) name3;
} else {
entry->name = xmlStrdup(name);
entry->name2 = xmlStrdup(name2);
entry->name3 = xmlStrdup(name3);
}
entry->payload = userdata;
entry->next = NULL;
entry->valid = 1;
......@@ -615,6 +733,14 @@ xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
key = xmlHashComputeKey(table, name, name2, name3);
if (table->table[key].valid == 0)
return(NULL);
if (table->dict) {
for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
if ((entry->name == name) &&
(entry->name2 == name2) &&
(entry->name3 == name3))
return(entry->payload);
}
}
for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
if ((xmlStrEqual(entry->name, name)) &&
(xmlStrEqual(entry->name2, name2)) &&
......@@ -920,12 +1046,14 @@ xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
if ((f != NULL) && (entry->payload != NULL))
f(entry->payload, entry->name);
entry->payload = NULL;
if(entry->name)
xmlFree(entry->name);
if(entry->name2)
xmlFree(entry->name2);
if(entry->name3)
xmlFree(entry->name3);
if (table->dict == NULL) {
if(entry->name)
xmlFree(entry->name);
if(entry->name2)
xmlFree(entry->name2);
if(entry->name3)
xmlFree(entry->name3);
}
if(prev) {
prev->next = entry->next;
xmlFree(entry);
......
......@@ -27,6 +27,7 @@ typedef xmlHashTable *xmlHashTablePtr;
#include <libxml/xmlversion.h>
#include <libxml/parser.h>
#include <libxml/dict.h>
#ifdef __cplusplus
extern "C" {
......@@ -99,6 +100,9 @@ typedef void (*xmlHashScannerFull)(void *payload, void *data,
*/
XMLPUBFUN xmlHashTablePtr XMLCALL
xmlHashCreate (int size);
XMLPUBFUN xmlHashTablePtr XMLCALL
xmlHashCreateDict(int size,
xmlDictPtr dict);
XMLPUBFUN void XMLCALL
xmlHashFree (xmlHashTablePtr table,
xmlHashDeallocator f);
......
......@@ -642,7 +642,7 @@ xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
const xmlChar *prefix;
if (ctxt->attsDefault == NULL) {
ctxt->attsDefault = xmlHashCreate(10);
ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
if (ctxt->attsDefault == NULL)
goto mem_error;
}
......@@ -729,7 +729,7 @@ xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
int type)
{
if (ctxt->attsSpecial == NULL) {
ctxt->attsSpecial = xmlHashCreate(10);
ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
if (ctxt->attsSpecial == NULL)
goto mem_error;
}
......@@ -3588,7 +3588,7 @@ void
xmlParseComment(xmlParserCtxtPtr ctxt) {
xmlChar *buf = NULL;
int size = XML_PARSER_BUFFER_SIZE;
int len;
int len = 0;
xmlParserInputState state;
const xmlChar *in;
int nbchar = 0, ccol;
......
......@@ -1206,18 +1206,6 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int
* *
****************************************************************/
/**
* xmlCreateElementTable:
*
* create and initialize an empty element hash table.
*
* Returns the xmlElementTablePtr just created or NULL in case of error.
*/
static xmlElementTablePtr
xmlCreateElementTable(void) {
return(xmlHashCreate(0));
}
/**
* xmlFreeElement:
* @elem: An element
......@@ -1269,6 +1257,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
if (name == NULL) {
return(NULL);
}
switch (type) {
case XML_ELEMENT_TYPE_EMPTY:
if (content != NULL) {
......@@ -1321,7 +1310,11 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
*/
table = (xmlElementTablePtr) dtd->elements;
if (table == NULL) {
table = xmlCreateElementTable();
xmlDictPtr dict = NULL;
if (dtd->doc != NULL)
dict = dtd->doc->dict;
table = xmlHashCreateDict(0, dict);
dtd->elements = (void *) table;
}
if (table == NULL) {
......@@ -1683,19 +1676,6 @@ xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlCreateAttributeTable:
*
* create and initialize an empty attribute hash table.
*
* Returns the xmlAttributeTablePtr just created or NULL in case
* of error.
*/
static xmlAttributeTablePtr
xmlCreateAttributeTable(void) {
return(xmlHashCreate(0));
}
#ifdef LIBXML_VALID_ENABLED
/**
* xmlScanAttributeDeclCallback:
......@@ -1899,7 +1879,10 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
*/
table = (xmlAttributeTablePtr) dtd->attributes;
if (table == NULL) {
table = xmlCreateAttributeTable();
xmlDictPtr dict = NULL;
if (dtd->doc != NULL)
dict = dtd->doc->dict;
table = xmlHashCreateDict(0, dict);
dtd->attributes = (void *) table;
}
if (table == NULL) {
......@@ -2184,19 +2167,6 @@ xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
* NOTATIONs *
* *
************************************************************************/
/**
* xmlCreateNotationTable:
*
* create and initialize an empty notation hash table.
*
* Returns the xmlNotationTablePtr just created or NULL in case
* of error.
*/
static xmlNotationTablePtr
xmlCreateNotationTable(void) {
return(xmlHashCreate(0));
}
/**
* xmlFreeNotation:
* @not: A notation
......@@ -2249,8 +2219,13 @@ xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd,
* Create the Notation table if needed.
*/
table = (xmlNotationTablePtr) dtd->notations;
if (table == NULL)
dtd->notations = table = xmlCreateNotationTable();
if (table == NULL) {
xmlDictPtr dict = NULL;
if (dtd->doc != NULL)
dict = dtd->doc->dict;
dtd->notations = table = xmlHashCreateDict(0, dict);
}
if (table == NULL) {
xmlVErrMemory(ctxt,
"xmlAddNotationDecl: Table creation failed!\n");
......@@ -2420,19 +2395,6 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str));
/**
* xmlCreateIDTable:
*
* create and initialize an empty id hash table.
*
* Returns the xmlIDTablePtr just created or NULL in case
* of error.
*/
static xmlIDTablePtr
xmlCreateIDTable(void) {
return(xmlHashCreate(0));
}
/**
* xmlFreeID:
* @not: A id
......@@ -2487,8 +2449,9 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
* Create the ID table if needed.
*/
table = (xmlIDTablePtr) doc->ids;
if (table == NULL)
doc->ids = table = xmlCreateIDTable();
if (table == NULL) {
doc->ids = table = xmlHashCreateDict(0, doc->dict);
}
if (table == NULL) {
xmlVErrMemory(ctxt,
"xmlAddID: Table creation failed!\n");
......@@ -2704,19 +2667,6 @@ typedef struct xmlValidateMemo_t
typedef xmlValidateMemo *xmlValidateMemoPtr;
/**
* xmlCreateRefTable:
*
* create and initialize an empty ref hash table.
*
* Returns the xmlRefTablePtr just created or NULL in case
* of error.
*/
static xmlRefTablePtr
xmlCreateRefTable(void) {
return(xmlHashCreate(0));
}
/**
* xmlFreeRef:
* @lk: A list link
......@@ -2813,8 +2763,9 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
* Create the Ref table if needed.
*/
table = (xmlRefTablePtr) doc->refs;
if (table == NULL)
doc->refs = table = xmlCreateRefTable();
if (table == NULL) {
doc->refs = table = xmlHashCreateDict(0, doc->dict);
}
if (table == NULL) {
xmlVErrMemory(ctxt,
"xmlAddRef: Table creation failed!\n");
......@@ -3063,6 +3014,11 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
if (dtd == NULL) return(NULL);
if (dtd->elements == NULL) {
xmlDictPtr dict = NULL;
if (dtd->doc != NULL)
dict = dtd->doc->dict;
if (!create)
return(NULL);
/*
......@@ -3070,7 +3026,7 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
*/
table = (xmlElementTablePtr) dtd->elements;
if (table == NULL) {
table = xmlCreateElementTable();
table = xmlHashCreateDict(0, dict);
dtd->elements = (void *) table;
}
if (table == NULL) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment