diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2002-03-20 19:24:21 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2002-03-20 19:24:21 +0000 |
commit | e50f3b5d54496e3afb411a9c3012c697b75eb34e (patch) | |
tree | ba2929e5f7179fda994f03b8cbe28baff3c475ce /xmlIO.c | |
parent | c62a147963b5839fc815267706eaec381f90ca16 (diff) | |
download | android_external_libxml2-e50f3b5d54496e3afb411a9c3012c697b75eb34e.tar.gz android_external_libxml2-e50f3b5d54496e3afb411a9c3012c697b75eb34e.tar.bz2 android_external_libxml2-e50f3b5d54496e3afb411a9c3012c697b75eb34e.zip |
I wanted to see the real speed at the SAX interface after a little too
* testSAX.c: I wanted to see the real speed at the SAX interface
after a little too many Ximianer started complaining about the
parser speed.
added a --quiet option:
paphio:~/XML -> ls -l db100000.xml
-rw-rw-r-- 1 veillard www 20182040 Mar 20 10:30 db100000.xml
paphio:~/XML -> time ./testSAX --quiet db100000.xml
3200006 callbacks generated
real 0m1.270s
Which means 16MBytes/s and 3Mcallback/s
Daniel
Diffstat (limited to 'xmlIO.c')
-rw-r--r-- | xmlIO.c | 156 |
1 files changed, 148 insertions, 8 deletions
@@ -33,6 +33,14 @@ #include <zlib.h> #endif +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +/* seems needed for Solaris */ +#ifndef MAP_FAILED +#define MAP_FAILED ((void *) -1) +#endif +#endif + /* Figure a portable way to know if a file is a directory. */ #ifndef HAVE_STAT # ifdef HAVE__STAT @@ -1947,6 +1955,84 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) { return(ret); } +#ifdef HAVE_SYS_MMAN_H +typedef struct _xmlMMapContext xmlMMapContext; +typedef xmlMMapContext *xmlMMapContextPtr; +struct _xmlMMapContext { + int fd; + const char *mem; + size_t size; +}; + +/** + * xmlParserInputBufferCloseMMapFile: + * @ctxt: the mmaped context + * + * Free up the resources associated to the mmaped file + */ +static void +xmlParserInputBufferCloseMMapFile(xmlMMapContextPtr ctxt) { + if (ctxt == NULL) + return; + if (ctxt->mem != (void *) MAP_FAILED) + munmap((char *) ctxt->mem, ctxt->size); + if (ctxt->fd >= 0) + close(ctxt->fd); + xmlFree(ctxt); +} + +/** + * xmlParserInputBufferCreateMMapFile: + * @fd: the descriptor associated to the mmaped file. + * @base: the mmaped start + * @size: the length of the memory block + * @enc: the charset encoding if known + * + * Create a buffered parser input for the progressive parsing for the input + * from a memory area. + * + * Returns the new parser input or NULL + */ +static xmlParserInputBufferPtr +xmlParserInputBufferCreateMMapFile(int fd, const char *mem, size_t size, + xmlCharEncoding enc) { + xmlParserInputBufferPtr ret; + xmlMMapContextPtr ctxt; + + if (fd < 0) return(NULL); + if (size <= 0) return(NULL); + if (mem == NULL) return(NULL); + + ctxt = (xmlMMapContextPtr) xmlMalloc(sizeof(xmlMMapContext)); + if (ctxt == NULL) + return(NULL); + ctxt->fd = fd; + ctxt->mem = mem; + ctxt->size = size; + + + ret = xmlAllocParserInputBuffer(enc); + if (ret != NULL) { + ret->context = (void *) ctxt; + ret->readcallback = (xmlInputReadCallback) xmlNop; + ret->closecallback = (xmlInputCloseCallback) + xmlParserInputBufferCloseMMapFile; + if (ret->buffer->content != NULL) { + xmlFree(ret->buffer->content); + } + ret->buffer->alloc = XML_BUFFER_ALLOC_UNMUTABLE; + ret->buffer->content = (xmlChar *) mem; + ret->buffer->size = size; + ret->buffer->use = size; + } else { + xmlFree(ctxt); + return(NULL); + } + + return(ret); +} +#endif + /** * xmlOutputBufferCreateFd: * @fd: a file descriptor number @@ -2433,8 +2519,7 @@ xmlParserGetDirectory(const char *filename) { * * ****************************************************************/ -#ifdef LIBXML_CATALOG_ENABLED -static int xmlSysIDExists(const char *URL) { +static const char * xmlSysIDExists(const char *URL, size_t *size) { #ifdef HAVE_STAT int ret; struct stat info; @@ -2454,12 +2539,16 @@ static int xmlSysIDExists(const char *URL) { } else path = URL; ret = stat(path, &info); - if (ret == 0) - return(1); + if (ret == 0) { + if (size) + *size = info.st_size; + return(path); + } #endif - return(0); + if (size) + *size = -1; + return(NULL); } -#endif /** * xmlDefaultExternalEntityLoader: @@ -2480,7 +2569,57 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID, #ifdef LIBXML_CATALOG_ENABLED xmlCatalogAllow pref; #endif + const char *exist; + size_t length; + exist = xmlSysIDExists(URL, &length); +#ifdef HAVE_SYS_MMAN_H + /* + * Shortcut, if asked for a file, the file is present, mmap it ! + */ + if ((exist != NULL) && (length > 0)) { + int fd = -1; + const char *base = NULL; + xmlParserInputBufferPtr buf = NULL; + + if ((fd = open(exist, O_RDONLY)) >= 0) { + /* + * Magic test: don't drop back native compressed content support + */ + char tmpbuf[2]; + if (read(fd, tmpbuf, 2) != 2) + goto failed; + if ((tmpbuf[0] == 0x1F) && (tmpbuf[1] == 0x8B)) + goto failed; + + base = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0); + if (base != (void *) MAP_FAILED) { + buf = xmlParserInputBufferCreateMMapFile(fd, base, length, + XML_CHAR_ENCODING_NONE); + if (buf != NULL) { + ret = xmlNewInputStream(ctxt); + if (ret != NULL) { + ret->filename = (const char *) xmlCharStrdup(exist); + ret->directory = (const char *) + xmlParserGetDirectory(exist); + ret->buf = buf; + ret->base = ret->buf->buffer->content; + ret->cur = ret->buf->buffer->content; + ret->end = &ret->base[ret->buf->buffer->use]; + return(ret); + } + } + } + } +failed: + if (buf != NULL) + xmlFreeParserInputBuffer(buf); + if (base != (void *) MAP_FAILED) + munmap((char *) base, length); + if (fd >= 0) + close(fd); + } +#endif #ifdef DEBUG_EXTERNAL_ENTITIES xmlGenericError(xmlGenericErrorContext, "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL); @@ -2492,7 +2631,7 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID, */ pref = xmlCatalogGetDefaults(); - if ((pref != XML_CATA_ALLOW_NONE) && (!xmlSysIDExists(URL))) { + if ((pref != XML_CATA_ALLOW_NONE) && (exist == NULL)) { /* * Do a local lookup */ @@ -2518,7 +2657,8 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID, /* * TODO: do an URI lookup on the reference */ - if ((resource != NULL) && (!xmlSysIDExists((const char *)resource))) { + exist = xmlSysIDExists(URL, &length); + if ((resource != NULL) && (exist == NULL)) { xmlChar *tmp = NULL; if ((ctxt->catalogs != NULL) && |