2020#include < stdlib.h>
2121#include < map>
2222#include < set>
23+ #include < thread>
24+ #include < condition_variable>
2325#include " Type.hpp"
2426#include " WireType.hpp"
2527
@@ -115,18 +117,18 @@ class SerializationBufferBlock {
115117 size_t m_size;
116118 size_t m_reserved;
117119 uint8_t * m_buffer;
118-
119120 bool m_compressed;
120121};
121122
122123class SerializationBuffer {
123124public:
124125 SerializationBuffer (const SerializationContext& context) :
125126 m_context (context),
126- m_wants_compress (context.isCompressionEnabled())
127+ m_wants_compress (context.isCompressionEnabled()),
128+ m_compress_using_threads (context.compressUsingThreads()),
129+ m_is_consolidated (false )
127130 {
128131 m_top_block = new SerializationBufferBlock ();
129-
130132 m_blocks.push_back (std::shared_ptr<SerializationBufferBlock>(m_top_block));
131133 }
132134
@@ -265,7 +267,9 @@ class SerializationBuffer {
265267 }
266268
267269 uint8_t * buffer () {
268- consolidate ();
270+ if (!m_is_consolidated) {
271+ consolidate ();
272+ }
269273
270274 if (m_blocks.size () == 0 ) {
271275 return nullptr ;
@@ -293,30 +297,23 @@ class SerializationBuffer {
293297
294298 // nakedly write bytes into the stream
295299 void write_bytes (uint8_t * ptr, size_t bytecount) {
296- if (m_top_block->isCompressed () || m_top_block->oversized ()) {
297- m_top_block = new SerializationBufferBlock ();
298- m_blocks.push_back (
299- std::shared_ptr<SerializationBufferBlock>(
300- m_top_block
301- )
302- );
300+ while (bytecount > 1024 * 1024 ) {
301+ write_bytes (ptr, 1024 * 1024 );
302+
303+ ptr += 1024 * 1024 ;
304+ bytecount -= 1024 * 1024 ;
303305 }
304306
307+ checkTopBlock ();
308+
305309 m_top_block->write_bytes (ptr, bytecount);
306310 }
307311
308312 // allocate some memory and call 'c' with a uint8_t* pointing at it
309313 // to initialize it.
310314 template <class callback >
311315 void initialize_bytes (size_t bytecount, const callback& c) {
312- if (m_top_block->isCompressed () || m_top_block->oversized ()) {
313- m_top_block = new SerializationBufferBlock ();
314- m_blocks.push_back (
315- std::shared_ptr<SerializationBufferBlock>(
316- m_top_block
317- )
318- );
319- }
316+ checkTopBlock ();
320317
321318 m_top_block->initialize_bytes (bytecount, c);
322319 }
@@ -405,24 +402,35 @@ class SerializationBuffer {
405402
406403 void finalize () {
407404 if (m_wants_compress) {
405+ markForCompression (m_blocks.back ());
406+
408407 for (auto b: m_blocks) {
409- b-> compress ( );
408+ waitForCompression (b );
410409 }
411410 }
412411 }
413412
414413 template < class T >
415414 void write (T i) {
416- if (m_top_block->isCompressed () || m_top_block->oversized ()) {
415+ checkTopBlock ();
416+
417+ m_top_block->write (i);
418+ }
419+
420+ void checkTopBlock () {
421+ if (m_top_block->oversized ()) {
417422 m_top_block = new SerializationBufferBlock ();
423+
424+ if (m_wants_compress) {
425+ markForCompression (m_blocks.back ());
426+ }
427+
418428 m_blocks.push_back (
419429 std::shared_ptr<SerializationBufferBlock>(
420430 m_top_block
421431 )
422432 );
423433 }
424-
425- m_top_block->write (i);
426434 }
427435
428436 void startSerializing (Type* nativeType) {
@@ -456,6 +464,10 @@ class SerializationBuffer {
456464
457465 bool m_wants_compress;
458466
467+ bool m_compress_using_threads;
468+
469+ bool m_is_consolidated;
470+
459471 size_t m_size;
460472
461473 // the
@@ -472,6 +484,18 @@ class SerializationBuffer {
472484 std::set<Type*> m_types_being_serialized;
473485
474486 std::unordered_map<MutuallyRecursiveTypeGroup*, int > m_group_counter;
487+
488+ static void compressionThread ();
489+ static std::shared_ptr<SerializationBufferBlock> getNextCompressTask ();
490+
491+ void markForCompression (std::shared_ptr<SerializationBufferBlock> block);
492+ void waitForCompression (std::shared_ptr<SerializationBufferBlock> block);
493+
494+ static std::mutex s_compress_thread_mutex;
495+ static std::condition_variable* s_has_work;
496+ static std::vector<std::thread*> s_compress_threads;
497+ static std::unordered_set<std::shared_ptr<SerializationBufferBlock> > s_waiting_compress_blocks;
498+ static std::unordered_set<std::shared_ptr<SerializationBufferBlock> > s_working_compress_blocks;
475499};
476500
477501class MarkTypeBeingSerialized {
0 commit comments