From 916a11d26cb74da9dd534e07b35737def6cbf54a Mon Sep 17 00:00:00 2001 From: Mohammed Abdul Azeem Date: Thu, 28 Jul 2016 23:10:12 +0530 Subject: GSoC - moving FastAttributeList::clear to consumer thread: this shares the load of clearing the attributes list with the consumer when producer is busy. Change-Id: I6e89858703c7af9c30b2d99fd6825dc81290b488 Reviewed-on: https://gerrit.libreoffice.org/27649 Tested-by: Jenkins Reviewed-by: Michael Meeks --- sax/source/fastparser/fastparser.cxx | 50 ++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) (limited to 'sax/source') diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index ab324a1f40db..8fa922379f64 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -70,7 +70,11 @@ struct Entity; typedef std::unordered_map< OUString, sal_Int32, OUStringHash > NamespaceMap; -typedef std::vector EventList; +struct EventList +{ + std::vector maEvents; + bool mbIsAttributesEmpty; +}; enum CallbackType { INVALID, START_ELEMENT, END_ELEMENT, CHARACTERS, DONE, EXCEPTION }; @@ -531,7 +535,7 @@ EventList* Entity::getEventList() if (!mpProducedEvents) { mpProducedEvents = new EventList(); - mpProducedEvents->resize(mnEventListSize); + mpProducedEvents->maEvents.resize(mnEventListSize); mnProducedEventsSize = 0; } } @@ -544,7 +548,7 @@ Event& Entity::getEvent( CallbackType aType ) return maSharedEvent; EventList* pEventList = getEventList(); - Event& rEvent = (*pEventList)[mnProducedEventsSize++]; + Event& rEvent = pEventList->maEvents[mnProducedEventsSize++]; rEvent.maType = aType; return rEvent; } @@ -783,6 +787,24 @@ void FastSaxParserImpl::parseStream(const InputSource& maStructSource) done = true; aGuard.reset(); // lock + + if ( rEntity.maPendingEvents.size() <= rEntity.mnEventLowWater ) + { + aGuard.clear(); + for (auto aEventIt = pEventList->maEvents.begin(); + aEventIt != pEventList->maEvents.end(); ++aEventIt) + { + if (aEventIt->mxAttributes.is()) + { + aEventIt->mxAttributes->clear(); + if( rEntity.mxNamespaceHandler.is() ) + aEventIt->mxDeclAttributes->clear(); + } + pEventList->mbIsAttributesEmpty = true; + } + aGuard.reset(); + } + rEntity.maUsedEvents.push(pEventList); } } while (!done); @@ -926,8 +948,9 @@ void FastSaxParserImpl::produce( bool bForceFlush ) bool FastSaxParserImpl::consume(EventList *pEventList) { Entity& rEntity = getEntity(); - for (EventList::iterator aEventIt = pEventList->begin(); - aEventIt != pEventList->end(); ++aEventIt) + pEventList->mbIsAttributesEmpty = false; + for (auto aEventIt = pEventList->maEvents.begin(); + aEventIt != pEventList->maEvents.end(); ++aEventIt) { switch ((*aEventIt).maType) { @@ -1042,17 +1065,28 @@ void FastSaxParserImpl::callbackStartElement(const xmlChar *localName , const xm } // create attribute map and process namespace instructions - Event& rEvent = getEntity().getEvent( START_ELEMENT ); + Event& rEvent = rEntity.getEvent( START_ELEMENT ); + bool bIsAttributesEmpty = false; + if ( rEntity.mbEnableThreads ) + bIsAttributesEmpty = rEntity.getEventList()->mbIsAttributesEmpty; + if (rEvent.mxAttributes.is()) - rEvent.mxAttributes->clear(); + { + if( !bIsAttributesEmpty ) + rEvent.mxAttributes->clear(); + } else rEvent.mxAttributes.set( new FastAttributeList( rEntity.mxTokenHandler, rEntity.mpTokenHandler ) ); + if( rEntity.mxNamespaceHandler.is() ) { if (rEvent.mxDeclAttributes.is()) - rEvent.mxDeclAttributes->clear(); + { + if( !bIsAttributesEmpty ) + rEvent.mxDeclAttributes->clear(); + } else rEvent.mxDeclAttributes.set( new FastAttributeList( rEntity.mxTokenHandler, -- cgit v1.2.3