Kaydet (Commit) aeca826f authored tarafından Matúš Kukan's avatar Matúš Kukan

fastparser: don't use multithreading for small documents

Determined by XInputStream::available().

Change-Id: I450f4796d9c072b395393582bfc3e1e7768e243b
üst 7aa35dcb
...@@ -204,6 +204,7 @@ Entity::Entity( const ParserData& rData ) : ...@@ -204,6 +204,7 @@ Entity::Entity( const ParserData& rData ) :
Entity::Entity( const Entity& e ) : Entity::Entity( const Entity& e ) :
ParserData( e ) ParserData( e )
,mbEnableThreads(e.mbEnableThreads)
,maStructSource(e.maStructSource) ,maStructSource(e.maStructSource)
,mpParser(e.mpParser) ,mpParser(e.mpParser)
,maConverter(e.maConverter) ,maConverter(e.maConverter)
...@@ -330,6 +331,9 @@ EventList* Entity::getEventList() ...@@ -330,6 +331,9 @@ EventList* Entity::getEventList()
Event& Entity::getEvent( CallbackType aType ) Event& Entity::getEvent( CallbackType aType )
{ {
if (!mbEnableThreads)
return maSharedEvent;
EventList* pEventList = getEventList(); EventList* pEventList = getEventList();
Event& rEvent = (*pEventList)[mnProducedEventsSize++]; Event& rEvent = (*pEventList)[mnProducedEventsSize++];
rEvent.maType = aType; rEvent.maType = aType;
...@@ -570,33 +574,42 @@ void FastSaxParser::parseStream( const InputSource& maStructSource) throw (SAXEx ...@@ -570,33 +574,42 @@ void FastSaxParser::parseStream( const InputSource& maStructSource) throw (SAXEx
entity.mxDocumentHandler->startDocument(); entity.mxDocumentHandler->startDocument();
} }
rtl::Reference<ParserThread> xParser; rEntity.mbEnableThreads = (rEntity.maStructSource.aInputStream->available() > 10000);
xParser = new ParserThread(this);
xParser->launch();
bool done = false;
do {
rEntity.maConsumeResume.wait();
rEntity.maConsumeResume.reset();
osl::ResettableMutexGuard aGuard(rEntity.maEventProtector); if (rEntity.mbEnableThreads)
while (!rEntity.maPendingEvents.empty()) {
{ rtl::Reference<ParserThread> xParser;
if (rEntity.maPendingEvents.size() <= rEntity.mnEventLowWater) xParser = new ParserThread(this);
rEntity.maProduceResume.set(); // start producer again 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(); EventList *pEventList = rEntity.maPendingEvents.front();
rEntity.maPendingEvents.pop(); rEntity.maPendingEvents.pop();
aGuard.clear(); // unlock aGuard.clear(); // unlock
if (!consume(pEventList)) if (!consume(pEventList))
done = true; done = true;
aGuard.reset(); // lock aGuard.reset(); // lock
rEntity.maUsedEvents.push(pEventList); rEntity.maUsedEvents.push(pEventList);
} }
} while (!done); } while (!done);
xParser->join(); xParser->join();
deleteUsedEvents(); deleteUsedEvents();
}
else
{
parse();
}
// finish document // finish document
if( entity.mxDocumentHandler.is() ) if( entity.mxDocumentHandler.is() )
...@@ -906,7 +919,8 @@ void FastSaxParser::parse() ...@@ -906,7 +919,8 @@ void FastSaxParser::parse()
} }
while( nRead > 0 ); while( nRead > 0 );
rEntity.getEvent( CallbackType::DONE ); 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 ...@@ -1023,7 +1037,10 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char
rEntity.maNamespaceStack.push( NameWithToken(rEvent.msNamespace, nNamespaceToken) ); rEntity.maNamespaceStack.push( NameWithToken(rEvent.msNamespace, nNamespaceToken) );
rEvent.msElementName = OUString(pName, nNameLen, RTL_TEXTENCODING_UTF8); 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) catch (const Exception& e)
{ {
...@@ -1043,15 +1060,22 @@ void FastSaxParser::callbackEndElement( SAL_UNUSED_PARAMETER const XML_Char* ) ...@@ -1043,15 +1060,22 @@ void FastSaxParser::callbackEndElement( SAL_UNUSED_PARAMETER const XML_Char* )
rEntity.maNamespaceStack.pop(); rEntity.maNamespaceStack.pop();
rEntity.getEvent( CallbackType::END_ELEMENT ); 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 ) 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); 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( void FastSaxParser::callbackEntityDecl(
......
...@@ -107,6 +107,7 @@ struct Entity : public ParserData ...@@ -107,6 +107,7 @@ struct Entity : public ParserData
{ {
// Amount of work producer sends to consumer in one iteration: // Amount of work producer sends to consumer in one iteration:
static const size_t mnEventListSize = 1000; static const size_t mnEventListSize = 1000;
// unique for each Entity instance: // unique for each Entity instance:
// Number of valid events in mpProducedEvents: // Number of valid events in mpProducedEvents:
...@@ -120,9 +121,13 @@ struct Entity : public ParserData ...@@ -120,9 +121,13 @@ struct Entity : public ParserData
static const size_t mnEventHighWater = 8; static const size_t mnEventHighWater = 8;
osl::Condition maConsumeResume; osl::Condition maConsumeResume;
osl::Condition maProduceResume; osl::Condition maProduceResume;
// Event we use to store data if threading is disabled:
Event maSharedEvent;
// copied in copy constructor: // copied in copy constructor:
// Allow to disable threading for small documents:
bool mbEnableThreads;
::com::sun::star::xml::sax::InputSource maStructSource; ::com::sun::star::xml::sax::InputSource maStructSource;
XML_Parser mpParser; XML_Parser mpParser;
::sax_expatwrap::XMLFile2UTFConverter maConverter; ::sax_expatwrap::XMLFile2UTFConverter maConverter;
......
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