diff --git a/cpc/include/cpc_compressor.hpp b/cpc/include/cpc_compressor.hpp index ffcf776a..7196f0a8 100644 --- a/cpc/include/cpc_compressor.hpp +++ b/cpc/include/cpc_compressor.hpp @@ -44,6 +44,10 @@ template class cpc_compressor; template inline cpc_compressor& get_compressor(); +// function called atexit to clean up compression tables +template +void destroy_compressor(); + template class cpc_compressor { public: @@ -110,6 +114,8 @@ class cpc_compressor { cpc_compressor(); template friend cpc_compressor& get_compressor(); + friend void destroy_compressor(); + ~cpc_compressor(); void make_decoding_tables(); // call this at startup diff --git a/cpc/include/cpc_compressor_impl.hpp b/cpc/include/cpc_compressor_impl.hpp index e1e75d32..dea73e0f 100644 --- a/cpc/include/cpc_compressor_impl.hpp +++ b/cpc/include/cpc_compressor_impl.hpp @@ -22,6 +22,7 @@ #ifndef CPC_COMPRESSOR_IMPL_HPP_ #define CPC_COMPRESSOR_IMPL_HPP_ +#include #include #include @@ -35,10 +36,21 @@ namespace datasketches { // construct on first use template cpc_compressor& get_compressor() { + static bool do_init = true; static cpc_compressor* instance = new cpc_compressor(); // use new for global initialization + if (do_init) { + std::atexit(destroy_compressor); // just to clean up a little more nicely; don't worry if it fails + do_init = false; + } return *instance; } +// register to call compressor destructor at exit +template +void destroy_compressor() { + delete std::addressof(get_compressor()); +} + template cpc_compressor::cpc_compressor() { make_decoding_tables();