1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-10-26 12:25:09 +03: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:
Daniel Veillard 2003-09-16 23:17:26 +00:00
parent 9582d6ca54
commit 81514ba478
5 changed files with 113 additions and 11 deletions

View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -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