diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 36596cb..c858ee0 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -52,13 +52,11 @@ SET( SOURCES "src/TexComp.cpp" "src/CompressedImage.cpp" - "src/BlockStats.cpp" ) SET( HEADERS "include/TexComp.h" "include/CompressedImage.h" - "include/BlockStats.h" "src/CompressionFuncs.h" ) diff --git a/Core/include/BlockStats.h b/Core/include/BlockStats.h deleted file mode 100644 index b7f68dd..0000000 --- a/Core/include/BlockStats.h +++ /dev/null @@ -1,148 +0,0 @@ -/* FasTC - * Copyright (c) 2013 University of North Carolina at Chapel Hill. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for educational, research, and non-profit purposes, without - * fee, and without a written agreement is hereby granted, provided that the - * above copyright notice, this paragraph, and the following four paragraphs - * appear in all copies. - * - * Permission to incorporate this software into commercial products may be - * obtained by contacting the authors or the Office of Technology Development - * at the University of North Carolina at Chapel Hill . - * - * This software program and documentation are copyrighted by the University of - * North Carolina at Chapel Hill. The software program and documentation are - * supplied "as is," without any accompanying services from the University of - * North Carolina at Chapel Hill or the authors. The University of North - * Carolina at Chapel Hill and the authors do not warrant that the operation of - * the program will be uninterrupted or error-free. The end-user understands - * that the program was developed for research purposes and is advised not to - * rely exclusively on the program for any reason. - * - * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE - * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, - * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF - * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA - * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY - * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY - * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON - * AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND - * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, - * ENHANCEMENTS, OR MODIFICATIONS. - * - * Please send all BUG REPORTS to . - * - * The authors may be contacted via: - * - * Pavel Krajcevski - * Dept of Computer Science - * 201 S Columbia St - * Frederick P. Brooks, Jr. Computer Science Bldg - * Chapel Hill, NC 27599-3175 - * USA - * - * - */ - -#ifndef __BLOCK_STATS_H__ -#define __BLOCK_STATS_H__ - -#include "TexCompTypes.h" -#include "ReferenceCounter.h" - -/////////////////////////////////////////////////////////////////////////////// -// -// Forward declarations -// -/////////////////////////////////////////////////////////////////////////////// -class TCMutex; - -/////////////////////////////////////////////////////////////////////////////// -// -// class BlockStat -// -/////////////////////////////////////////////////////////////////////////////// - -struct BlockStat { - friend class BlockStatManager; - public: - BlockStat(const CHAR *statName, int); - BlockStat(const CHAR *statName, double stat); - - BlockStat(const BlockStat &); - BlockStat &operator=(const BlockStat &); - - void ToString(CHAR *buf, int bufSz) const; - - private: - const enum Type { - eType_Float, - eType_Int, - - kNumTypes - } m_Type; - - static const int kStatNameSz = 32; - CHAR m_StatName[kStatNameSz]; - union { - uint64 m_IntStat; - double m_FloatStat; - }; -}; - -class BlockStatManager { - - public: - BlockStatManager(int nBlocks); - BlockStatManager(const BlockStatManager &); - BlockStatManager &operator=(const BlockStatManager &); - ~BlockStatManager(); - - // A thread-safe version that returns a list index for recording - // block statistics. - uint32 BeginBlock(); - - // Add a stat for a given block. This is thread-safe - void AddStat(uint32 blockIdx, const BlockStat &stat); - - // Write the statistics to a file. - void ToFile(const CHAR *filename); - - private: - - class BlockStatList { - public: - BlockStatList(); - BlockStatList(const BlockStatList &other); - ~BlockStatList(); - - void AddStat(const BlockStat &stat); - BlockStat GetStat() const { return m_Stat; } - const BlockStatList *GetTail() const { return m_Tail; } - - private: - BlockStatList(const BlockStat &stat); - - BlockStatList *m_Tail; - BlockStat m_Stat; - - ReferenceCounter m_Counter; - } *m_BlockStatList; - uint32 m_BlockStatListSz; - - uint32 m_NextBlock; - ReferenceCounter m_Counter; - - TCMutex *m_Mutex; - - // Note: we probably shouldn't call this... - void Copy(const BlockStatManager &); -}; - -#endif // __BLOCK_STATS_H__ diff --git a/Core/include/TexComp.h b/Core/include/TexComp.h index bba3f1f..f62bbd6 100644 --- a/Core/include/TexComp.h +++ b/Core/include/TexComp.h @@ -47,10 +47,11 @@ #include "CompressedImage.h" #include "CompressionJob.h" +#include + // Forward declarations class Image; class ImageFile; -class BlockStatManager; struct SCompressionSettings { SCompressionSettings(); // defaults @@ -85,11 +86,9 @@ struct SCompressionSettings { // in the platform and compiler will provide synchronization. bool bUseAtomics; - // This is an optinal pointer to a stat manager class. If - // instantiated and the proper function pointer is defined - // then the compression routine that collects the stats will - // be called. - BlockStatManager *pStatManager; + // This is the output stream with which we should output the logs for the + // compression functions. + std::ostream *logStream; }; extern CompressedImage *CompressImage(Image *img, const SCompressionSettings &settings); diff --git a/Core/src/BlockStats.cpp b/Core/src/BlockStats.cpp deleted file mode 100644 index 89de020..0000000 --- a/Core/src/BlockStats.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* FasTC - * Copyright (c) 2012 University of North Carolina at Chapel Hill. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its documentation for educational, - * research, and non-profit purposes, without fee, and without a written agreement is hereby granted, - * provided that the above copyright notice, this paragraph, and the following four paragraphs appear - * in all copies. - * - * Permission to incorporate this software into commercial products may be obtained by contacting the - * authors or the Office of Technology Development at the University of North Carolina at Chapel Hill . - * - * This software program and documentation are copyrighted by the University of North Carolina at Chapel Hill. - * The software program and documentation are supplied "as is," without any accompanying services from the - * University of North Carolina at Chapel Hill or the authors. The University of North Carolina at Chapel Hill - * and the authors do not warrant that the operation of the program will be uninterrupted or error-free. The - * end-user understands that the program was developed for research purposes and is advised not to rely - * exclusively on the program for any reason. - * - * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE - * USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE - * AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY - * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY - * OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, - * ENHANCEMENTS, OR MODIFICATIONS. - * - * Please send all BUG REPORTS to . - * - * The authors may be contacted via: - * - * Pavel Krajcevski - * Dept of Computer Science - * 201 S Columbia St - * Frederick P. Brooks, Jr. Computer Science Bldg - * Chapel Hill, NC 27599-3175 - * USA - * - * - */ - -#include "BlockStats.h" - -#include -#include -#include -#include -#include - -#include "FileStream.h" -#include "Thread.h" - -//////////////////////////////////////////////////////////////////////////////// -// -// BlockStat implementation -// -//////////////////////////////////////////////////////////////////////////////// - -BlockStat::BlockStat(const CHAR *statName, int stat) - : m_Type(eType_Int) - , m_IntStat(stat) -{ -#ifdef _MSC_VER - strncpy_s(m_StatName, statName, kStatNameSz); -#else - strncpy(m_StatName, statName, kStatNameSz); -#endif -} - -BlockStat::BlockStat(const CHAR *statName, double stat) - : m_Type(eType_Float) - , m_FloatStat(stat) -{ -#ifdef _MSC_VER - strncpy_s(m_StatName, statName, kStatNameSz); -#else - strncpy(m_StatName, statName, kStatNameSz); -#endif -} - -BlockStat::BlockStat(const BlockStat &other) : m_Type(other.m_Type) { - memcpy(this, &other, sizeof(*this)); -} - -BlockStat &BlockStat::operator=(const BlockStat &other) { - memcpy(this, &other, sizeof(*this)); - return *this; -} - -void BlockStat::ToString(CHAR *buf, int bufSz) const { - switch(m_Type) { - case BlockStat::eType_Float: -#ifdef _MSC_VER - _sntprintf_s(buf, bufSz, _TRUNCATE, "%s,%f", m_StatName, m_FloatStat); -#else - snprintf(buf, bufSz, "%s,%f", m_StatName, m_FloatStat); -#endif - break; - - case BlockStat::eType_Int: -#ifdef _MSC_VER - _sntprintf_s(buf, bufSz, _TRUNCATE, "%s,%lu", m_StatName, (unsigned long)m_IntStat); -#else - snprintf(buf, bufSz, "%s,%lu", m_StatName, (unsigned long)m_IntStat); -#endif - break; - - default: - assert(!"Unknown stat type!"); - break; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -// BlockStat Manager Implementation -// -//////////////////////////////////////////////////////////////////////////////// - -void BlockStatManager::Copy(const BlockStatManager &other) { - // This is a bug. If we copy the manager then all of the lists and pointers - // become shared and can cause dereferencing issues. Check to see where you're - // copying this class and make sure to actually create a new instance. - assert(!"We shouldn't be copying these in this manner!"); - - m_BlockStatList = new BlockStatList(*other.m_BlockStatList); - m_BlockStatListSz = other.m_BlockStatListSz; - m_NextBlock = other.m_NextBlock; - - // If we do copy them, then make sure that we are actually using the exact same - // pointers for our synchronization primitives... otherwise we could run into - // deadlock issues. - m_Mutex = other.m_Mutex; -} - -BlockStatManager::BlockStatManager(const BlockStatManager &other) { - Copy(other); -} - -BlockStatManager &BlockStatManager::operator=(const BlockStatManager &other) { - m_Counter = other.m_Counter; - Copy(other); - return *this; -} - -BlockStatManager::BlockStatManager(int nBlocks) - : m_BlockStatListSz(std::max(nBlocks, 0)) - , m_NextBlock(0) - , m_Mutex(new TCMutex) -{ - m_BlockStatList = new BlockStatList[m_BlockStatListSz]; - if(!m_BlockStatList) { - fprintf(stderr, "Out of memory!\n"); - assert(false); - exit(1); - } -} - -BlockStatManager::~BlockStatManager() { - if(m_Counter.GetRefCount() == 0) { - delete [] m_BlockStatList; - } - - if(m_Mutex) - { - delete m_Mutex; - m_Mutex = 0; - } -} - -uint32 BlockStatManager::BeginBlock() { - if(m_NextBlock == m_BlockStatListSz) { - fprintf(stderr, "WARNING -- BlockStatManager::BeginBlock(), reached end of block list.\n"); - assert(false); - return m_NextBlock-1; - } - - TCLock lock (*m_Mutex); - return m_NextBlock++; -} - -void BlockStatManager::AddStat(uint32 blockIdx, const BlockStat &stat) { - if(blockIdx >= m_BlockStatListSz) { - fprintf(stderr, "WARNING -- BlockStatManager::AddStat(), block index out of bounds!\n"); - assert(false); - return; - } - - TCLock lock (*m_Mutex); - m_BlockStatList[blockIdx].AddStat(stat); -} - -void BlockStatManager::ToFile(const CHAR *filename) { - - FileStream fstr (filename, eFileMode_Write); - - for(uint32 i = 0; i < m_BlockStatListSz; i++) { - const BlockStatList *head = &(m_BlockStatList[i]); - while(head) { - BlockStat s = head->GetStat(); - - CHAR statStr[256]; - s.ToString(statStr, 256); - - CHAR str[256]; -#ifdef _MSC_VER - _sntprintf_s(str, 256, _TRUNCATE, "%d,%s\n", i, statStr); -#else - snprintf(str, 256, "%d,%s\n", i, statStr); -#endif - - uint32 strLen = uint32(strlen(str)); - if(strLen > 255) { - str[255] = '\n'; - strLen = 256; - } - - fstr.Write((uint8 *)str, strLen); - - head = head->GetTail(); - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -// BlockStat List Implementation -// -//////////////////////////////////////////////////////////////////////////////// -static const CHAR *kNullBlockString = "NULL_BLOCK_STAT"; -static const uint32 kNullBlockStringLength = uint32(strlen(kNullBlockString)); - -BlockStatManager::BlockStatList::BlockStatList() - : m_Tail(0) - , m_Stat(kNullBlockString, 0.0) -{ } - -BlockStatManager::BlockStatList::BlockStatList(const BlockStat &stat) - : m_Tail(0) - , m_Stat(stat) -{ - assert(!"If you're copying a block stat list then you're probably not using them properly."); -} - -BlockStatManager::BlockStatList::BlockStatList(const BlockStatList &other) - : m_Tail(new BlockStatList(*other.m_Tail)) - , m_Stat(other.m_Stat) -{} - -BlockStatManager::BlockStatList::~BlockStatList() { - if(m_Counter.GetRefCount() == 0 && m_Tail) { - delete m_Tail; - } -} - -void BlockStatManager::BlockStatList::AddStat(const BlockStat &stat) { - if(strncmp(stat.m_StatName, m_Stat.m_StatName, BlockStat::kStatNameSz) == 0) { - m_Stat = stat; - } - else if(m_Tail) { - m_Tail->AddStat(stat); - } - else { - if(strncmp(m_Stat.m_StatName, kNullBlockString, kNullBlockStringLength) == 0) { - m_Stat = stat; - } - else { - m_Tail = new BlockStatList(stat); - } - } -} diff --git a/Core/src/TexComp.cpp b/Core/src/TexComp.cpp index 47f566e..ee91714 100644 --- a/Core/src/TexComp.cpp +++ b/Core/src/TexComp.cpp @@ -158,10 +158,10 @@ static double CompressImageInSerial( // !FIXME! We're assuming that we have 4x4 blocks here... CompressionJob cj (imgData, outBuf, imgWidth, imgHeight); - if(fStats && settings.pStatManager) { + if(fStats && settings.logStream) { // !FIXME! Actually use the stat manager... //(*fStats)(cj, *(settings.pStatManager)); - (*fStats)(cj, &std::cout); + (*fStats)(cj, settings.logStream); } else { (*f)(cj); @@ -293,8 +293,8 @@ static double CompressImageWithThreads( CompressionFuncWithStats fStats = ChooseFuncFromSettingsWithStats(settings); double cmpTimeTotal = 0.0; - if(fStats && settings.pStatManager) { - ThreadGroup tgrp (settings.iNumThreads, imgData, imgDataSz, fStats, *(settings.pStatManager), outBuf); + if(fStats && settings.logStream) { + ThreadGroup tgrp (settings.iNumThreads, imgData, imgDataSz, fStats, settings.logStream, outBuf); cmpTimeTotal = CompressThreadGroup(tgrp, settings); } else { @@ -316,7 +316,7 @@ static double CompressImageWithWorkerQueue( CompressionFuncWithStats fStats = ChooseFuncFromSettingsWithStats(settings); double cmpTimeTotal = 0.0; - if(fStats && settings.pStatManager) { + if(fStats && settings.logStream) { WorkerQueue wq ( settings.iNumCompressions, settings.iNumThreads, @@ -324,7 +324,7 @@ static double CompressImageWithWorkerQueue( imgData, imgDataSz, fStats, - *(settings.pStatManager), + settings.logStream, outBuf ); @@ -405,13 +405,13 @@ bool CompressImageData( uint32 numThreads = settings.iNumThreads; if(settings.format == eCompressionFormat_PVRTC && - (settings.iNumThreads > 1 || settings.pStatManager)) { + (settings.iNumThreads > 1 || settings.logStream)) { if(settings.iNumThreads > 1) { ReportError("WARNING - PVRTC compressor does not support multithreading."); numThreads = 1; } - if(settings.pStatManager) { + if(settings.logStream) { ReportError("WARNING - PVRTC compressor does not support stat collection."); } } diff --git a/Core/src/ThreadGroup.cpp b/Core/src/ThreadGroup.cpp index 7aefc57..ba2f038 100644 --- a/Core/src/ThreadGroup.cpp +++ b/Core/src/ThreadGroup.cpp @@ -58,7 +58,7 @@ CmpThread::CmpThread() , m_Height(0) , m_CmpFunc(NULL) , m_CmpFuncWithStats(NULL) - , m_StatManager(NULL) + , m_LogStream(NULL) , m_OutBuf(NULL) , m_InBuf(NULL) , m_ParentExitFlag(NULL) @@ -74,7 +74,7 @@ void CmpThread::operator()() { return; } - if(!(m_CmpFunc || (m_CmpFuncWithStats && m_StatManager))) { + if(!(m_CmpFunc || (m_CmpFuncWithStats && m_LogStream))) { fprintf(stderr, "Incorrect thread function pointer.\n"); return; } @@ -91,9 +91,7 @@ void CmpThread::operator()() { if(m_CmpFunc) (*m_CmpFunc)(cj); else - // !FIXME! Actually use the block stat manager... - // (*m_CmpFuncWithStats)(cj, *m_StatManager); - (*m_CmpFuncWithStats)(cj, &std::cout); + (*m_CmpFuncWithStats)(cj, m_LogStream); { TCLock lock(*m_ParentCounterLock); @@ -152,7 +150,7 @@ ThreadGroup::ThreadGroup( const unsigned char *inBuf, unsigned int inBufSz, CompressionFuncWithStats func, - BlockStatManager &statManager, + std::ostream *logStream, unsigned char *outBuf ) : m_StartBarrier(new TCBarrier(numThreads + 1)) @@ -186,7 +184,7 @@ ThreadGroup::ThreadGroup( m_Threads[i].m_StartBarrier = m_StartBarrier; m_Threads[i].m_ParentExitFlag = &m_ExitFlag; m_Threads[i].m_CmpFuncWithStats = func; - m_Threads[i].m_StatManager = &statManager; + m_Threads[i].m_LogStream = logStream; } } diff --git a/Core/src/ThreadGroup.h b/Core/src/ThreadGroup.h index 1bda661..d8ee656 100644 --- a/Core/src/ThreadGroup.h +++ b/Core/src/ThreadGroup.h @@ -47,7 +47,8 @@ #include "CompressionFuncs.h" #include "Thread.h" #include "StopWatch.h" -#include "BlockStats.h" + +#include struct CmpThread : public TCCallable { friend class ThreadGroup; @@ -66,7 +67,7 @@ private: CompressionFunc m_CmpFunc; CompressionFuncWithStats m_CmpFuncWithStats; - BlockStatManager *m_StatManager; + std::ostream *m_LogStream; unsigned char *m_OutBuf; const unsigned char *m_InBuf; @@ -95,7 +96,7 @@ class ThreadGroup { const unsigned char *inBuf, unsigned int inBufSz, CompressionFuncWithStats func, - BlockStatManager &statManager, + std::ostream *logStream, unsigned char *outBuf ); @@ -139,6 +140,8 @@ class ThreadGroup { EThreadState m_ThreadState; bool m_ExitFlag; + std::ostream *m_LogStream; + const unsigned int m_CompressedBlockSize; const unsigned int m_UncompressedBlockSize; }; diff --git a/Core/src/WorkerQueue.cpp b/Core/src/WorkerQueue.cpp index c3a6d65..c19c917 100644 --- a/Core/src/WorkerQueue.cpp +++ b/Core/src/WorkerQueue.cpp @@ -72,9 +72,9 @@ void WorkerThread::operator()() { CompressionFunc f = m_Parent->GetCompressionFunc(); CompressionFuncWithStats fStat = m_Parent->GetCompressionFuncWithStats(); - BlockStatManager *statManager = m_Parent->GetBlockStatManager(); + std::ostream *logStream = m_Parent->GetLogStream(); - if(!(f || (fStat && statManager))) { + if(!(f || (fStat && logStream))) { fprintf(stderr, "%s\n", "Illegal worker queue initialization -- compression func is NULL."); return; } @@ -105,9 +105,7 @@ void WorkerThread::operator()() { if(f) (*f)(cj); else - // !FIXME! Actually use stat manager... - // (*fStat)(cj, *statManager); - (*fStat)(cj, &std::cout); + (*fStat)(cj, logStream); break; } @@ -147,7 +145,7 @@ WorkerQueue::WorkerQueue( , m_NextBlock(0) , m_CompressionFunc(func) , m_CompressionFuncWithStats(NULL) - , m_BlockStatManager(NULL) + , m_LogStream(NULL) { clamp(m_NumThreads, uint32(1), uint32(kMaxNumWorkerThreads)); @@ -165,7 +163,7 @@ WorkerQueue::WorkerQueue( const uint8 *inBuf, uint32 inBufSz, CompressionFuncWithStats func, - BlockStatManager &blockStatManager, + std::ostream *logStream, uint8 *outBuf ) : m_NumCompressions(0) @@ -180,7 +178,7 @@ WorkerQueue::WorkerQueue( , m_NextBlock(0) , m_CompressionFunc(NULL) , m_CompressionFuncWithStats(func) - , m_BlockStatManager(&blockStatManager) + , m_LogStream(logStream) { clamp(m_NumThreads, uint32(1), uint32(kMaxNumWorkerThreads)); diff --git a/Core/src/WorkerQueue.h b/Core/src/WorkerQueue.h index d99f96e..855b2d4 100644 --- a/Core/src/WorkerQueue.h +++ b/Core/src/WorkerQueue.h @@ -46,7 +46,6 @@ // Forward declare... class WorkerQueue; -class BlockStatManager; // Necessary includes... #include "TexCompTypes.h" @@ -54,6 +53,8 @@ class BlockStatManager; #include "StopWatch.h" #include "CompressionFuncs.h" +#include + class WorkerThread : public TCCallable { friend class WorkerQueue; public: @@ -95,7 +96,7 @@ class WorkerQueue { const uint8 *inBuf, uint32 inBufSz, CompressionFuncWithStats func, - BlockStatManager &blockStatManager, + std::ostream *logStream, uint8 *outBuf ); @@ -138,8 +139,8 @@ class WorkerQueue { const CompressionFuncWithStats m_CompressionFuncWithStats; CompressionFuncWithStats GetCompressionFuncWithStats() const { return m_CompressionFuncWithStats; } - BlockStatManager *m_BlockStatManager; - BlockStatManager *GetBlockStatManager() const { return m_BlockStatManager; } + std::ostream *m_LogStream; + std::ostream *GetLogStream() const { return m_LogStream; } StopWatch m_StopWatch;