From cc3ac382a2827a42d45f3fcb5e2149c163667ba0 Mon Sep 17 00:00:00 2001 From: Matúš Kukan Date: Thu, 25 Sep 2014 14:45:55 +0200 Subject: FastSerializer: Do not keep whole sequence in memory; write in chunks Change-Id: Ibca65a2b8397358ac4013c8e5b53389ac6949e4d --- comphelper/source/streaming/seqstream.cxx | 2 ++ include/comphelper/seqstream.hxx | 11 +++++++---- sax/source/tools/fastserializer.cxx | 19 +++++++++++++++---- sax/source/tools/fastserializer.hxx | 2 ++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/comphelper/source/streaming/seqstream.cxx b/comphelper/source/streaming/seqstream.cxx index d66ce3bde083..aec451986075 100644 --- a/comphelper/source/streaming/seqstream.cxx +++ b/comphelper/source/streaming/seqstream.cxx @@ -214,6 +214,8 @@ void SAL_CALL OSequenceOutputStream::flush( ) throw(NotConnectedException, Buff // cut the sequence to the real size m_rSequence.realloc(m_nSize); + // and next time write to the beginning + m_nSize = 0; } diff --git a/include/comphelper/seqstream.hxx b/include/comphelper/seqstream.hxx index 13dd4dc42550..75b19343299c 100644 --- a/include/comphelper/seqstream.hxx +++ b/include/comphelper/seqstream.hxx @@ -115,13 +115,16 @@ public: virtual ~OSequenceOutputStream() { if (m_bConnected) closeOutput(); } + sal_Int32 getSize() const { return m_nSize; } + /// same as XOutputStream::writeBytes (as expected :) virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& aData ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - /// this is a dummy in this implementation, no buffering is used + /** Resizes the sequence used for writing to the really used size. + * Next time, writeBytes will write to the beginning of the sequence. + */ virtual void SAL_CALL flush( ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - /** closes the output stream. In the case of this class, this means that the sequence used for writing is - resized to the really used size and not used any further, every subsequent call to one of the XOutputStream - methods will throw a NotConnectedException. + /** Calls flush() and closes the output stream to prevent further manipulation with the sequence. + Every subsequent call to one of the XOutputStream methods will throw a NotConnectedException. */ virtual void SAL_CALL closeOutput( ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; }; diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx index dfa37c7434f4..d85bfefd700a 100644 --- a/sax/source/tools/fastserializer.cxx +++ b/sax/source/tools/fastserializer.cxx @@ -53,8 +53,8 @@ using ::com::sun::star::io::BufferSizeExceededException; namespace sax_fastparser { FastSaxSerializer::FastSaxSerializer( ) - : maOutputData() - , maOutputStream(maOutputData) + : maOutputData(0x4000) + , maOutputStream(maOutputData, 1.3, 0x1000, 0x4000) , mxOutputStream() , mxFastTokenHandler() , maMarkStack() @@ -298,7 +298,7 @@ namespace sax_fastparser { if ( maMarkStack.size() == 1 && eMergeType != MERGE_MARKS_IGNORE) { - maOutputStream.writeBytes( maMarkStack.top()->getData() ); + writeOutput( maMarkStack.top()->getData() ); maMarkStack.pop(); return; } @@ -319,11 +319,22 @@ namespace sax_fastparser { void FastSaxSerializer::writeBytes( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ) { if ( maMarkStack.empty() ) - maOutputStream.writeBytes( aData ); + writeOutput( aData ); else maMarkStack.top()->append( aData ); } + void FastSaxSerializer::writeOutput( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ) + { + maOutputStream.writeBytes( aData ); + // Write when the sequence gets big enough + if (maOutputStream.getSize() > 0x10000) + { + maOutputStream.flush(); + mxOutputStream->writeBytes(maOutputData); + } + } + FastSaxSerializer::Int8Sequence& FastSaxSerializer::ForMerge::getData() { merge( maData, maPostponed, true ); diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx index 147d7671d160..45535f25b74f 100644 --- a/sax/source/tools/fastserializer.hxx +++ b/sax/source/tools/fastserializer.hxx @@ -217,6 +217,8 @@ private: void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ); void write( const OUString& s ); + void writeOutput( const css::uno::Sequence< ::sal_Int8 >& aData ) + throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException); protected: rtl::ByteSequence maClosingBracket; -- cgit