mirror of
https://github.com/GNOME/libxml2.git
synced 2025-03-13 18:47:01 +08:00
do string allocations in large pools, allowing to find if a string pertain
* dict.c include/libxml/dict.h: do string allocations in large pools, allowing to find if a string pertain to a dict quickly * xmllint.c: fix --stream --repeat --timing * Makefile.am: the testThreads run output should be seen. Daniel
This commit is contained in:
parent
9582d6ca54
commit
81514ba478
@ -1,3 +1,10 @@
|
||||
Wed Sep 17 01:07:56 CEST 2003 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* dict.c include/libxml/dict.h: do string allocations in large
|
||||
pools, allowing to find if a string pertain to a dict quickly
|
||||
* xmllint.c: fix --stream --repeat --timing
|
||||
* Makefile.am: the testThreads run output should be seen.
|
||||
|
||||
Mon Sep 15 16:46:28 CEST 2003 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* SAX2.c include/libxml/parser.h: starting work on reusing the
|
||||
|
@ -566,10 +566,10 @@ Threadtests : testThreads$(EXEEXT)
|
||||
@echo "##"
|
||||
@echo "## Threaded regression tests"
|
||||
@echo "##"
|
||||
-@($(CHECKER) $(top_builddir)/testThreads ; \
|
||||
-($(CHECKER) $(top_builddir)/testThreads ; \
|
||||
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";)
|
||||
|
||||
Readertests : testReader$(EXEEXT)
|
||||
Readertests : xmllint$(EXEEXT)
|
||||
@(echo > .memdump)
|
||||
@echo "##"
|
||||
@echo "## Reader regression tests"
|
||||
|
102
dict.c
102
dict.c
@ -40,11 +40,21 @@ typedef struct _xmlDictEntry xmlDictEntry;
|
||||
typedef xmlDictEntry *xmlDictEntryPtr;
|
||||
struct _xmlDictEntry {
|
||||
struct _xmlDictEntry *next;
|
||||
xmlChar *name;
|
||||
const xmlChar *name;
|
||||
int len;
|
||||
int valid;
|
||||
};
|
||||
|
||||
typedef struct _xmlDictStrings xmlDictStrings;
|
||||
typedef xmlDictStrings *xmlDictStringsPtr;
|
||||
struct _xmlDictStrings {
|
||||
xmlDictStringsPtr next;
|
||||
xmlChar *free;
|
||||
xmlChar *end;
|
||||
int size;
|
||||
int nbStrings;
|
||||
xmlChar array[1];
|
||||
};
|
||||
/*
|
||||
* The entire dictionnary
|
||||
*/
|
||||
@ -52,8 +62,58 @@ struct _xmlDict {
|
||||
struct _xmlDictEntry *dict;
|
||||
int size;
|
||||
int nbElems;
|
||||
xmlDictStringsPtr strings;
|
||||
};
|
||||
|
||||
/*
|
||||
* xmlDictAddString:
|
||||
* @dict: the dictionnary
|
||||
* @name: the name of the userdata
|
||||
* @len: the length of the name, if -1 it is recomputed
|
||||
*
|
||||
* Add the string to the array[s]
|
||||
*
|
||||
* Returns the pointer of the local string, or NULL in case of error.
|
||||
*/
|
||||
static const xmlChar *
|
||||
xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) {
|
||||
xmlDictStringsPtr pool;
|
||||
const xmlChar *ret;
|
||||
int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
|
||||
|
||||
pool = dict->strings;
|
||||
while (pool != NULL) {
|
||||
if (pool->end - pool->free > namelen)
|
||||
goto found_pool;
|
||||
if (pool->size > size) size = pool->size;
|
||||
pool = pool->next;
|
||||
}
|
||||
/*
|
||||
* Not found, need to allocate
|
||||
*/
|
||||
if (pool == NULL) {
|
||||
if (size == 0) size = 1000;
|
||||
else size *= 4; /* exponential growth */
|
||||
if (size < 4 * namelen)
|
||||
size = 4 * namelen; /* just in case ! */
|
||||
pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
|
||||
if (pool == NULL)
|
||||
return(NULL);
|
||||
pool->size = size;
|
||||
pool->nbStrings = 0;
|
||||
pool->free = &pool->array[0];
|
||||
pool->end = &pool->array[size];
|
||||
pool->next = dict->strings;
|
||||
dict->strings = pool;
|
||||
}
|
||||
found_pool:
|
||||
ret = pool->free;
|
||||
memcpy(pool->free, name, namelen);
|
||||
pool->free += namelen;
|
||||
*(pool->free++) = 0;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* xmlDictComputeKey:
|
||||
* Calculate the hash key
|
||||
@ -110,6 +170,7 @@ xmlDictCreate(void) {
|
||||
dict->size = MIN_DICT_SIZE;
|
||||
dict->nbElems = 0;
|
||||
dict->dict = xmlMalloc(MIN_DICT_SIZE * sizeof(xmlDictEntry));
|
||||
dict->strings = NULL;
|
||||
if (dict->dict) {
|
||||
memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
|
||||
return(dict);
|
||||
@ -226,6 +287,7 @@ xmlDictFree(xmlDictPtr dict) {
|
||||
xmlDictEntryPtr iter;
|
||||
xmlDictEntryPtr next;
|
||||
int inside_dict = 0;
|
||||
xmlDictStringsPtr pool, nextp;
|
||||
|
||||
if (dict == NULL)
|
||||
return;
|
||||
@ -237,8 +299,6 @@ xmlDictFree(xmlDictPtr dict) {
|
||||
inside_dict = 1;
|
||||
while (iter) {
|
||||
next = iter->next;
|
||||
if (iter->name)
|
||||
xmlFree(iter->name);
|
||||
if (!inside_dict)
|
||||
xmlFree(iter);
|
||||
dict->nbElems--;
|
||||
@ -249,6 +309,12 @@ xmlDictFree(xmlDictPtr dict) {
|
||||
}
|
||||
xmlFree(dict->dict);
|
||||
}
|
||||
pool = dict->strings;
|
||||
while (pool != NULL) {
|
||||
nextp = pool->next;
|
||||
xmlFree(pool);
|
||||
pool = nextp;
|
||||
}
|
||||
xmlFree(dict);
|
||||
}
|
||||
|
||||
@ -294,6 +360,9 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
|
||||
return(insert->name);
|
||||
}
|
||||
|
||||
ret = xmlDictAddString(dict, name, len);
|
||||
if (ret == NULL)
|
||||
return(NULL);
|
||||
if (insert == NULL) {
|
||||
entry = &(dict->dict[key]);
|
||||
} else {
|
||||
@ -301,8 +370,7 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
|
||||
if (entry == NULL)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
ret = entry->name = xmlStrndup(name, len);
|
||||
entry->name = ret;
|
||||
entry->len = len;
|
||||
entry->next = NULL;
|
||||
entry->valid = 1;
|
||||
@ -321,6 +389,30 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlDictOwns:
|
||||
* @dict: the dictionnary
|
||||
* @str: the string
|
||||
*
|
||||
* check if a string is owned by the disctionary
|
||||
*
|
||||
* Returns 1 if true, 0 if false and -1 in case of error
|
||||
* -1 in case of error
|
||||
*/
|
||||
int
|
||||
xmlDictOwns(xmlDictPtr dict, const xmlChar *str) {
|
||||
xmlDictStringsPtr pool;
|
||||
|
||||
if ((dict == NULL) || (str == NULL))
|
||||
return(-1);
|
||||
pool = dict->strings;
|
||||
while (pool != NULL) {
|
||||
if ((str >= pool->array) && (str <= pool->free))
|
||||
return(1);
|
||||
pool = pool->next;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
/**
|
||||
* xmlDictSize:
|
||||
* @dict: the dictionnary
|
||||
|
@ -47,6 +47,9 @@ XMLPUBFUN const xmlChar * XMLCALL
|
||||
xmlDictLookup (xmlDictPtr dict,
|
||||
const xmlChar *name,
|
||||
int len);
|
||||
XMLPUBFUN int XMLCALL
|
||||
xmlDictOwns (xmlDictPtr dict,
|
||||
const xmlChar *str);
|
||||
XMLPUBFUN int XMLCALL
|
||||
xmlDictSize (xmlDictPtr dict);
|
||||
#ifdef __cplusplus
|
||||
|
@ -618,7 +618,7 @@ static void streamFile(char *filename) {
|
||||
xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
|
||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||
if (relaxng != NULL) {
|
||||
if (timing) {
|
||||
if ((timing) && (!repeat)) {
|
||||
startTimer();
|
||||
}
|
||||
ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
|
||||
@ -627,7 +627,7 @@ static void streamFile(char *filename) {
|
||||
"Relax-NG schema %s failed to compile\n", relaxng);
|
||||
relaxng = NULL;
|
||||
}
|
||||
if (timing) {
|
||||
if ((timing) && (!repeat)) {
|
||||
endTimer("Compiling the schemas");
|
||||
}
|
||||
}
|
||||
@ -636,7 +636,7 @@ static void streamFile(char *filename) {
|
||||
/*
|
||||
* Process all nodes in sequence
|
||||
*/
|
||||
if (timing) {
|
||||
if ((timing) && (!repeat)) {
|
||||
startTimer();
|
||||
}
|
||||
ret = xmlTextReaderRead(reader);
|
||||
@ -645,7 +645,7 @@ static void streamFile(char *filename) {
|
||||
processNode(reader);
|
||||
ret = xmlTextReaderRead(reader);
|
||||
}
|
||||
if (timing) {
|
||||
if ((timing) && (!repeat)) {
|
||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||
if ((valid) || (relaxng != NULL))
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user