#ifndef __ZLibStats_h_ #define __ZLibStats_h_ #include "ThreadMonitor.h" ///////////////////////////////////////////////////////////////////// // ZLibStats // // Keep track of our compression results in the log file via // ThreadMonitor. // // This records how many bytes have gone through and what the // compression rate is. ///////////////////////////////////////////////////////////////////// class ZLibStats : private ThreadMonitor::Extra { private: static ZLibStats *instance() { static __thread ZLibStats *_instance = new ZLibStats(); return _instance; } int64_t _beforeCompression; int64_t _afterCompression; int64_t _beforeDecompression; int64_t _afterDecompression; ZLibStats() : _beforeCompression(0), _afterCompression(0), _beforeDecompression(0), _afterDecompression(0) { ThreadMonitor::find().add(this); } // ThreadMonitor::Extra virtual std::string getInfoForThreadMonitor() { TclList result; if (_beforeCompression || _afterCompression) { result<<"zlib compression"<<_beforeCompression<<_afterCompression; if (_afterCompression == 0) // Something compressed to nothing. That's possible if we don't // call flush right before doing these statistics. It's possible that // some bytes are hiding in a zlib buffer somewhere. result<<"100%"; else // 0% means no change. 99% means 99% disappeared and 1% is left. // -1% means the result is 1% *larger* than the input. This is // consistent with the way that zip and gzip normally display the // same statistics. result<<(dtoa((_beforeCompression - _afterCompression) * 100.0 / _beforeCompression, 4) + '%'); } if (_beforeDecompression || _afterDecompression) { // Use the same output format for compression and decompression. A // larger percent means better compression. If one program is // compressing data, and another program is decompressing the same data, // they should both display the same number. result<<"zlib decompression"<<_afterDecompression<<_beforeDecompression; if (_beforeDecompression == 0) result<<"100%"; else result<<(dtoa((_afterDecompression - _beforeDecompression) * 100.0 / _afterDecompression, 4) + '%'); } _beforeCompression = 0; _afterCompression = 0; _beforeDecompression = 0; _afterDecompression = 0; return result; } public: // Each time you call deflate(), call this function with the size of the // input in bytes. static void beforeCompression(int64_t bytes) { instance()->_beforeCompression += bytes; } // Each time you call deflate(), call this function with the size of the // output in bytes. static void afterCompression(int64_t bytes) { instance()->_afterCompression += bytes; } // Each time you call inflate(), call this function with the size of the // input in bytes. static void beforeDecompression(int64_t bytes) { instance()->_beforeDecompression += bytes; } // Each time you call inflate(), call this function with the size of the // output in bytes. static void afterDecompression(int64_t bytes) { instance()->_afterDecompression += bytes; } }; #endif