summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatúš Kukan <matus.kukan@gmail.com>2013-10-16 19:58:36 +0200
committerMatúš Kukan <matus.kukan@gmail.com>2013-10-17 21:38:40 +0200
commitaeca826f3463a831182cc9824b5ee229150cc1e5 (patch)
treef14d960c1a80aafce631b041a4c3ef080eb6ffa0
parent7aa35dcb43a8d626873a04196e37391ea8f0a878 (diff)
fastparser: don't use multithreading for small documents
Determined by XInputStream::available(). Change-Id: I450f4796d9c072b395393582bfc3e1e7768e243b
-rw-r--r--sax/source/fastparser/fastparser.cxx80
-rw-r--r--sax/source/fastparser/fastparser.hxx5
2 files changed, 57 insertions, 28 deletions
diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx
index fead88dbc9fe..d7635d9c22b9 100644
--- a/sax/source/fastparser/fastparser.cxx
+++ b/sax/source/fastparser/fastparser.cxx
@@ -204,6 +204,7 @@ Entity::Entity( const ParserData& rData ) :
Entity::Entity( const Entity& e ) :
ParserData( e )
+ ,mbEnableThreads(e.mbEnableThreads)
,maStructSource(e.maStructSource)
,mpParser(e.mpParser)
,maConverter(e.maConverter)
@@ -330,6 +331,9 @@ EventList* Entity::getEventList()
Event& Entity::getEvent( CallbackType aType )
{
+ if (!mbEnableThreads)
+ return maSharedEvent;
+
EventList* pEventList = getEventList();
Event& rEvent = (*pEventList)[mnProducedEventsSize++];
rEvent.maType = aType;
@@ -570,33 +574,42 @@ void FastSaxParser::parseStream( const InputSource& maStructSource) throw (SAXEx
entity.mxDocumentHandler->startDocument();
}
- rtl::Reference<ParserThread> xParser;
- xParser = new ParserThread(this);
- xParser->launch();
- bool done = false;
- do {
- rEntity.maConsumeResume.wait();
- rEntity.maConsumeResume.reset();
+ rEntity.mbEnableThreads = (rEntity.maStructSource.aInputStream->available() > 10000);
- osl::ResettableMutexGuard aGuard(rEntity.maEventProtector);
- while (!rEntity.maPendingEvents.empty())
- {
- if (rEntity.maPendingEvents.size() <= rEntity.mnEventLowWater)
- rEntity.maProduceResume.set(); // start producer again
+ if (rEntity.mbEnableThreads)
+ {
+ rtl::Reference<ParserThread> xParser;
+ xParser = new ParserThread(this);
+ xParser->launch();
+ bool done = false;
+ do {
+ rEntity.maConsumeResume.wait();
+ rEntity.maConsumeResume.reset();
+
+ osl::ResettableMutexGuard aGuard(rEntity.maEventProtector);
+ while (!rEntity.maPendingEvents.empty())
+ {
+ if (rEntity.maPendingEvents.size() <= rEntity.mnEventLowWater)
+ rEntity.maProduceResume.set(); // start producer again
- EventList *pEventList = rEntity.maPendingEvents.front();
- rEntity.maPendingEvents.pop();
- aGuard.clear(); // unlock
+ EventList *pEventList = rEntity.maPendingEvents.front();
+ rEntity.maPendingEvents.pop();
+ aGuard.clear(); // unlock
- if (!consume(pEventList))
- done = true;
+ if (!consume(pEventList))
+ done = true;
- aGuard.reset(); // lock
- rEntity.maUsedEvents.push(pEventList);
- }
- } while (!done);
- xParser->join();
- deleteUsedEvents();
+ aGuard.reset(); // lock
+ rEntity.maUsedEvents.push(pEventList);
+ }
+ } while (!done);
+ xParser->join();
+ deleteUsedEvents();
+ }
+ else
+ {
+ parse();
+ }
// finish document
if( entity.mxDocumentHandler.is() )
@@ -906,7 +919,8 @@ void FastSaxParser::parse()
}
while( nRead > 0 );
rEntity.getEvent( CallbackType::DONE );
- produce( CallbackType::DONE );
+ if (rEntity.mbEnableThreads)
+ produce( CallbackType::DONE );
}
//------------------------------------------
@@ -1023,7 +1037,10 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char
rEntity.maNamespaceStack.push( NameWithToken(rEvent.msNamespace, nNamespaceToken) );
rEvent.msElementName = OUString(pName, nNameLen, RTL_TEXTENCODING_UTF8);
- produce( CallbackType::START_ELEMENT );
+ if (rEntity.mbEnableThreads)
+ produce( CallbackType::START_ELEMENT );
+ else
+ rEntity.startElement( &rEvent );
}
catch (const Exception& e)
{
@@ -1043,15 +1060,22 @@ void FastSaxParser::callbackEndElement( SAL_UNUSED_PARAMETER const XML_Char* )
rEntity.maNamespaceStack.pop();
rEntity.getEvent( CallbackType::END_ELEMENT );
- produce( CallbackType::END_ELEMENT );
+ if (rEntity.mbEnableThreads)
+ produce( CallbackType::END_ELEMENT );
+ else
+ rEntity.endElement();
}
void FastSaxParser::callbackCharacters( const XML_Char* s, int nLen )
{
- Event& rEvent = getEntity().getEvent( CallbackType::CHARACTERS );
+ Entity& rEntity = getEntity();
+ Event& rEvent = rEntity.getEvent( CallbackType::CHARACTERS );
rEvent.msChars = OUString(s, nLen, RTL_TEXTENCODING_UTF8);
- produce( CallbackType::CHARACTERS );
+ if (rEntity.mbEnableThreads)
+ produce( CallbackType::CHARACTERS );
+ else
+ rEntity.characters( rEvent.msChars );
}
void FastSaxParser::callbackEntityDecl(
diff --git a/sax/source/fastparser/fastparser.hxx b/sax/source/fastparser/fastparser.hxx
index f1b625a4d48b..972ce07f542e 100644
--- a/sax/source/fastparser/fastparser.hxx
+++ b/sax/source/fastparser/fastparser.hxx
@@ -107,6 +107,7 @@ struct Entity : public ParserData
{
// Amount of work producer sends to consumer in one iteration:
static const size_t mnEventListSize = 1000;
+
// unique for each Entity instance:
// Number of valid events in mpProducedEvents:
@@ -120,9 +121,13 @@ struct Entity : public ParserData
static const size_t mnEventHighWater = 8;
osl::Condition maConsumeResume;
osl::Condition maProduceResume;
+ // Event we use to store data if threading is disabled:
+ Event maSharedEvent;
// copied in copy constructor:
+ // Allow to disable threading for small documents:
+ bool mbEnableThreads;
::com::sun::star::xml::sax::InputSource maStructSource;
XML_Parser mpParser;
::sax_expatwrap::XMLFile2UTFConverter maConverter;