You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by jb...@apache.org on 2020/06/03 06:10:28 UTC

[geode-native] branch develop updated: GEODE-2484: Replaces ACE with boost::filesystem in stats. (#607)

This is an automated email from the ASF dual-hosted git repository.

jbarrett pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode-native.git


The following commit(s) were added to refs/heads/develop by this push:
     new a2a1044  GEODE-2484: Replaces ACE with boost::filesystem in stats. (#607)
a2a1044 is described below

commit a2a1044baa1d4e48d6345f724c0197bba781c3ad
Author: Jacob Barrett <jb...@pivotal.io>
AuthorDate: Tue Jun 2 23:08:25 2020 -0700

    GEODE-2484: Replaces ACE with boost::filesystem in stats. (#607)
---
 cppcache/include/geode/CacheableString.hpp         |   3 -
 cppcache/integration-test/CMakeLists.txt           |  29 +-
 cppcache/integration/test/CMakeLists.txt           |  17 +-
 cppcache/src/AdminRegion.cpp                       |   2 +-
 cppcache/src/AdminRegion.hpp                       |   3 +-
 cppcache/src/CacheImpl.cpp                         |   1 +
 cppcache/src/CacheImpl.hpp                         |   1 -
 cppcache/src/CacheTransactionManagerImpl.cpp       |   2 +-
 cppcache/src/ClientProxyMembershipID.cpp           |  11 +-
 cppcache/src/ClientProxyMembershipID.hpp           |  10 +-
 cppcache/src/ClientProxyMembershipIDFactory.cpp    |  14 +-
 cppcache/src/ClientProxyMembershipIDFactory.hpp    |   3 +-
 cppcache/src/CppCacheLibrary.cpp                   |  26 +-
 cppcache/src/CppCacheLibrary.hpp                   |  23 +-
 cppcache/src/DistributedSystemImpl.cpp             |   2 +-
 cppcache/src/Exception.cpp                         |  10 +-
 cppcache/src/ExceptionTypes.cpp                    |  52 +-
 .../src/InternalCacheTransactionManager2PCImpl.cpp |   4 +-
 cppcache/src/SystemProperties.cpp                  |   2 +-
 cppcache/src/TcrConnection.cpp                     |  10 +-
 cppcache/src/TcrDistributionManager.hpp            |   3 +-
 cppcache/src/TcrMessage.cpp                        |  11 +-
 cppcache/src/TcrMessage.hpp                        |   4 +-
 cppcache/src/ThinClientBaseDM.cpp                  |  74 ++-
 cppcache/src/ThinClientBaseDM.hpp                  |  53 +-
 .../src/ThinClientCacheDistributionManager.hpp     |   2 +-
 cppcache/src/ThinClientPoolDM.cpp                  |  25 +-
 cppcache/src/ThinClientRegion.cpp                  |  59 +--
 cppcache/src/ThinClientRegion.hpp                  |   4 +-
 cppcache/src/config.h.in                           |   3 +
 cppcache/src/statistics/HostStatSampler.cpp        | 588 +++++++--------------
 cppcache/src/statistics/HostStatSampler.hpp        | 116 ++--
 cppcache/src/statistics/PoolStatsSampler.cpp       |   1 +
 cppcache/src/statistics/StatArchiveWriter.cpp      |  59 +--
 cppcache/src/statistics/StatArchiveWriter.hpp      |  49 +-
 cppcache/src/statistics/StatisticsManager.cpp      |   5 +-
 cppcache/src/statistics/StatisticsManager.hpp      |  17 +-
 cppcache/test/CMakeLists.txt                       |   3 +-
 cppcache/test/QueueConnectionRequestTest.cpp       |  10 +-
 cppcache/test/statistics/HostStatSamplerTest.cpp   | 494 +++++++++++++++++
 40 files changed, 1013 insertions(+), 792 deletions(-)

diff --git a/cppcache/include/geode/CacheableString.hpp b/cppcache/include/geode/CacheableString.hpp
index d76f222..e5973af 100644
--- a/cppcache/include/geode/CacheableString.hpp
+++ b/cppcache/include/geode/CacheableString.hpp
@@ -25,9 +25,6 @@
 #include "internal/DataSerializablePrimitive.hpp"
 #include "internal/geode_globals.hpp"
 
-/** @file
- */
-
 namespace apache {
 namespace geode {
 namespace client {
diff --git a/cppcache/integration-test/CMakeLists.txt b/cppcache/integration-test/CMakeLists.txt
index 2fa3add..1fc9e32 100644
--- a/cppcache/integration-test/CMakeLists.txt
+++ b/cppcache/integration-test/CMakeLists.txt
@@ -85,6 +85,14 @@ endforeach()
 
 set (PORT 20000)
 
+add_custom_target(cppcache-integration-tests)
+set_target_properties(cppcache-integration-tests PROPERTIES
+  EXCLUDE_FROM_ALL TRUE
+  EXCLUDE_FROM_DEFAULT_BUILD TRUE
+  FOLDER cpp/test/integration
+)
+add_dependencies(integration-tests cppcache-integration-tests)
+
 file(GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "test*.cpp")
 foreach(FILE ${SOURCES})
   string(REGEX REPLACE "\\.cpp" "" TEST ${FILE})
@@ -152,6 +160,7 @@ foreach(FILE ${SOURCES})
   )
 
   set_tests_properties(${TEST} PROPERTIES LABELS STABLE)
+  add_dependencies(cppcache-integration-tests ${TEST})
 endforeach()
 
 configure_file(CTestCustom.cmake.in CTestCustom.cmake)
@@ -250,22 +259,14 @@ set_tests_properties(testFwPerf
    LABELS OMITTED
 )
 
-add_custom_target(run-stable-cppcache-integration-tests
-  COMMAND ctest -C $<CONFIGURATION> -L STABLE
+add_custom_target(run-cppcache-integration-tests
+  COMMAND ctest -C $<CONFIG>
   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-  USES_TERMINAL)
-add_dependencies(run-integration-tests run-stable-cppcache-integration-tests)
-set_target_properties(run-stable-cppcache-integration-tests PROPERTIES
-    EXCLUDE_FROM_ALL TRUE
-    EXCLUDE_FROM_DEFAULT_BUILD TRUE
-	FOLDER cpp/test/integration
+  USES_TERMINAL
 )
-
-add_custom_target(run-quick-cppcache-integration-tests
-  COMMAND ctest -C $<CONFIGURATION> -L QUICK -j 4
-  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-  USES_TERMINAL)
-set_target_properties(run-quick-cppcache-integration-tests PROPERTIES
+add_dependencies(run-cppcache-integration-tests cppcache-integration-tests)
+add_dependencies(run-integration-tests run-cppcache-integration-tests)
+set_target_properties(run-cppcache-integration-tests PROPERTIES
     EXCLUDE_FROM_ALL TRUE
     EXCLUDE_FROM_DEFAULT_BUILD TRUE
 	FOLDER cpp/test/integration
diff --git a/cppcache/integration/test/CMakeLists.txt b/cppcache/integration/test/CMakeLists.txt
index 442e6ce..01a67bd 100644
--- a/cppcache/integration/test/CMakeLists.txt
+++ b/cppcache/integration/test/CMakeLists.txt
@@ -101,10 +101,25 @@ add_clangformat(cpp-integration-test)
 
 enable_testing()
 include(GoogleTest)
-gtest_discover_tests(cpp-integration-test)
+gtest_discover_tests(cpp-integration-test
+  DISCOVERY_TIMEOUT 60
+)
 
 file(GLOB SSL_CERTIFICATES
         "${CMAKE_CURRENT_SOURCE_DIR}/*Keys"
         )
 
 file(INSTALL ${SSL_CERTIFICATES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
+add_custom_target(run-cpp-integration-test
+  DEPENDS $<TARGET_FILE:cpp-integration-test>
+  COMMAND ctest -C $<CONFIG>
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  USES_TERMINAL
+)
+add_dependencies(run-integration-tests run-cpp-integration-test)
+set_target_properties(run-cpp-integration-test PROPERTIES
+  EXCLUDE_FROM_ALL TRUE
+  EXCLUDE_FROM_DEFAULT_BUILD TRUE
+  FOLDER cpp/test/integration
+)
diff --git a/cppcache/src/AdminRegion.cpp b/cppcache/src/AdminRegion.cpp
index ccc6139..7c774f4 100644
--- a/cppcache/src/AdminRegion.cpp
+++ b/cppcache/src/AdminRegion.cpp
@@ -100,7 +100,7 @@ GfErrType AdminRegion::putNoThrow(const std::shared_ptr<CacheableKey>& keyPtr,
       break;
     }
     case TcrMessage::EXCEPTION: {
-      const char* exceptionMsg = reply.getException();
+      const auto& exceptionMsg = reply.getException();
       err = ThinClientRegion::handleServerException("AdminRegion::put",
                                                     exceptionMsg);
       break;
diff --git a/cppcache/src/AdminRegion.hpp b/cppcache/src/AdminRegion.hpp
index da88c00..6aa8903 100644
--- a/cppcache/src/AdminRegion.hpp
+++ b/cppcache/src/AdminRegion.hpp
@@ -53,7 +53,6 @@ class AdminRegion : public std::enable_shared_from_this<AdminRegion> {
 
   GfErrType putNoThrow(const std::shared_ptr<CacheableKey>& keyPtr,
                        const std::shared_ptr<Cacheable>& valuePtr);
-  TcrConnectionManager* getConnectionManager();
 
  public:
   AdminRegion(const AdminRegion&) = delete;
@@ -74,7 +73,7 @@ class AdminRegion : public std::enable_shared_from_this<AdminRegion> {
   void init();
   void put(const std::shared_ptr<CacheableKey>& keyPtr,
            const std::shared_ptr<Cacheable>& valuePtr);
-  friend class apache::geode::statistics::HostStatSampler;
+  TcrConnectionManager* getConnectionManager();
 };
 
 }  // namespace client
diff --git a/cppcache/src/CacheImpl.cpp b/cppcache/src/CacheImpl.cpp
index a4d4815..da11b19 100644
--- a/cppcache/src/CacheImpl.cpp
+++ b/cppcache/src/CacheImpl.cpp
@@ -24,6 +24,7 @@
 #include <geode/RegionFactory.hpp>
 #include <geode/SystemProperties.hpp>
 
+#include "AdminRegion.hpp"
 #include "AutoDelete.hpp"
 #include "CacheXmlParser.hpp"
 #include "ClientProxyMembershipID.hpp"
diff --git a/cppcache/src/CacheImpl.hpp b/cppcache/src/CacheImpl.hpp
index 98978e5..db2899c 100644
--- a/cppcache/src/CacheImpl.hpp
+++ b/cppcache/src/CacheImpl.hpp
@@ -30,7 +30,6 @@
 #include <geode/TypeRegistry.hpp>
 #include <geode/internal/geode_globals.hpp>
 
-#include "AdminRegion.hpp"
 #include "CachePerfStats.hpp"
 #include "ClientProxyMembershipIDFactory.hpp"
 #include "DistributedSystem.hpp"
diff --git a/cppcache/src/CacheTransactionManagerImpl.cpp b/cppcache/src/CacheTransactionManagerImpl.cpp
index 09a5d0b..0467cea 100644
--- a/cppcache/src/CacheTransactionManagerImpl.cpp
+++ b/cppcache/src/CacheTransactionManagerImpl.cpp
@@ -87,7 +87,7 @@ void CacheTransactionManagerImpl::commit() {
       }
       case TcrMessage::EXCEPTION: {
         //			noteCommitFailure(txState, nullptr);
-        const char* exceptionMsg = reply.getException();
+        const auto& exceptionMsg = reply.getException();
         err = ThinClientRegion::handleServerException(
             "CacheTransactionManager::commit", exceptionMsg);
         GfErrTypeThrowException("Commit Failed", err);
diff --git a/cppcache/src/ClientProxyMembershipID.cpp b/cppcache/src/ClientProxyMembershipID.cpp
index ed0fc98..8779a7d 100644
--- a/cppcache/src/ClientProxyMembershipID.cpp
+++ b/cppcache/src/ClientProxyMembershipID.cpp
@@ -49,9 +49,9 @@ ClientProxyMembershipID::ClientProxyMembershipID()
 ClientProxyMembershipID::~ClientProxyMembershipID() noexcept = default;
 
 ClientProxyMembershipID::ClientProxyMembershipID(
-    std::string dsName, std::string randString, const char* hostname,
+    std::string dsName, std::string randString, const std::string& hostname,
     const ACE_INET_Addr& address, uint32_t hostPort,
-    const char* durableClientId,
+    const std::string& durableClientId,
     const std::chrono::seconds durableClientTimeOut) {
   auto vmPID = boost::this_process::get_id();
 
@@ -100,7 +100,8 @@ void ClientProxyMembershipID::initHostAddressVector(const uint8_t* hostAddr,
 }
 
 void ClientProxyMembershipID::initObjectVars(
-    const char* hostname, uint32_t hostPort, const char* durableClientId,
+    const std::string& hostname, uint32_t hostPort,
+    const std::string& durableClientId,
     const std::chrono::seconds durableClntTimeOut, int32_t dcPort, int32_t vPID,
     int8_t vmkind, int8_t splitBrainFlag, const char* dsname,
     const char* uniqueTag, uint32_t vmViewId) {
@@ -134,8 +135,8 @@ void ClientProxyMembershipID::initObjectVars(
   m_memID.writeString(dsname);
   m_memID.writeString(uniqueTag);
 
-  if (durableClientId != nullptr &&
-      durableClntTimeOut != std::chrono::seconds::zero()) {
+  if (!(durableClientId.empty() ||
+        durableClntTimeOut == std::chrono::seconds::zero())) {
     m_memID.writeString(durableClientId);
     const auto int32ptr = CacheableInt32::create(
         static_cast<int32_t>(durableClntTimeOut.count()));
diff --git a/cppcache/src/ClientProxyMembershipID.hpp b/cppcache/src/ClientProxyMembershipID.hpp
index 201eeac..f933587 100644
--- a/cppcache/src/ClientProxyMembershipID.hpp
+++ b/cppcache/src/ClientProxyMembershipID.hpp
@@ -45,9 +45,9 @@ class ClientProxyMembershipID : public DSMemberForVersionStamp {
   const std::string& getDSMemberId() const;
 
   ClientProxyMembershipID(std::string dsName, std::string randString,
-                          const char* hostname, const ACE_INET_Addr& address,
-                          uint32_t hostPort,
-                          const char* durableClientId = nullptr,
+                          const std::string& hostname,
+                          const ACE_INET_Addr& address, uint32_t hostPort,
+                          const std::string& durableClientId,
                           const std::chrono::seconds durableClientTimeOut =
                               std::chrono::seconds::zero());
 
@@ -77,8 +77,8 @@ class ClientProxyMembershipID : public DSMemberForVersionStamp {
 
   void initHostAddressVector(const uint8_t* hostAddr, uint32_t hostAddrLen);
 
-  void initObjectVars(const char* hostname, uint32_t hostPort,
-                      const char* durableClientId,
+  void initObjectVars(const std::string& hostname, uint32_t hostPort,
+                      const std::string& durableClientId,
                       const std::chrono::seconds durableClntTimeOut,
                       int32_t dcPort, int32_t vPID, int8_t vmkind,
                       int8_t splitBrainFlag, const char* dsname,
diff --git a/cppcache/src/ClientProxyMembershipIDFactory.cpp b/cppcache/src/ClientProxyMembershipIDFactory.cpp
index ceffcf9..021ffb9 100644
--- a/cppcache/src/ClientProxyMembershipIDFactory.cpp
+++ b/cppcache/src/ClientProxyMembershipIDFactory.cpp
@@ -21,6 +21,7 @@
 #include <iterator>
 #include <random>
 
+#include <boost/asio/ip/host_name.hpp>
 #include <boost/process/environment.hpp>
 
 #include "util/Log.hpp"
@@ -31,7 +32,7 @@ namespace client {
 
 ClientProxyMembershipIDFactory::ClientProxyMembershipIDFactory(
     std::string dsName)
-    : dsName(dsName) {
+    : dsName(std::move(dsName)) {
   static const auto alphabet =
       "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
   static const auto numChars = (sizeof(alphabet) / sizeof(char)) - 2;
@@ -53,12 +54,13 @@ ClientProxyMembershipIDFactory::ClientProxyMembershipIDFactory(
 }
 
 std::unique_ptr<ClientProxyMembershipID> ClientProxyMembershipIDFactory::create(
-    const char* hostname, const ACE_INET_Addr& address, uint32_t hostPort,
-    const char* durableClientId,
+    const std::string& durableClientId,
     const std::chrono::seconds durableClntTimeOut) {
-  return std::unique_ptr<ClientProxyMembershipID>(new ClientProxyMembershipID(
-      dsName, randString, hostname, address, hostPort, durableClientId,
-      durableClntTimeOut));
+  const auto hostname = boost::asio::ip::host_name();
+  const ACE_INET_Addr address("", hostname.c_str(), "tcp");
+  return std::unique_ptr<ClientProxyMembershipID>(
+      new ClientProxyMembershipID(dsName, randString, hostname, address, 0,
+                                  durableClientId, durableClntTimeOut));
 }
 
 }  // namespace client
diff --git a/cppcache/src/ClientProxyMembershipIDFactory.hpp b/cppcache/src/ClientProxyMembershipIDFactory.hpp
index d1f00c3..21d0edb 100644
--- a/cppcache/src/ClientProxyMembershipIDFactory.hpp
+++ b/cppcache/src/ClientProxyMembershipIDFactory.hpp
@@ -33,8 +33,7 @@ class ClientProxyMembershipIDFactory {
   explicit ClientProxyMembershipIDFactory(std::string dsName);
 
   std::unique_ptr<ClientProxyMembershipID> create(
-      const char* hostname, const ACE_INET_Addr& address, uint32_t hostPort,
-      const char* durableClientId = nullptr,
+      const std::string& durableClientId = nullptr,
       const std::chrono::seconds durableClntTimeOut =
           std::chrono::seconds::zero());
 
diff --git a/cppcache/src/CppCacheLibrary.cpp b/cppcache/src/CppCacheLibrary.cpp
index 4bdd4cf..23ec0eb 100644
--- a/cppcache/src/CppCacheLibrary.cpp
+++ b/cppcache/src/CppCacheLibrary.cpp
@@ -22,7 +22,6 @@
 
 #include "Utils.hpp"
 
-// called during DLL initialization
 void initLibDllEntry(void) {
   apache::geode::client::CppCacheLibrary::initLib();
 }
@@ -35,21 +34,14 @@ namespace apache {
 namespace geode {
 namespace client {
 
-// expect this to be called from key Library entry points, or automatically
-// if we can... Probably safest to call from DistributedSystem factory method.
-// impl type Unit tests may need to call this themselves to ensure the
-// internals are prepared. fw_helper framework will handle this.
 void CppCacheLibrary::initLib(void) { ACE::init(); }
 
-// this closes ace and triggers the cleanup of the singleton CppCacheLibrary.
 void CppCacheLibrary::closeLib(void) {
-  // ACE::fini(); This should not happen..... Things might be using ace beyond
-  // the life of
-  // using geode.
+  // DO NOT CALL ACE::fini() HERE!
+  // Things might be using ace beyond the life of Geode.
 }
 
-// return the directory where the library/DLL resides
-std::string CppCacheLibrary::getProductLibDir() {
+std::string CppCacheLibrary::initProductLibDir() {
   // otherwise... get the DLL path, and work backwards from it.
   char buffer[PATH_MAX + 1];
   buffer[0] = '\0';
@@ -69,7 +61,12 @@ std::string CppCacheLibrary::getProductLibDir() {
   return std::string();
 }
 
-std::string CppCacheLibrary::getProductDir() {
+const std::string& CppCacheLibrary::getProductLibDir() {
+  static const std::string productLibDir = initProductLibDir();
+  return productLibDir;
+}
+
+std::string CppCacheLibrary::initProductDir() {
   // If the environment variable is set, use it.
   auto geodeNativeEnvironment = Utils::getEnv("GEODE_NATIVE_HOME");
   if (geodeNativeEnvironment.length() > 0) {
@@ -103,6 +100,11 @@ std::string CppCacheLibrary::getProductDir() {
   }
 }
 
+const std::string& CppCacheLibrary::getProductDir() {
+  static const std::string productDir = initProductDir();
+  return productDir;
+}
+
 }  // namespace client
 }  // namespace geode
 }  // namespace apache
diff --git a/cppcache/src/CppCacheLibrary.hpp b/cppcache/src/CppCacheLibrary.hpp
index 42eb14a..4052fa7 100644
--- a/cppcache/src/CppCacheLibrary.hpp
+++ b/cppcache/src/CppCacheLibrary.hpp
@@ -31,17 +31,28 @@ namespace client {
 // initialize GEODE runtime if it has not already been initialized.
 class APACHE_GEODE_EXPORT CppCacheLibrary {
  public:
-  // Call to this to trigger initialization.
+  /**
+   * Call to this to trigger initialization.
+   */
   static void initLib(void);
 
-  // Call to this to trigger cleanup.  initLib and closeLib calls must be in
-  // pairs.
+  /**
+   * Call to this to trigger cleanup.  initLib and closeLib calls must be in
+   * pairs.
+   */
   static void closeLib(void);
 
-  // Returns the directory where the library/DLL resides
-  static std::string getProductLibDir();
+  /**
+   * Returns the directory where the library/DLL resides
+   */
+  static const std::string& getProductLibDir();
 
-  static std::string getProductDir();
+  static const std::string& getProductDir();
+
+ private:
+  static std::string initProductLibDir();
+
+  static std::string initProductDir();
 };
 
 }  // namespace client
diff --git a/cppcache/src/DistributedSystemImpl.cpp b/cppcache/src/DistributedSystemImpl.cpp
index 2e20823..ef9ebb8 100644
--- a/cppcache/src/DistributedSystemImpl.cpp
+++ b/cppcache/src/DistributedSystemImpl.cpp
@@ -20,7 +20,7 @@
 #if defined(HAVE_PTHREAD_H)
 #include <pthread.h>
 #elif defined(_WIN32)
-#include <windows.h>
+//#include <windows.h>
 #endif
 
 #include <boost/filesystem.hpp>
diff --git a/cppcache/src/Exception.cpp b/cppcache/src/Exception.cpp
index 8f984de..78e68c4 100644
--- a/cppcache/src/Exception.cpp
+++ b/cppcache/src/Exception.cpp
@@ -51,20 +51,16 @@ std::string Exception::getStackTrace() const {
   return stack_ ? stack_->getString() : "No stack available.";
 }
 
-// class to store/clear last server exception in TSS area
-
 thread_local std::string threadLocalExceptionMessage;
 
-void setThreadLocalExceptionMessage(const char* exMsg) {
-  threadLocalExceptionMessage.clear();
-  if (exMsg != nullptr) {
-    threadLocalExceptionMessage.assign(exMsg);
-  }
+void setThreadLocalExceptionMessage(std::string exMsg) {
+  threadLocalExceptionMessage = std::move(exMsg);
 }
 
 const std::string& getThreadLocalExceptionMessage() {
   return threadLocalExceptionMessage;
 }
+
 }  // namespace client
 }  // namespace geode
 }  // namespace apache
diff --git a/cppcache/src/ExceptionTypes.cpp b/cppcache/src/ExceptionTypes.cpp
index 2f31d17..2a12e07 100644
--- a/cppcache/src/ExceptionTypes.cpp
+++ b/cppcache/src/ExceptionTypes.cpp
@@ -30,13 +30,14 @@ namespace apache {
 namespace geode {
 namespace client {
 
-void setThreadLocalExceptionMessage(const char* exMsg);
+void setThreadLocalExceptionMessage(std::string exMsg);
 const std::string& getThreadLocalExceptionMessage();
 
 [[noreturn]] void GfErrTypeThrowException(const char* str, GfErrType err) {
   std::string func;
   std::string message;
-  const auto& exMsg = getThreadLocalExceptionMessage();
+  auto exMsg = getThreadLocalExceptionMessage();
+  setThreadLocalExceptionMessage("");
   if (!exMsg.empty()) {
     func.append(str);
     func.append(": ");
@@ -45,7 +46,6 @@ const std::string& getThreadLocalExceptionMessage();
     case GF_NOTCON: {
       message.append(!exMsg.empty() ? exMsg : ": not connected to Geode");
       NotConnectedException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_MSG: {
@@ -54,101 +54,85 @@ const std::string& getThreadLocalExceptionMessage();
                          : ": message from server could not be handled");
 
       MessageException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHESERVER_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg
                                     : ": exception happened at cache server");
       CacheServerException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_NOTOWN: {
       message.append(!exMsg.empty() ? exMsg : ": not own the lock");
       NotOwnerException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_REGION_NOT_FOUND: {
       message.append(!exMsg.empty() ? exMsg : ": region not found on server");
       CacheServerException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_REGION_NOT_GLOBAL: {
       message.append(!exMsg.empty() ? exMsg : ": region not global");
       IllegalStateException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": illegal argument");
       IllegalArgumentException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_ILLEGAL_STATE_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": illegal State");
       IllegalStateException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_WRITER_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg
                                     : ": exception on server during write");
       CacheWriterException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHEWRITER_ERROR: {
       message.append(!exMsg.empty() ? exMsg : ": exception in CacheWriter");
       CacheWriterException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_LOADER_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": exception in CacheLoader");
       CacheLoaderException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_LISTENER_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": exception in CacheListener");
       CacheListenerException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_REGION_INVALID: {
       message.append(!exMsg.empty() ? exMsg : ": region not valid");
       RegionDestroyedException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_PROXY: {
       message.append(!exMsg.empty() ? exMsg : ": error in Cache proxy");
       CacheProxyException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_IOERR: {
       message.append(!exMsg.empty() ? exMsg
                                     : ": Input/Output error in operation");
       GeodeIOException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_ENOENT: {
       message.append(!exMsg.empty() ? exMsg : ": entity does not exist");
       NoSystemException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_REGION_KEYS_NOT_STRINGS: {
       message.append(
           !exMsg.empty() ? exMsg : ": region entries do not support C access");
       IllegalArgumentException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_REGION_ENTRY_NOT_BYTES: {
@@ -156,19 +140,16 @@ const std::string& getThreadLocalExceptionMessage();
                          ? exMsg
                          : ": existing non-null values was not a byte array");
       IllegalArgumentException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_TIMEOUT_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": timed out");
       TimeoutException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_TIMEOUT: {
       message.append(!exMsg.empty() ? exMsg : ": timed out");
       TimeoutException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CLIENT_WAIT_TIMEOUT: {
@@ -176,62 +157,52 @@ const std::string& getThreadLocalExceptionMessage();
                          ? exMsg
                          : ": timed out, possibly bucket is not available.");
       TimeoutException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_ENOMEM: {
       message.append(!exMsg.empty() ? exMsg : ": Out of memory");
       OutOfMemoryException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_ERANGE: {
       message.append(!exMsg.empty() ? exMsg : ": Buffer Size Exceeded");
       BufferSizeExceededException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_LEASE_EXPIRED_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": lock Lease Expired On you");
       LeaseExpiredException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_REGION_EXISTS_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": Named Region Exists");
       RegionExistsException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_ENTRY_NOT_FOUND: {
       message.append(!exMsg.empty() ? exMsg : ": Entry not found");
       EntryNotFoundException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_ENTRY_EXISTS: {
       message.append(!exMsg.empty() ? exMsg
                                     : ": Entry already exists in the region");
       EntryExistsException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_ENTRY_DESTROYED_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": Entry has been destroyed");
       EntryDestroyedException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_REGION_DESTROYED_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": Named Region Destroyed");
       RegionDestroyedException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_CLOSED_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": Cache has been closed");
       CacheClosedException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_STATISTICS_DISABLED_EXCEPTION: {
@@ -239,50 +210,42 @@ const std::string& getThreadLocalExceptionMessage();
                          ? exMsg
                          : ": Statistics have been disabled for the region");
       StatisticsDisabledException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_CONCURRENT_MODIFICATION_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg
                                     : ": Concurrent modification in the cache");
       ConcurrentModificationException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_NOT_AUTHORIZED_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": unauthorized operation");
       NotAuthorizedException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_AUTHENTICATION_FAILED_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": authentication failed");
       AuthenticationFailedException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_AUTHENTICATION_REQUIRED_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": no authentication provided");
       AuthenticationRequiredException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_DUPLICATE_DURABLE_CLIENT: {
       message.append(!exMsg.empty() ? exMsg : ": Duplicate Durable Client Id");
       DuplicateDurableClientException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_REMOTE_QUERY_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": Query failed");
       QueryException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_CACHE_LOCATOR_EXCEPTION: {
       NoAvailableLocatorsException cause(
           func + (!exMsg.empty() ? exMsg : ": No locators available"));
-      setThreadLocalExceptionMessage(nullptr);
       try {
         throw cause;
       } catch (...) {
@@ -294,38 +257,32 @@ const std::string& getThreadLocalExceptionMessage();
     case GF_ALL_CONNECTIONS_IN_USE_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": All connections are in use");
       AllConnectionsInUseException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_FUNCTION_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": Function execution failed");
       FunctionExecutionException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_DISKFULL: {
       message.append(!exMsg.empty() ? exMsg : ": Disk full");
       DiskFailureException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_ROLLBACK_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": Transaction rolled back");
       RollbackException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_COMMIT_CONFLICT_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": Commit conflict exception");
       CommitConflictException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_TRANSACTION_DATA_REBALANCED_EXCEPTION: {
       message.append(
           !exMsg.empty() ? exMsg : ": Transaction data rebalanced exception");
       TransactionDataRebalancedException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_TRANSACTION_DATA_NODE_HAS_DEPARTED_EXCEPTION: {
@@ -333,13 +290,11 @@ const std::string& getThreadLocalExceptionMessage();
                          ? exMsg
                          : ": Transaction data node has departed exception");
       TransactionDataNodeHasDepartedException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     case GF_PUTALL_PARTIAL_RESULT_EXCEPTION: {
       message.append(!exMsg.empty() ? exMsg : ": PutAll Partial exception");
       PutAllPartialResultException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
     default: {
@@ -351,7 +306,6 @@ const std::string& getThreadLocalExceptionMessage();
         message.append(exMsg);
       }
       UnknownException ex(message);
-      setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
   }
diff --git a/cppcache/src/InternalCacheTransactionManager2PCImpl.cpp b/cppcache/src/InternalCacheTransactionManager2PCImpl.cpp
index facc842..0df0512 100644
--- a/cppcache/src/InternalCacheTransactionManager2PCImpl.cpp
+++ b/cppcache/src/InternalCacheTransactionManager2PCImpl.cpp
@@ -78,7 +78,7 @@ void InternalCacheTransactionManager2PCImpl::prepare() {
           break;
         case TcrMessage::EXCEPTION: {
           TXCleaner txCleaner(this);
-          const char* exceptionMsg = replyCommitBefore.getException();
+          const auto& exceptionMsg = replyCommitBefore.getException();
           err = ThinClientRegion::handleServerException(
               "CacheTransactionManager::prepare", exceptionMsg);
           GfErrTypeThrowException("Commit Failed in prepare", err);
@@ -182,7 +182,7 @@ void InternalCacheTransactionManager2PCImpl::afterCompletion(int32_t status) {
           break;
         }
         case TcrMessage::EXCEPTION: {
-          const char* exceptionMsg = replyCommitAfter.getException();
+          const auto& exceptionMsg = replyCommitAfter.getException();
           err = ThinClientRegion::handleServerException(
               "CacheTransactionManager::afterCompletion", exceptionMsg);
           GfErrTypeThrowException("2PC Commit Failed", err);
diff --git a/cppcache/src/SystemProperties.cpp b/cppcache/src/SystemProperties.cpp
index 3071634..a3184c9 100644
--- a/cppcache/src/SystemProperties.cpp
+++ b/cppcache/src/SystemProperties.cpp
@@ -88,7 +88,7 @@ constexpr auto DefaultConnectWaitTimeout = std::chrono::seconds::zero();
 constexpr auto DefaultBucketWaitTimeout = std::chrono::seconds::zero();
 
 constexpr auto DefaultSamplingInterval = std::chrono::seconds(1);
-constexpr bool DefaultSamplingEnabled = false;
+constexpr auto DefaultSamplingEnabled = false;
 
 const char DefaultStatArchive[] = "statArchive.gfs";
 const char DefaultLogFilename[] = "";  // stdout...
diff --git a/cppcache/src/TcrConnection.cpp b/cppcache/src/TcrConnection.cpp
index a31871b..d841631 100644
--- a/cppcache/src/TcrConnection.cpp
+++ b/cppcache/src/TcrConnection.cpp
@@ -163,21 +163,13 @@ bool TcrConnection::initTcrConnection(
         reinterpret_cast<const uint8_t*>(dsMemberId.c_str()),
         static_cast<int32_t>(dsMemberId.size()));
   } else {
-    ACE_TCHAR hostName[256];
-    ACE_OS::hostname(hostName, sizeof(hostName) - 1);
-
-    ACE_INET_Addr driver(hostName);
-
-    uint16_t hostPort = 0;
-
     // Add 3 durable Subcription properties to ClientProxyMembershipID
-
     auto&& durableId = sysProp.durableClientId();
     auto&& durableTimeOut = sysProp.durableTimeout();
 
     // Write ClientProxyMembershipID serialized object.
     auto memId = cacheImpl->getClientProxyMembershipIDFactory().create(
-        hostName, driver, hostPort, durableId.c_str(), durableTimeOut);
+        durableId.c_str(), durableTimeOut);
     const auto& dsMemberId = memId->getDSMemberId();
     handShakeMsg.writeBytes(
         reinterpret_cast<const uint8_t*>(dsMemberId.c_str()),
diff --git a/cppcache/src/TcrDistributionManager.hpp b/cppcache/src/TcrDistributionManager.hpp
index 1d3930a..2a7907d 100644
--- a/cppcache/src/TcrDistributionManager.hpp
+++ b/cppcache/src/TcrDistributionManager.hpp
@@ -32,8 +32,7 @@ class ThinClientRegion;
 /**
  * @brief Distribute data between caches
  */
-class APACHE_GEODE_EXPORT TcrDistributionManager
-    : public ThinClientDistributionManager {
+class TcrDistributionManager : public ThinClientDistributionManager {
  public:
   TcrDistributionManager(ThinClientRegion* region,
                          TcrConnectionManager& connManager);
diff --git a/cppcache/src/TcrMessage.cpp b/cppcache/src/TcrMessage.cpp
index aa8361d..9f1c80b 100644
--- a/cppcache/src/TcrMessage.cpp
+++ b/cppcache/src/TcrMessage.cpp
@@ -79,9 +79,8 @@ inline void writeInt(uint8_t* buffer, uint32_t value) {
 }
 }  // namespace
 
-extern void setThreadLocalExceptionMessage(const char*);
+extern void setThreadLocalExceptionMessage(std::string);
 
-// AtomicInc TcrMessage::m_transactionId = 0;
 uint8_t* TcrMessage::m_keepAlive = nullptr;
 const int TcrMessage::m_flag_empty = 0x01;
 const int TcrMessage::m_flag_concurrency_checks = 0x02;
@@ -144,7 +143,7 @@ TcrMessage::TcrMessage()
       m_tombstoneVersions(),
       m_tombstoneKeys(),
       m_versionObjPartListptr(),
-      exceptionMessage(),
+      m_exceptionMessage(),
       m_regionName("INVALID_REGION_NAME"),
       m_regex(),
       m_bucketServerLocations(),
@@ -215,9 +214,9 @@ bool TcrMessage::forTransaction() const { return m_txId != -1; }
 
 bool TcrMessage::getBoolValue() const { return m_boolValue; }
 
-const char* TcrMessage::getException() {
-  exceptionMessage = Utils::nullSafeToString(m_value);
-  return exceptionMessage.c_str();
+const std::string& TcrMessage::getException() {
+  m_exceptionMessage = Utils::nullSafeToString(m_value);
+  return m_exceptionMessage;
 }
 
 bool TcrMessage::isDurable() const { return m_isDurable; }
diff --git a/cppcache/src/TcrMessage.hpp b/cppcache/src/TcrMessage.hpp
index 007dbd1..9230600 100644
--- a/cppcache/src/TcrMessage.hpp
+++ b/cppcache/src/TcrMessage.hpp
@@ -243,7 +243,7 @@ class TcrMessage {
 
   const std::map<std::string, int>* getCqs() const;
   bool getBoolValue() const;
-  const char* getException();
+  const std::string& getException();
 
   const char* getMsgData() const;
   const char* getMsgHeader() const;
@@ -434,7 +434,7 @@ class TcrMessage {
   std::shared_ptr<CacheableHashMap> m_tombstoneVersions;
   std::shared_ptr<CacheableHashSet> m_tombstoneKeys;
   std::shared_ptr<VersionedCacheableObjectPartList> m_versionObjPartListptr;
-  std::string exceptionMessage;
+  std::string m_exceptionMessage;
   std::string m_regionName;
   std::string m_regex;
   std::vector<std::shared_ptr<BucketServerLocation>> m_bucketServerLocations;
diff --git a/cppcache/src/ThinClientBaseDM.cpp b/cppcache/src/ThinClientBaseDM.cpp
index 82bcea0..4acc0d2 100644
--- a/cppcache/src/ThinClientBaseDM.cpp
+++ b/cppcache/src/ThinClientBaseDM.cpp
@@ -127,15 +127,15 @@ GfErrType ThinClientBaseDM::handleEPError(TcrEndpoint* ep,
                                           GfErrType error) {
   if (error == GF_NOERR) {
     if (reply.getMessageType() == TcrMessage::EXCEPTION) {
-      const char* exceptStr = reply.getException();
-      if (exceptStr != nullptr) {
+      const auto& exceptStr = reply.getException();
+      if (!exceptStr.empty()) {
         bool markServerDead = unrecoverableServerError(exceptStr);
         bool doFailover = (markServerDead || nonFatalServerError(exceptStr));
         if (doFailover) {
           LOGFINE(
               "ThinClientDistributionManager::sendRequestToEP: retrying for "
-              "server [%s] exception: %s",
-              ep->name().c_str(), exceptStr);
+              "server [" +
+              ep->name() + "] exception: " + exceptStr);
           error = GF_NOTCON;
           if (markServerDead) {
             ep->setConnectionStatus(false);
@@ -168,13 +168,12 @@ GfErrType ThinClientBaseDM::sendRequestToEndPoint(const TcrMessage& request,
  * the server so that need not be marked as dead.
  * This method is for exceptions when server should be marked as dead.
  */
-bool ThinClientBaseDM::unrecoverableServerError(const char* exceptStr) {
-  return (
-      (strstr(exceptStr, "org.apache.geode.cache.CacheClosedException") !=
-       nullptr) ||
-      (strstr(exceptStr, "org.apache.geode.distributed.ShutdownException") !=
-       nullptr) ||
-      (strstr(exceptStr, "java.lang.OutOfMemoryError") != nullptr));
+bool ThinClientBaseDM::unrecoverableServerError(const std::string& exceptStr) {
+  return ((exceptStr.find("org.apache.geode.cache.CacheClosedException") !=
+           std::string::npos) ||
+          (exceptStr.find("org.apache.geode.distributed.ShutdownException") !=
+           std::string::npos) ||
+          (exceptStr.find("java.lang.OutOfMemoryError") != std::string::npos));
 }
 
 /**
@@ -184,12 +183,13 @@ bool ThinClientBaseDM::unrecoverableServerError(const char* exceptStr) {
  * the server so that need not be marked as dead.
  * This method is for exceptions when server should *not* be marked as dead.
  */
-bool ThinClientBaseDM::nonFatalServerError(const char* exceptStr) {
-  return ((strstr(exceptStr, "org.apache.geode.distributed.TimeoutException") !=
-           nullptr) ||
-          (strstr(exceptStr, "org.apache.geode.ThreadInterruptedException") !=
-           nullptr) ||
-          (strstr(exceptStr, "java.lang.IllegalStateException") != nullptr));
+bool ThinClientBaseDM::nonFatalServerError(const std::string& exceptStr) {
+  return (
+      (exceptStr.find("org.apache.geode.distributed.TimeoutException") !=
+       std::string::npos) ||
+      (exceptStr.find("org.apache.geode.ThreadInterruptedException") !=
+       std::string::npos) ||
+      (exceptStr.find("java.lang.IllegalStateException") != std::string::npos));
 }
 
 void ThinClientBaseDM::failover() {}
@@ -338,6 +338,46 @@ std::recursive_mutex& ThinClientBaseDM::getRedundancyLock() {
   return m_connManager.getRedundancyLock();
 }
 
+bool ThinClientBaseDM::isNotAuthorizedException(
+    const std::string& exceptionMsg) {
+  if (exceptionMsg.find("org.apache.geode.security.NotAuthorizedException") !=
+      std::string::npos) {
+    LOGDEBUG("isNotAuthorizedException() An exception (" + exceptionMsg +
+             ") happened at remote server.");
+    return true;
+  }
+  return false;
+}
+
+bool ThinClientBaseDM::isPutAllPartialResultException(
+    const std::string& exceptionMsg) {
+  if (exceptionMsg.find(
+          "org.apache.geode.internal.cache.PutAllPartialResultException") !=
+      std::string::npos) {
+    LOGDEBUG("isNotAuthorizedException() An exception (" + exceptionMsg +
+             ") happened at remote server.");
+    return true;
+  }
+  return false;
+}
+
+bool ThinClientBaseDM::isAuthRequireException(const std::string& exceptionMsg) {
+  if (exceptionMsg.find(
+          "org.apache.geode.security.AuthenticationRequiredException") !=
+      std::string::npos) {
+    LOGDEBUG("isAuthRequireExcep() An exception (" + exceptionMsg +
+             ") happened at remote server.");
+    return true;
+  }
+  return false;
+}
+
+void ThinClientBaseDM::setDeltaEnabledOnServer(bool isDeltaEnabledOnServer) {
+  s_isDeltaEnabledOnServer = isDeltaEnabledOnServer;
+  LOGFINE("Delta enabled on server: %s",
+          s_isDeltaEnabledOnServer ? "true" : "false");
+}
+
 }  // namespace client
 }  // namespace geode
 }  // namespace apache
diff --git a/cppcache/src/ThinClientBaseDM.hpp b/cppcache/src/ThinClientBaseDM.hpp
index e9d00a7..2920876 100644
--- a/cppcache/src/ThinClientBaseDM.hpp
+++ b/cppcache/src/ThinClientBaseDM.hpp
@@ -25,6 +25,7 @@
 
 #include <geode/internal/geode_globals.hpp>
 
+#include "ErrType.hpp"
 #include "Queue.hpp"
 #include "Task.hpp"
 #include "util/Log.hpp"
@@ -121,56 +122,18 @@ class ThinClientBaseDM {
 
   static bool isDeltaEnabledOnServer() { return s_isDeltaEnabledOnServer; }
 
-  inline static void setDeltaEnabledOnServer(bool isDeltaEnabledOnServer) {
-    s_isDeltaEnabledOnServer = isDeltaEnabledOnServer;
-    LOGFINE("Delta enabled on server: %s",
-            s_isDeltaEnabledOnServer ? "true" : "false");
-  }
+  static void setDeltaEnabledOnServer(bool isDeltaEnabledOnServer);
+
   TcrConnectionManager& getConnectionManager() const { return m_connManager; }
 
   virtual size_t getNumberOfEndPoints() const { return 0; }
 
-  bool isNotAuthorizedException(const char* exceptionMsg) {
-    if (exceptionMsg != nullptr &&
-        strstr(exceptionMsg,
-               "org.apache.geode.security.NotAuthorizedException") != nullptr) {
-      LOGDEBUG(
-          "isNotAuthorizedException() An exception (%s) happened at remote "
-          "server.",
-          exceptionMsg);
-      return true;
-    }
-    return false;
-  }
+  bool isNotAuthorizedException(const std::string& exceptionMsg);
 
-  bool isPutAllPartialResultException(const char* exceptionMsg) {
-    if (exceptionMsg != nullptr &&
-        strstr(
-            exceptionMsg,
-            "org.apache.geode.internal.cache.PutAllPartialResultException") !=
-            nullptr) {
-      LOGDEBUG(
-          "isNotAuthorizedException() An exception (%s) happened at remote "
-          "server.",
-          exceptionMsg);
-      return true;
-    }
-    return false;
-  }
+  bool isPutAllPartialResultException(const std::string& exceptionMsg);
 
  protected:
-  bool isAuthRequireException(const char* exceptionMsg) {
-    if (exceptionMsg != nullptr &&
-        strstr(exceptionMsg,
-               "org.apache.geode.security.AuthenticationRequiredException") !=
-            nullptr) {
-      LOGDEBUG(
-          "isAuthRequireExcep() An exception (%s) happened at remote server.",
-          exceptionMsg);
-      return true;
-    }
-    return false;
-  }
+  bool isAuthRequireException(const std::string& exceptionMsg);
 
   ThinClientRegion* m_region;
 
@@ -185,8 +148,8 @@ class ThinClientBaseDM {
   ThinClientBaseDM& operator=(const ThinClientBaseDM&);
 
  protected:
-  static bool unrecoverableServerError(const char* exceptStr);
-  static bool nonFatalServerError(const char* exceptStr);
+  static bool unrecoverableServerError(const std::string& exceptStr);
+  static bool nonFatalServerError(const std::string& exceptStr);
   static GfErrType handleEPError(TcrEndpoint* ep, TcrMessageReply& reply,
                                  GfErrType error);
 
diff --git a/cppcache/src/ThinClientCacheDistributionManager.hpp b/cppcache/src/ThinClientCacheDistributionManager.hpp
index 24d8d81..29898e8 100644
--- a/cppcache/src/ThinClientCacheDistributionManager.hpp
+++ b/cppcache/src/ThinClientCacheDistributionManager.hpp
@@ -35,7 +35,7 @@ namespace client {
 class TcrMessage;
 class TcrConnection;
 
-class APACHE_GEODE_EXPORT ThinClientCacheDistributionManager
+class ThinClientCacheDistributionManager
     : public ThinClientDistributionManager {
  public:
   explicit ThinClientCacheDistributionManager(
diff --git a/cppcache/src/ThinClientPoolDM.cpp b/cppcache/src/ThinClientPoolDM.cpp
index a5b2256..64deebb 100644
--- a/cppcache/src/ThinClientPoolDM.cpp
+++ b/cppcache/src/ThinClientPoolDM.cpp
@@ -169,12 +169,7 @@ ThinClientPoolDM::ThinClientPoolDM(const char* name,
   // to set security flag at pool level
   m_isSecurityOn = cacheImpl->getAuthInitialize() != nullptr;
 
-  ACE_TCHAR hostName[256];
-  ACE_OS::hostname(hostName, sizeof(hostName) - 1);
-  ACE_INET_Addr driver(hostName);
-
-  uint16_t hostPort = 0;
-  auto&& durableId = sysProp.durableClientId();
+  const auto& durableId = sysProp.durableClientId();
 
   std::string clientDurableId = durableId;
   if (!m_poolName.empty()) {
@@ -183,7 +178,7 @@ ThinClientPoolDM::ThinClientPoolDM(const char* name,
 
   const auto durableTimeOut = sysProp.durableTimeout();
   m_memId = cacheImpl->getClientProxyMembershipIDFactory().create(
-      hostName, driver, hostPort, clientDurableId.c_str(), durableTimeOut);
+      clientDurableId.c_str(), durableTimeOut);
 
   if (m_attrs->m_initLocList.empty() && m_attrs->m_initServList.empty()) {
     std::string msg = "No locators or servers provided for pool named ";
@@ -898,7 +893,7 @@ int32_t ThinClientPoolDM::GetPDXIdForType(
   throwExceptionIfError("Operation Failed", sendSyncRequest(request, reply));
 
   if (reply.getMessageType() == TcrMessage::EXCEPTION) {
-    LOGDEBUG("ThinClientPoolDM::GetPDXTypeById: Exception = %s ",
+    LOGDEBUG("ThinClientPoolDM::GetPDXTypeById: Exception = " +
              reply.getException());
     throw IllegalStateException("Failed to register PdxSerializable Type");
   }
@@ -934,7 +929,7 @@ void ThinClientPoolDM::AddPdxType(std::shared_ptr<Serializable> pdxType,
   throwExceptionIfError("Operation Failed", sendSyncRequest(request, reply));
 
   if (reply.getMessageType() == TcrMessage::EXCEPTION) {
-    LOGDEBUG("ThinClientPoolDM::GetPDXTypeById: Exception = %s ",
+    LOGDEBUG("ThinClientPoolDM::GetPDXTypeById: Exception = " +
              reply.getException());
     throw IllegalStateException("Failed to register PdxSerializable Type");
   }
@@ -951,7 +946,7 @@ std::shared_ptr<Serializable> ThinClientPoolDM::GetPDXTypeById(int32_t typeId) {
   throwExceptionIfError("Operation Failed", sendSyncRequest(request, reply));
 
   if (reply.getMessageType() == TcrMessage::EXCEPTION) {
-    LOGDEBUG("ThinClientPoolDM::GetPDXTypeById: Exception = %s ",
+    LOGDEBUG("ThinClientPoolDM::GetPDXTypeById: Exception = " +
              reply.getException());
     throw IllegalStateException("Failed to understand PdxSerializable Type");
   }
@@ -971,7 +966,7 @@ int32_t ThinClientPoolDM::GetEnumValue(std::shared_ptr<Serializable> enumInfo) {
   throwExceptionIfError("Operation Failed", sendSyncRequest(request, reply));
 
   if (reply.getMessageType() == TcrMessage::EXCEPTION) {
-    LOGDEBUG("ThinClientPoolDM::GetEnumValue: Exception = %s ",
+    LOGDEBUG("ThinClientPoolDM::GetEnumValue: Exception = " +
              reply.getException());
     throw IllegalStateException("Failed to register Pdx enum Type");
   }
@@ -1006,8 +1001,7 @@ std::shared_ptr<Serializable> ThinClientPoolDM::GetEnum(int32_t val) {
   throwExceptionIfError("Operation Failed", sendSyncRequest(request, reply));
 
   if (reply.getMessageType() == TcrMessage::EXCEPTION) {
-    LOGDEBUG("ThinClientPoolDM::GetEnum: Exception = %s ",
-             reply.getException());
+    LOGDEBUG("ThinClientPoolDM::GetEnum: Exception = " + reply.getException());
     throw IllegalStateException("Failed to understand enum Type");
   }
 
@@ -1027,8 +1021,7 @@ void ThinClientPoolDM::AddEnum(std::shared_ptr<Serializable> enumInfo,
   throwExceptionIfError("Operation Failed", sendSyncRequest(request, reply));
 
   if (reply.getMessageType() == TcrMessage::EXCEPTION) {
-    LOGDEBUG("ThinClientPoolDM::AddEnum: Exception = %s ",
-             reply.getException());
+    LOGDEBUG("ThinClientPoolDM::AddEnum: Exception = " + reply.getException());
     throw IllegalStateException("Failed to register enum Type");
   }
 }
@@ -2245,7 +2238,7 @@ GfErrType ThinClientPoolDM::doFailover(TcrConnection* conn) {
         break;
       }
       case TcrMessage::EXCEPTION: {
-        const char* exceptionMsg = reply.getException();
+        const auto& exceptionMsg = reply.getException();
         err = ThinClientRegion::handleServerException(
             "CacheTransactionManager::failover", exceptionMsg);
         break;
diff --git a/cppcache/src/ThinClientRegion.cpp b/cppcache/src/ThinClientRegion.cpp
index afefb45..64c7ab0 100644
--- a/cppcache/src/ThinClientRegion.cpp
+++ b/cppcache/src/ThinClientRegion.cpp
@@ -52,7 +52,7 @@ namespace client {
 static const std::regex PREDICATE_IS_FULL_QUERY_REGEX(
     "^\\s*(?:select|import)\\b", std::regex::icase);
 
-void setThreadLocalExceptionMessage(const char* exMsg);
+void setThreadLocalExceptionMessage(std::string exMsg);
 
 class PutAllWork : public PooledWork<GfErrType> {
   ThinClientPoolDM* m_poolDM;
@@ -184,7 +184,7 @@ class PutAllWork : public PooledWork<GfErrType> {
           LOGDEBUG("received PutAllPartialResultException");
           err = GF_PUTALL_PARTIAL_RESULT_EXCEPTION;
         } else {
-          LOGDEBUG("received unknown exception:%s", m_reply->getException());
+          LOGDEBUG("received unknown exception:" + m_reply->getException());
           err = GF_PUTALL_PARTIAL_RESULT_EXCEPTION;
           // TODO should assign a new err code
         }
@@ -322,7 +322,7 @@ class RemoveAllWork : public PooledWork<GfErrType> {
           LOGDEBUG("received PutAllPartialResultException");
           err = GF_PUTALL_PARTIAL_RESULT_EXCEPTION;
         } else {
-          LOGDEBUG("received unknown exception:%s", m_reply->getException());
+          LOGDEBUG("received unknown exception:" + m_reply->getException());
           err = GF_PUTALL_PARTIAL_RESULT_EXCEPTION;
           // TODO should assign a new err code
         }
@@ -2727,53 +2727,50 @@ GfErrType ThinClientRegion::clientNotificationHandler(TcrMessage& msg) {
   return err;
 }
 
-GfErrType ThinClientRegion::handleServerException(const char* func,
-                                                  const char* exceptionMsg) {
+GfErrType ThinClientRegion::handleServerException(
+    const std::string& func, const std::string& exceptionMsg) {
   GfErrType error = GF_NOERR;
   setThreadLocalExceptionMessage(exceptionMsg);
-  if (strstr(exceptionMsg,
-             "org.apache.geode.security.NotAuthorizedException") != nullptr) {
+  if (exceptionMsg.find("org.apache.geode.security.NotAuthorizedException") !=
+      std::string::npos) {
     error = GF_NOT_AUTHORIZED_EXCEPTION;
-  } else if (strstr(exceptionMsg,
-                    "org.apache.geode.cache.CacheWriterException") != nullptr) {
+  } else if (exceptionMsg.find("org.apache.geode.cache.CacheWriterException") !=
+             std::string::npos) {
     error = GF_CACHE_WRITER_EXCEPTION;
-  } else if (strstr(
-                 exceptionMsg,
+  } else if (exceptionMsg.find(
                  "org.apache.geode.security.AuthenticationFailedException") !=
-             nullptr) {
+             std::string::npos) {
     error = GF_AUTHENTICATION_FAILED_EXCEPTION;
-  } else if (strstr(exceptionMsg,
-                    "org.apache.geode.internal.cache.execute."
-                    "InternalFunctionInvocationTargetException") != nullptr) {
+  } else if (exceptionMsg.find("org.apache.geode.internal.cache.execute."
+                               "InternalFunctionInvocationTargetException") !=
+             std::string::npos) {
     error = GF_FUNCTION_EXCEPTION;
-  } else if (strstr(exceptionMsg,
-                    "org.apache.geode.cache.CommitConflictException") !=
-             nullptr) {
+  } else if (exceptionMsg.find(
+                 "org.apache.geode.cache.CommitConflictException") !=
+             std::string::npos) {
     error = GF_COMMIT_CONFLICT_EXCEPTION;
-  } else if (strstr(exceptionMsg,
-                    "org.apache.geode.cache."
-                    "TransactionDataNodeHasDepartedException") != nullptr) {
+  } else if (exceptionMsg.find("org.apache.geode.cache."
+                               "TransactionDataNodeHasDepartedException") !=
+             std::string::npos) {
     error = GF_TRANSACTION_DATA_NODE_HAS_DEPARTED_EXCEPTION;
-  } else if (strstr(
-                 exceptionMsg,
+  } else if (exceptionMsg.find(
                  "org.apache.geode.cache.TransactionDataRebalancedException") !=
-             nullptr) {
+             std::string::npos) {
     error = GF_TRANSACTION_DATA_REBALANCED_EXCEPTION;
-  } else if (strstr(
-                 exceptionMsg,
+  } else if (exceptionMsg.find(
                  "org.apache.geode.security.AuthenticationRequiredException") !=
-             nullptr) {
+             std::string::npos) {
     error = GF_AUTHENTICATION_REQUIRED_EXCEPTION;
   } else {
     error = GF_CACHESERVER_EXCEPTION;
   }
 
   if (error != GF_AUTHENTICATION_REQUIRED_EXCEPTION) {
-    LOGERROR("%s: An exception (%s) happened at remote server.", func,
-             exceptionMsg);
+    LOGERROR(func + ": An exception (" + exceptionMsg +
+             ") happened at remote server.");
   } else {
-    LOGFINER("%s: An exception (%s) happened at remote server.", func,
-             exceptionMsg);
+    LOGFINER(func + ": An exception (" + exceptionMsg +
+             ") happened at remote server.");
   }
   return error;
 }
diff --git a/cppcache/src/ThinClientRegion.hpp b/cppcache/src/ThinClientRegion.hpp
index efc8adf..f62bee9 100644
--- a/cppcache/src/ThinClientRegion.hpp
+++ b/cppcache/src/ThinClientRegion.hpp
@@ -135,8 +135,8 @@ class APACHE_GEODE_EXPORT ThinClientRegion : public LocalRegion {
 
   void receiveNotification(TcrMessage* msg);
 
-  static GfErrType handleServerException(const char* func,
-                                         const char* exceptionMsg);
+  static GfErrType handleServerException(const std::string& func,
+                                         const std::string& exceptionMsg);
 
   void acquireGlobals(bool failover) override;
   void releaseGlobals(bool failover) override;
diff --git a/cppcache/src/config.h.in b/cppcache/src/config.h.in
index e511793..3fb636a 100644
--- a/cppcache/src/config.h.in
+++ b/cppcache/src/config.h.in
@@ -45,6 +45,9 @@
 #define PRODUCT_LIB_NAME "@PRODUCT_LIB_NAME@"
 #define PRODUCT_DLL_NAME "@PRODUCT_DLL_NAME@"
 
+#define GEODE_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@"
+#define GEODE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
+
 // TODO relace with CMake checks
 #define WITH_ACE_Select_Reactor 1
 
diff --git a/cppcache/src/statistics/HostStatSampler.cpp b/cppcache/src/statistics/HostStatSampler.cpp
index d180cb5..b77b76f 100644
--- a/cppcache/src/statistics/HostStatSampler.cpp
+++ b/cppcache/src/statistics/HostStatSampler.cpp
@@ -17,23 +17,27 @@
 
 #include "HostStatSampler.hpp"
 
+#include <algorithm>
 #include <chrono>
+#include <map>
+#include <regex>
 #include <thread>
 #include <utility>
 #include <vector>
 
-#include <ace/ACE.h>
-#include <ace/Dirent_Selector.h>
-#include <ace/INET_Addr.h>
-#include <ace/OS_NS_sys_stat.h>
-#include <ace/OS_NS_sys_utsname.h>
+#include <boost/filesystem.hpp>
 #include <boost/process/environment.hpp>
+#include <boost/range/adaptors.hpp>
 
+#include <geode/CacheFactory.hpp>
+#include <geode/ExceptionTypes.hpp>
 #include <geode/internal/geode_globals.hpp>
 
+#include "../AdminRegion.hpp"
 #include "../CacheImpl.hpp"
 #include "../ClientHealthStats.hpp"
 #include "../ClientProxyMembershipID.hpp"
+#include "../CppCacheLibrary.hpp"
 #include "../DistributedSystem.hpp"
 #include "../TcrConnectionManager.hpp"
 #include "../util/Log.hpp"
@@ -43,83 +47,6 @@
 namespace apache {
 namespace geode {
 namespace statistics {
-namespace globals {
-
-std::string g_statFile;
-std::string g_statFileWithExt;
-int64_t g_spaceUsed = 0;
-int64_t g_previoussamplesize = 0;
-int64_t g_previoussamplesizeLastFile = 0;
-// Make a pair for the filename & its size
-std::pair<std::string, size_t> g_fileInfoPair;
-// Vector to hold the fileInformation
-typedef std::vector<std::pair<std::string, int64_t> > g_fileInfo;
-
-}  // namespace globals
-}  // namespace statistics
-}  // namespace geode
-}  // namespace apache
-
-namespace {
-
-// extern "C" {
-
-int selector(const dirent* d) {
-  std::string inputname(d->d_name);
-  std::string filebasename = ACE::basename(
-      apache::geode::statistics::globals::g_statFileWithExt.c_str());
-  size_t actualHyphenPos = filebasename.find_last_of('.');
-  if (strcmp(filebasename.c_str(), d->d_name) == 0) return 1;
-  size_t fileExtPos = inputname.find_last_of('.');
-  std::string extName = inputname.substr(fileExtPos + 1, inputname.length());
-  if (strcmp(extName.c_str(), "gfs") != 0) return 0;
-  if (fileExtPos != std::string::npos) {
-    std::string tempname = inputname.substr(0, fileExtPos);
-    size_t fileHyphenPos = tempname.find_last_of('-');
-    if (fileHyphenPos != std::string::npos) {
-      std::string buff1 = tempname.substr(0, fileHyphenPos);
-      if (filebasename.find(buff1) == std::string::npos) {
-        return 0;
-      }
-      if (fileHyphenPos != actualHyphenPos) return 0;
-      std::string buff = tempname.substr(fileHyphenPos + 1,
-                                         tempname.length() - fileHyphenPos - 1);
-      for (std::string::iterator iter = buff.begin(); iter != buff.end();
-           ++iter) {
-        if (*iter < '0' || *iter > '9') {
-          return 0;
-        }
-      }
-      return 1;
-    } else {
-      return 0;
-    }
-  } else {
-    return 0;
-  }
-}
-
-int comparator(const dirent** d1, const dirent** d2) {
-  if (strlen((*d1)->d_name) < strlen((*d2)->d_name)) {
-    return -1;
-  } else if (strlen((*d1)->d_name) > strlen((*d2)->d_name)) {
-    return 1;
-  }
-  int diff = std::strcmp((*d1)->d_name, (*d2)->d_name);
-  if (diff < 0) {
-    return -1;
-  } else if (diff > 0) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-}  // namespace
-
-namespace apache {
-namespace geode {
-namespace statistics {
 
 using std::chrono::duration_cast;
 using std::chrono::high_resolution_clock;
@@ -128,191 +55,123 @@ using std::chrono::nanoseconds;
 
 using client::Exception;
 
-const char* HostStatSampler::NC_HSS_Thread = "NC HSS Thread";
+constexpr auto GFS_EXTENSION = ".gfs";
+
+constexpr size_t kibibyte = 1024;
+constexpr size_t mebibyte = kibibyte * 1024;
+constexpr size_t gibibyte = mebibyte * 1024;
+
+constexpr size_t MAX_STATS_FILE_LIMIT = 1 * gibibyte;
 
-HostStatSampler::HostStatSampler(const char* filePath,
-                                 std::chrono::milliseconds sampleIntervalMs,
+HostStatSampler::HostStatSampler(boost::filesystem::path filePath,
+                                 std::chrono::milliseconds sampleRate,
                                  StatisticsManager* statMngr, CacheImpl* cache,
-                                 int64_t statFileLimit,
-                                 int64_t statDiskSpaceLimit)
-    : m_cache(cache) {
-  m_isStatDiskSpaceEnabled = false;
-  m_adminError = false;
-  m_running = false;
-  m_stopRequested = false;
-  m_archiver = nullptr;
-  m_samplerStats = new StatSamplerStats(statMngr->getStatisticsFactory());
-  m_startTime = system_clock::now();
-  m_pid = boost::this_process::get_id();
+                                 size_t statFileLimit,
+                                 size_t statDiskSpaceLimit)
+
+    : HostStatSampler(std::move(filePath), sampleRate, statFileLimit,
+                      statDiskSpaceLimit) {
+  m_cache = cache;
+  m_samplerStats = std::unique_ptr<StatSamplerStats>(
+      new StatSamplerStats(statMngr->getStatisticsFactory()));
   m_statMngr = statMngr;
-  m_archiveFileName = filePath;
-  globals::g_statFile = filePath;
-  m_sampleRate = sampleIntervalMs;
-  rollIndex = 0;
-  m_archiveDiskSpaceLimit = statDiskSpaceLimit;
-  globals::g_spaceUsed = 0;
-
-  if (statDiskSpaceLimit != 0) {
-    m_isStatDiskSpaceEnabled = true;
-  }
 
-  m_archiveFileSizeLimit = statFileLimit * 1024 * 1024;  // 10000000;
-  if (m_archiveFileSizeLimit < 0 ||
-      m_archiveFileSizeLimit > GEMFIRE_MAX_STATS_FILE_LIMIT) {
-    m_archiveFileSizeLimit = GEMFIRE_MAX_STATS_FILE_LIMIT;
-  }
+  initStatDiskSpaceEnabled();
+}
 
+HostStatSampler::HostStatSampler(boost::filesystem::path filePath,
+                                 std::chrono::milliseconds sampleRate,
+                                 size_t statFileLimit,
+                                 size_t statDiskSpaceLimit)
+    : m_adminError(false),
+      m_running(false),
+      m_stopRequested(false),
+      m_isStatDiskSpaceEnabled(statDiskSpaceLimit != 0),
+      m_archiveFileName(std::move(filePath)),
+      m_archiveFileSizeLimit(
+          std::min(statFileLimit * mebibyte, MAX_STATS_FILE_LIMIT)),
+      m_archiveDiskSpaceLimit(statDiskSpaceLimit * mebibyte),
+      m_spaceUsed(0),
+      m_sampleRate(sampleRate),
+      m_pid(boost::this_process::get_id()),
+      m_startTime(system_clock::now()),
+      m_rollIndex(0) {
   if (m_isStatDiskSpaceEnabled) {
-    m_archiveDiskSpaceLimit = statDiskSpaceLimit * 1024 * 1024;  // 10000000;
-
-    if (m_archiveDiskSpaceLimit <
-        0 /*|| m_archiveDiskSpaceLimit > GEMFIRE_MAX_STAT_DISK_LIMIT*/) {
-      m_archiveDiskSpaceLimit = GEMFIRE_MAX_STAT_DISK_LIMIT;
-    }
-
-    // If FileSizelimit is greater than DiskSpaceLimit & diskspaceLimit is set,
-    // then set DiskSpaceLimit to FileSizelimit
-    if (m_archiveFileSizeLimit > m_archiveDiskSpaceLimit) {
+    if (m_archiveFileSizeLimit == 0 ||
+        m_archiveFileSizeLimit > m_archiveDiskSpaceLimit) {
       m_archiveFileSizeLimit = m_archiveDiskSpaceLimit;
     }
+  }
+}
 
-    // If only DiskSpaceLimit is specified and no FileSizeLimit specified, then
-    // set DiskSpaceLimit to FileSizelimit.
-    // This helps in getting the file handle that is exceeded the limit.
-    if (m_archiveFileSizeLimit == 0) {
-      m_archiveFileSizeLimit = m_archiveDiskSpaceLimit;
-    }
+void HostStatSampler::initStatDiskSpaceEnabled() {
+  if (m_isStatDiskSpaceEnabled) {
+    initStatFileWithExt();
 
-    globals::g_statFileWithExt = initStatFileWithExt();
-
-#ifdef _WIN32
-    // replace all '\' with '/' to make everything easier..
-    std::replace(globals::g_statFile.begin(), globals::g_statFile.end(), '\\',
-                 '/');
-#endif
-
-    std::string dirname = ACE::dirname(globals::g_statFile.c_str());
-    ACE_Dirent_Selector sds;
-    int status = sds.open(dirname.c_str(), selector, comparator);
-    if (status != -1) {
-      for (int i = 0; i < sds.length(); i++) {
-        std::string strname = ACE::basename(sds[i]->d_name);
-        size_t fileExtPos = strname.find_last_of('.', strname.length());
-        if (fileExtPos != std::string::npos) {
-          std::string tempname = strname.substr(0, fileExtPos);
-          size_t fileHyphenPos = tempname.find_last_of('-', tempname.length());
-          if (fileHyphenPos != std::string::npos) {
-            std::string buff =
-                tempname.substr(fileHyphenPos + 1, tempname.length());
-            rollIndex = std::stoi(buff) + 1;
-          }
-        }
-      }
-      sds.close();
-    }
+    initRollIndex();
 
-    FILE* existingFile = fopen(globals::g_statFileWithExt.c_str(), "r");
-    if (existingFile != nullptr && statFileLimit > 0) {
-      fclose(existingFile);
-      existingFile = nullptr;
-      changeArchive(globals::g_statFileWithExt);
+    auto exists = boost::filesystem::exists(m_archiveFileName);
+    if (exists && m_archiveFileSizeLimit > 0) {
+      changeArchive(m_archiveFileName);
     } else {
       writeGfs();
     }
-    if (existingFile != nullptr) {
-      fclose(existingFile);
-      existingFile = nullptr;
-    }
   }
 }
 
-std::string HostStatSampler::initStatFileWithExt() {
-  std::string archivefilename = createArchiveFileName();
-  archivefilename = chkForGFSExt(archivefilename);
-  return archivefilename;
+void HostStatSampler::initRollIndex() {
+  forEachIndexStatFile(
+      [&](const int32_t index, const boost::filesystem::path&) {
+        m_rollIndex = std::max(m_rollIndex, index + 1);
+      });
 }
 
-HostStatSampler::~HostStatSampler() {
-  if (m_samplerStats != nullptr) {
-    delete m_samplerStats;
-    m_samplerStats = nullptr;
-  }
+boost::filesystem::path HostStatSampler::initStatFileWithExt() {
+  return chkForGFSExt(createArchiveFilename());
 }
 
-std::string HostStatSampler::createArchiveFileName() {
+HostStatSampler::~HostStatSampler() noexcept = default;
+
+const boost::filesystem::path& HostStatSampler::createArchiveFilename() {
   if (!m_isStatDiskSpaceEnabled) {
-    char buff[1024] = {0};
-    auto pid = boost::this_process::get_id();
-    auto len = m_archiveFileName.length();
-    auto fileExtPos = m_archiveFileName.find_last_of('.', len);
-    if (fileExtPos == std::string::npos) {
-      std::snprintf(buff, 1024, "%s-%d.gfs", m_archiveFileName.c_str(), pid);
+    const auto pid = std::to_string(boost::this_process::get_id());
+
+    if (!m_archiveFileName.has_extension()) {
+      m_archiveFileName += "-" + pid;
     } else {
-      std::string tmp;
-      tmp = m_archiveFileName.substr(0, fileExtPos);
-      std::snprintf(buff, 1024, "%s-%d.gfs", tmp.c_str(), pid);
+      m_archiveFileName = m_archiveFileName.parent_path() /
+                          m_archiveFileName.stem() += "-" + pid;
     }
-    m_archiveFileName = buff;
-    return m_archiveFileName;
-  } else {
-    return m_archiveFileName;
+    m_archiveFileName += GFS_EXTENSION;
   }
+
+  return m_archiveFileName;
 }
 
-std::string HostStatSampler::getArchiveFileName() { return m_archiveFileName; }
+const boost::filesystem::path& HostStatSampler::getArchiveFilename() const {
+  return m_archiveFileName;
+}
 
-int64_t HostStatSampler::getArchiveFileSizeLimit() {
+size_t HostStatSampler::getArchiveFileSizeLimit() const {
   return m_archiveFileSizeLimit;
 }
 
-int64_t HostStatSampler::getArchiveDiskSpaceLimit() {
+size_t HostStatSampler::getArchiveDiskSpaceLimit() const {
   return m_archiveDiskSpaceLimit;
 }
 
-std::chrono::milliseconds HostStatSampler::getSampleRate() {
+std::chrono::milliseconds HostStatSampler::getSampleRate() const {
   return m_sampleRate;
 }
 
-bool HostStatSampler::isSamplingEnabled() { return true; }
-
 void HostStatSampler::accountForTimeSpentWorking(int64_t nanosSpentWorking) {
   m_samplerStats->tookSample(nanosSpentWorking);
 }
 
-bool HostStatSampler::statisticsExists(const int64_t id) {
-  std::lock_guard<decltype(m_statMngr->getListMutex())> guard(
-      m_statMngr->getListMutex());
-  std::vector<Statistics*>& statsList = m_statMngr->getStatsList();
-  std::vector<Statistics*>::iterator i;
-  for (i = statsList.begin(); i != statsList.end(); ++i) {
-    if ((*i)->getUniqueId() == id) {
-      return true;
-    }
-  }
-  return false;
-}
-
-Statistics* HostStatSampler::findStatistics(const int64_t id) {
-  std::lock_guard<decltype(m_statMngr->getListMutex())> guard(
-      m_statMngr->getListMutex());
-  std::vector<Statistics*>& statsList = m_statMngr->getStatsList();
-  std::vector<Statistics*>::iterator i;
-  for (i = statsList.begin(); i != statsList.end(); ++i) {
-    if ((*i)->getUniqueId() == id) {
-      return *i;
-    }
-  }
-  return nullptr;
-}
-
 std::recursive_mutex& HostStatSampler::getStatListMutex() {
   return m_statMngr->getListMutex();
 }
 
-int32_t HostStatSampler::getStatisticsModCount() {
-  return m_statMngr->getStatListModCount();
-}
-
 std::vector<Statistics*>& HostStatSampler::getStatistics() {
   return m_statMngr->getStatsList();
 }
@@ -327,154 +186,71 @@ system_clock::time_point HostStatSampler::getSystemStartTime() {
   return m_startTime;
 }
 
-std::string HostStatSampler::getSystemDirectoryPath() {
-  ACE_utsname u;
-  ACE_OS::uname(&u);
-  std::string dirPath(u.nodename);
-  return dirPath;
+const std::string& HostStatSampler::getSystemDirectoryPath() {
+  return client::CppCacheLibrary::getProductDir();
 }
 
-std::string HostStatSampler::getProductDescription() {
-  return "Apache Geode Native Client ";
+const std::string& HostStatSampler::getProductDescription() const {
+  return client::CacheFactory::getProductDescription();
 }
 
-void HostStatSampler::changeArchive(std::string filename) {
-  if (filename.length() == 0) {
+void HostStatSampler::changeArchive(boost::filesystem::path filename) {
+  if (filename.empty()) {
     // terminate the sampling thread
     m_stopRequested = true;
     return;
   }
+
   filename = chkForGFSExt(filename);
-  if (m_archiver != nullptr) {
-    globals::g_previoussamplesize = m_archiver->getSampleSize();
+
+  if (m_archiver) {
     m_archiver->closeFile();
   }
-  // create new file only when tis file has some data; otherwise reuse it
+
   rollArchive(filename);
 
-  m_archiver.reset(new StatArchiveWriter(filename, this, m_cache));
+  m_archiver.reset(new StatArchiveWriter(filename.string(), this, m_cache));
 }
 
-std::string HostStatSampler::chkForGFSExt(std::string filename) {
-  if (!m_isStatDiskSpaceEnabled) {
-    int32_t len = static_cast<int32_t>(filename.length());
-    size_t posOfExt = filename.find_last_of('.', len);
-    if (posOfExt == std::string::npos) {
-      std::string newFilename = filename + "." + "gfs";
-      return newFilename;
-    }
-    std::string extName = filename.substr(posOfExt + 1);
-    if (extName != "gfs") {
-      std::string newFilename = filename.substr(0, posOfExt) + "." + "gfs";
-      return newFilename;
-    }
+boost::filesystem::path HostStatSampler::chkForGFSExt(
+    const boost::filesystem::path& filename) const {
+  if (filename.extension() == GFS_EXTENSION) {
     return filename;
-  } else {
-    std::string filebasename = ACE::basename(filename.c_str());
-    int32_t len = static_cast<int32_t>(filebasename.length());
-    size_t fileExtPos = filebasename.find_last_of('.', len);
-    // if no extension then add .gfs extension
-    if (fileExtPos == std::string::npos) {
-      std::string newFilename = filename + "." + "gfs";
-      return newFilename;
-    } else {
-      std::string extName = filebasename.substr(fileExtPos + 1);
-      // if extension other than .gfs change it to ext + .log
-      if (extName != "gfs") {
-        std::string newFilename = filename + "." + "gfs";
-        return newFilename;
-      }
-      // .gfs Extension already provided, no need to append any extension.
-      else {
-        return filename;
-      }
-    }
   }
-}
 
-int32_t HostStatSampler::rollArchive(std::string filename) {
-  FILE* fpExist = fopen(filename.c_str(), "r");
-  if (fpExist == nullptr) {
-    return 0;  // no need to roll
-  } else {
-    fclose(fpExist);
-    ACE_stat statBuf = {};
-    ACE_OS::stat(filename.c_str(), &statBuf);
-    if (statBuf.st_size == 0) return 0;  // reuse this file
+  auto tmp = filename;
+  if (m_isStatDiskSpaceEnabled) {
+    return tmp += GFS_EXTENSION;
   }
+  return tmp.replace_extension(GFS_EXTENSION);
+}
 
-  std::string statsdirname;
-  std::string statsbasename;
-  std::string fnameBeforeExt;
-  std::string extName;
-  std::string newfilestr;
-  bool gotNewFileName = false;
-  int32_t len = static_cast<int32_t>(filename.length());
-  int32_t lastPosOfSep = static_cast<int32_t>(
-      filename.find_last_of(ACE_DIRECTORY_SEPARATOR_CHAR, len));
-  if (lastPosOfSep == -1) {
-    statsdirname = ".";
-  } else {
-    statsdirname = filename.substr(0, lastPosOfSep);
+void HostStatSampler::rollArchive(const boost::filesystem::path& filename) {
+  if (!boost::filesystem::exists(filename) ||
+      boost::filesystem::is_empty(filename)) {
+    return;
   }
-  statsbasename = filename.substr(lastPosOfSep + 1, len);
-  char gfsFileExtAfter = '.';
-  int32_t baselen = static_cast<int32_t>(statsbasename.length());
-  int32_t posOfExt = static_cast<int32_t>(statsbasename.find_last_of(
-      gfsFileExtAfter, static_cast<int32_t>(baselen)));
-  if (posOfExt == -1) {
-    // throw IllegalArgument;
-  } else {
-    fnameBeforeExt = statsbasename.substr(0, posOfExt);
-    extName = statsbasename.substr(posOfExt + 1, baselen);
+
+  const auto extension = filename.extension();
+  if (extension.empty()) {
+    throw client::IllegalArgumentException("Missing extension.");
   }
 
-  int32_t i = this->rollIndex;
-  // 1000 is a good enough val to hold even a very int64_t filename.
-  while (!gotNewFileName) {
-    char newfilename[1000] = {0};
-    if (i < 10) {
-      std::snprintf(newfilename, 1000, "%s%c%s-%d.%s", statsdirname.c_str(),
-                    ACE_DIRECTORY_SEPARATOR_CHAR, fnameBeforeExt.c_str(), i,
-                    extName.c_str());
-    } else {
-      std::snprintf(newfilename, 1000, "%s%c%s-%d.%s", statsdirname.c_str(),
-                    ACE_DIRECTORY_SEPARATOR_CHAR, fnameBeforeExt.c_str(), i,
-                    extName.c_str());
-    }
-    FILE* fp = fopen(newfilename, "r");
+  while (true) {
+    auto newFilename = filename.parent_path() / filename.stem();
+    newFilename += "-";
+    newFilename += std::to_string(m_rollIndex++);
+    newFilename += extension;
 
-    if (fp != nullptr) {
-      // file exists; increment i and try the next filename
-      i++;
-      fclose(fp);
-    } else {
-      newfilestr = newfilename;
-      // In the next call it will start looking from rollIndex = i+1
-      if (rename(filename.c_str(), newfilestr.c_str()) < 0) {
-        return -1;
-      } else {
-        this->rollIndex = i + 1;
-        return 0;
-      }
+    if (boost::filesystem::exists(newFilename)) {
+      continue;
     }
-  }
-  // The control will come here in case of error only.
-  // This return looks redundant but introduced to remove warnings
-  // while compiling the code.
-  return -1;
-}
 
-void HostStatSampler::initSpecialStats() {
-  // After Special categories are decided initialize them here
+    boost::filesystem::rename(filename, newFilename);
+    break;
+  }
 }
 
-void HostStatSampler::sampleSpecialStats() {}
-
-void HostStatSampler::closeSpecialStats() {}
-
-void HostStatSampler::checkListeners() {}
-
 void HostStatSampler::start() {
   if (!m_running.exchange(true)) {
     m_thread = std::thread(&HostStatSampler::svc, this);
@@ -486,7 +262,7 @@ void HostStatSampler::stop() {
   m_thread.join();
 }
 
-bool HostStatSampler::isRunning() { return m_running; }
+bool HostStatSampler::isRunning() const { return m_running; }
 
 void HostStatSampler::putStatsInAdminRegion() {
   try {
@@ -530,16 +306,9 @@ void HostStatSampler::putStatsInAdminRegion() {
         auto obj = client::ClientHealthStats::create(
             gets, puts, misses, numListeners, numThreads, cpuTime, numCPU);
         if (clientId.empty()) {
-          ACE_TCHAR hostName[256];
-          ACE_OS::hostname(hostName, sizeof(hostName) - 1);
-          ACE_INET_Addr driver("", hostName, "tcp");
-
-          uint16_t hostPort = 0;
-
           auto memId = conn_man->getCacheImpl()
                            ->getClientProxyMembershipIDFactory()
-                           .create(hostName, driver, hostPort,
-                                   m_durableClientId, m_durableTimeout);
+                           .create(m_durableClientId, m_durableTimeout);
           clientId = memId->getDSMemberIdForThinClientUse();
         }
 
@@ -553,28 +322,23 @@ void HostStatSampler::putStatsInAdminRegion() {
 }
 
 void HostStatSampler::writeGfs() {
-  std::string archivefilename = createArchiveFileName();
-  changeArchive(archivefilename);
+  const auto& archiveFilename = createArchiveFilename();
+  changeArchive(archiveFilename);
 }
 
 void HostStatSampler::forceSample() {
   std::lock_guard<decltype(m_samplingLock)> guard(m_samplingLock);
 
   if (m_archiver) {
-    sampleSpecialStats();
     m_archiver->sample();
     m_archiver->flush();
   }
 }
 
-void HostStatSampler::doSample(std::string& archivefilename) {
+void HostStatSampler::doSample(const boost::filesystem::path& archiveFilename) {
   std::lock_guard<decltype(m_samplingLock)> guard(m_samplingLock);
 
-  sampleSpecialStats();
-  checkListeners();
-
-  // Populate Admin Region for GFMon
-  if (isSamplingEnabled() && !m_adminError) {
+  if (!m_adminError) {
     putStatsInAdminRegion();
   }
 
@@ -582,18 +346,17 @@ void HostStatSampler::doSample(std::string& archivefilename) {
     m_archiver->sample();
 
     if (m_archiveFileSizeLimit != 0) {
-      int64_t size = m_archiver->getSampleSize();
-      int64_t bytesWritten =
-          m_archiver->bytesWritten();  // + g_previoussamplesize;
+      auto size = m_archiver->getSampleSize();
+      auto bytesWritten = m_archiver->bytesWritten();
       if (bytesWritten > (m_archiveFileSizeLimit - size)) {
         // roll the archive
-        changeArchive(archivefilename);
+        changeArchive(archiveFilename);
       }
     }
-    globals::g_spaceUsed += m_archiver->bytesWritten();
+    m_spaceUsed += m_archiver->bytesWritten();
     // delete older stat files if disk limit is about to be exceeded.
     if ((m_archiveDiskSpaceLimit != 0) &&
-        (globals::g_spaceUsed >=
+        (m_spaceUsed >=
          (m_archiveDiskSpaceLimit - m_archiver->getSampleSize()))) {
       checkDiskLimit();
     }
@@ -605,50 +368,72 @@ void HostStatSampler::doSample(std::string& archivefilename) {
   }
 }
 
-void HostStatSampler::checkDiskLimit() {
-  globals::g_fileInfo fileInfo;
-  globals::g_spaceUsed = 0;
-  char fullpath[512] = {0};
-  std::string dirname = ACE::dirname(globals::g_statFile.c_str());
-  ACE_stat statBuf = {};
-  ACE_Dirent_Selector sds;
-  int status = sds.open(dirname.c_str(), selector, comparator);
-  if (status != -1) {
-    for (int i = 1; i < sds.length(); i++) {
-      std::snprintf(fullpath, 512, "%s%c%s", dirname.c_str(),
-                    ACE_DIRECTORY_SEPARATOR_CHAR, sds[i]->d_name);
-      ACE_OS::stat(fullpath, &statBuf);
-      globals::g_fileInfoPair = std::make_pair(fullpath, statBuf.st_size);
-      fileInfo.push_back(globals::g_fileInfoPair);
-      globals::g_spaceUsed += fileInfo[i - 1].second;
+template <typename _Function>
+void HostStatSampler::forEachIndexStatFile(_Function function) const {
+  const std::regex statsFilter(m_archiveFileName.stem().string() +
+                               R"(-([\d]+))" +
+                               m_archiveFileName.extension().string());
+
+  auto dir = m_archiveFileName.parent_path();
+  if (dir.empty()) {
+    dir = boost::filesystem::current_path();
+  }
+
+  for (const auto& entry :
+       boost::make_iterator_range(boost::filesystem::directory_iterator(dir),
+                                  {}) |
+           boost::adaptors::filtered(
+               static_cast<bool (*)(const boost::filesystem::path&)>(
+                   &boost::filesystem::is_regular_file))) {
+    std::smatch match;
+    const auto& file = entry.path();
+    const auto filename = file.filename();
+    const auto& filenameStr = filename.string();
+    if (std::regex_match(filenameStr, match, statsFilter)) {
+      const auto index = std::stoi(match[1].str());
+      function(index, file);
     }
-    globals::g_spaceUsed += m_archiver->bytesWritten();
-    sds.close();
   }
-  int fileIndex = 0;
-  while ((globals::g_spaceUsed >
-          m_archiveDiskSpaceLimit) /*&& (fileIndex < entries_count)*/) {
-    int64_t fileSize = fileInfo[fileIndex].second;
-    if (ACE_OS::unlink(fileInfo[fileIndex].first.c_str()) == 0) {
-      globals::g_spaceUsed -= fileSize;
-    } else {
-      LOGWARN("%s\t%s\n", "Could not delete",
-              fileInfo[fileIndex].first.c_str());
+}
+
+void HostStatSampler::checkDiskLimit() {
+  m_spaceUsed = 0;
+
+  std::map<int32_t, std::pair<boost::filesystem::path, size_t>> indexedFiles;
+  forEachIndexStatFile(
+      [&](const int32_t index, const boost::filesystem::path& file) {
+        const auto size = boost::filesystem::file_size(file);
+        indexedFiles.emplace(index, std::make_pair(file, size));
+        m_spaceUsed += size;
+      });
+
+  if (m_archiver) {
+    m_spaceUsed += m_archiver->bytesWritten();
+  }
+
+  for (const auto& i : indexedFiles) {
+    if (m_spaceUsed > m_archiveDiskSpaceLimit) {
+      const auto& file = i.second.first;
+      const auto size = i.second.second;
+      try {
+        boost::filesystem::remove(file);
+        m_spaceUsed -= size;
+      } catch (boost::filesystem::filesystem_error& e) {
+        LOGWARN("Could not delete " + file.string() + ": " + e.what());
+      }
     }
-    fileIndex++;
   }
 }
 
 void HostStatSampler::svc(void) {
-  client::DistributedSystemImpl::setThreadName(NC_HSS_Thread);
+  client::DistributedSystemImpl::setThreadName("NC HSS Thread");
   try {
-    initSpecialStats();
     // createArchiveFileName instead of getArchiveFileName here because
     // for the first time the sampler needs to add the pid to the filename
     // passed to it.
-    auto archivefilename = createArchiveFileName();
+    auto archiveFilename = createArchiveFilename();
     if (!m_isStatDiskSpaceEnabled) {
-      changeArchive(archivefilename);
+      changeArchive(archiveFilename);
     }
     auto samplingRate = milliseconds(getSampleRate());
     bool gotexception = false;
@@ -664,12 +449,12 @@ void HostStatSampler::svc(void) {
           }
           waitTime = 0;
           gotexception = false;
-          changeArchive(archivefilename);
+          changeArchive(archiveFilename);
         }
 
         auto sampleStart = high_resolution_clock::now();
 
-        doSample(archivefilename);
+        doSample(archiveFilename);
 
         nanoseconds spentWorking = high_resolution_clock::now() - sampleStart;
         // updating the sampler statistics
@@ -695,7 +480,6 @@ void HostStatSampler::svc(void) {
         gotexception = true;
       }
     }
-    closeSpecialStats();
     m_samplerStats->close();
     if (m_archiver != nullptr) {
       m_archiver->close();
@@ -704,7 +488,6 @@ void HostStatSampler::svc(void) {
     // log the exception and let the thread exit.
     LOGERROR("Exception in statistics sampler thread: %s: %s",
              e.getName().c_str(), e.what());
-    closeSpecialStats();
   } /* catch (...) {
        // log the exception and let the thread exit.
        LOGERROR("Exception in sampler thread ");
@@ -712,6 +495,7 @@ void HostStatSampler::svc(void) {
    }*/
   m_running = false;
 }
+
 }  // namespace statistics
 }  // namespace geode
 }  // namespace apache
diff --git a/cppcache/src/statistics/HostStatSampler.hpp b/cppcache/src/statistics/HostStatSampler.hpp
index 09d8d19..ad6656e 100644
--- a/cppcache/src/statistics/HostStatSampler.hpp
+++ b/cppcache/src/statistics/HostStatSampler.hpp
@@ -24,10 +24,13 @@
 #include <chrono>
 #include <memory>
 #include <mutex>
+#include <regex>
 #include <string>
 #include <thread>
 #include <vector>
 
+#include <boost/filesystem/path.hpp>
+
 #include <geode/ExceptionTypes.hpp>
 #include <geode/internal/geode_globals.hpp>
 
@@ -38,13 +41,7 @@
 #include "StatisticsManager.hpp"
 #include "StatisticsType.hpp"
 
-#ifndef GEMFIRE_MAX_STATS_FILE_LIMIT
-#define GEMFIRE_MAX_STATS_FILE_LIMIT (1024 * 1024 * 1024)
-#endif
-
-#ifndef GEMFIRE_MAX_STAT_DISK_LIMIT
-#define GEMFIRE_MAX_STAT_DISK_LIMIT (1024LL * 1024LL * 1024LL * 1024LL)
-#endif
+class TestableHostStatSampler;
 
 namespace apache {
 namespace geode {
@@ -62,10 +59,12 @@ class StatisticsManager;
  */
 class HostStatSampler {
  public:
-  HostStatSampler(const char* filePath,
-                  std::chrono::milliseconds sampleIntervalMs,
+  HostStatSampler(boost::filesystem::path filePath,
+                  std::chrono::milliseconds sampleRate,
                   StatisticsManager* statMngr, CacheImpl* cache,
-                  int64_t statFileLimit = 0, int64_t statDiskSpaceLimit = 0);
+                  size_t statFileLimit = 0, size_t statDiskSpaceLimit = 0);
+
+  ~HostStatSampler() noexcept;
 
   HostStatSampler(const HostStatSampler&) = delete;
 
@@ -74,46 +73,28 @@ class HostStatSampler {
   /**
    * Adds the pid to the archive file passed to it.
    */
-  std::string createArchiveFileName();
+  const boost::filesystem::path& createArchiveFilename();
   /**
    * Returns the archiveFileName
    */
-  std::string getArchiveFileName();
+  const boost::filesystem::path& getArchiveFilename() const;
   /**
    * Gets the archive size limit in bytes.
    */
-  int64_t getArchiveFileSizeLimit();
+  size_t getArchiveFileSizeLimit() const;
   /**
    * Gets the archive disk space limit in bytes.
    */
-  int64_t getArchiveDiskSpaceLimit();
+  size_t getArchiveDiskSpaceLimit() const;
   /**
    * Gets the sample rate in milliseconds
    */
-  std::chrono::milliseconds getSampleRate();
-  /**
-   * Returns true if sampling is enabled.
-   */
-  bool isSamplingEnabled();
+  std::chrono::milliseconds getSampleRate() const;
   /**
    * Called when this sampler has spent some time working and wants
    * it to be accounted for.
    */
   void accountForTimeSpentWorking(int64_t nanosSpentWorking);
-
-  /**
-   * Returns true if the specified statistic resource still exists.
-   */
-  bool statisticsExists(int64_t id);
-  /**
-   * Returns the statistics resource instance given its id.
-   */
-  Statistics* findStatistics(int64_t id);
-
-  /**
-   * Returns the number of statistics object the manager has.
-   */
-  int32_t getStatisticsModCount();
   /**
    * Gets list mutex for synchronization
    */
@@ -138,29 +119,27 @@ class HostStatSampler {
   /**
    * Returns the path to this sampler's system directory; if it has one.
    */
-  std::string getSystemDirectoryPath();
+  const std::string& getSystemDirectoryPath();
   /**
    * Returns a description of the product that the stats are on
    */
-  std::string getProductDescription();
+  const std::string& getProductDescription() const;
   /**
    * If the size of the archive file exceeds the size limit then the sampler
    * starts writing in a new file. The path of the new file need to be
    * obtained from the manager.
    */
-  void changeArchive(std::string);
-
-  void checkListeners();
+  void changeArchive(boost::filesystem::path);
 
   void writeGfs();
 
   void forceSample();
 
-  void doSample(std::string& archivefilename);
+  void doSample(const boost::filesystem::path& archiveFilename);
+
   /**
    * If the total size of all the archive files exceeds the archive disk space
-   * limit then the older
-   * files are deleted.
+   * limit then the older files are deleted.
    */
   void checkDiskLimit();
 
@@ -180,9 +159,7 @@ class HostStatSampler {
   /**
    * Method to know whether the sampling thread is running or not.
    */
-  bool isRunning();
-
-  ~HostStatSampler();
+  bool isRunning() const;
 
  private:
   std::recursive_mutex m_samplingLock;
@@ -192,13 +169,14 @@ class HostStatSampler {
   std::atomic<bool> m_stopRequested;
   std::atomic<bool> m_isStatDiskSpaceEnabled;
   std::unique_ptr<StatArchiveWriter> m_archiver;
-  StatSamplerStats* m_samplerStats;
+  std::unique_ptr<StatSamplerStats> m_samplerStats;
   const char* m_durableClientId;
   std::chrono::seconds m_durableTimeout;
 
-  std::string m_archiveFileName;
-  int64_t m_archiveFileSizeLimit;
-  int64_t m_archiveDiskSpaceLimit;
+  boost::filesystem::path m_archiveFileName;
+  size_t m_archiveFileSizeLimit;
+  size_t m_archiveDiskSpaceLimit;
+  size_t m_spaceUsed = 0;
   std::chrono::milliseconds m_sampleRate;
   StatisticsManager* m_statMngr;
   CacheImpl* m_cache;
@@ -206,41 +184,49 @@ class HostStatSampler {
   int64_t m_pid;
   system_clock::time_point m_startTime;
 
-  std::string initStatFileWithExt();
+  /**
+   * For testing only.
+   */
+  explicit HostStatSampler(boost::filesystem::path filePath,
+                           std::chrono::milliseconds sampleRate,
+                           size_t statFileLimit, size_t statDiskSpaceLimit);
+
+  boost::filesystem::path initStatFileWithExt();
+
   /**
    * The archiveFile, after it exceeds archiveFileSizeLimit should be rolled
    * to a new file name. This integer rollIndex will be used to format the
    * file name into which the current archiveFile will be renamed.
    */
-  int32_t rollIndex;
+  int32_t m_rollIndex;
+
   /**
-   * This function rolls the existing archive file
+   * This function rolls the existing archive file.
+   * Create new file only if current file has some data, otherwise reuse it.
    */
-  int32_t rollArchive(std::string filename);
+  void rollArchive(const boost::filesystem::path& filename);
+
   /**
    * This function check whether the filename has gfs ext or not
    * If it is not there it adds and then returns the new filename.
    */
-  std::string chkForGFSExt(std::string filename);
+  boost::filesystem::path chkForGFSExt(
+      const boost::filesystem::path& filename) const;
 
   /**
-   * Initialize any special sampler stats. Like ProcessStats, HostStats
-   */
-  void initSpecialStats();
-  /**
-   * Collect samples of the special tests.
-   */
-  void sampleSpecialStats();
-  /**
-   * Closes down anything initialied by initSpecialStats.
-   */
-  void closeSpecialStats();
-  /**
    * Update New Stats in Admin Region.
    */
   void putStatsInAdminRegion();
 
+  void initStatDiskSpaceEnabled();
+
   static const char* NC_HSS_Thread;
+
+  friend TestableHostStatSampler;
+  void initRollIndex();
+
+  template <typename _Function>
+  void forEachIndexStatFile(_Function function) const;
 };
 
 }  // namespace statistics
diff --git a/cppcache/src/statistics/PoolStatsSampler.cpp b/cppcache/src/statistics/PoolStatsSampler.cpp
index b7d13fe..9e28db0 100644
--- a/cppcache/src/statistics/PoolStatsSampler.cpp
+++ b/cppcache/src/statistics/PoolStatsSampler.cpp
@@ -19,6 +19,7 @@
 
 #include <string>
 
+#include "../AdminRegion.hpp"
 #include "../CacheImpl.hpp"
 #include "../ClientHealthStats.hpp"
 #include "../ReadWriteLock.hpp"
diff --git a/cppcache/src/statistics/StatArchiveWriter.cpp b/cppcache/src/statistics/StatArchiveWriter.cpp
index cd7a5b9..29d0707 100644
--- a/cppcache/src/statistics/StatArchiveWriter.cpp
+++ b/cppcache/src/statistics/StatArchiveWriter.cpp
@@ -20,8 +20,8 @@
 #include <chrono>
 #include <ctime>
 
-#include <ace/OS_NS_sys_utsname.h>
-#include <ace/OS_NS_time.h>
+#include <boost/asio/ip/host_name.hpp>
+#include <boost/date_time.hpp>
 
 #include <geode/internal/geode_globals.hpp>
 
@@ -29,6 +29,7 @@
 #include "../util/chrono/time_point.hpp"
 #include "GeodeStatisticsFactory.hpp"
 #include "HostStatSampler.hpp"
+#include "config.h"
 
 namespace apache {
 namespace geode {
@@ -323,9 +324,6 @@ StatArchiveWriter::StatArchiveWriter(std::string outfile,
   archiveFile = outfile;
   bytesWrittenToFile = 0;
 
-  /* adongre
-   * CID 28982: Uninitialized scalar field (UNINIT_CTOR)
-   */
   m_samplesize = 0;
 
   dataBuffer = new StatDataOutput(archiveFile, cache);
@@ -345,39 +343,26 @@ StatArchiveWriter::StatArchiveWriter(std::string outfile,
       duration_cast<milliseconds>(
           sampler->getSystemStartTime().time_since_epoch())
           .count());
-  int32_t tzOffset = ACE_OS::timezone();
-  // offset in milli seconds
-  tzOffset = tzOffset * -1 * 1000;
-  this->dataBuffer->writeInt(tzOffset);
 
+  // C++20: Use std::chrono::time_zone
+  boost::posix_time::time_duration timeZoneOffset(
+      boost::posix_time::second_clock::local_time() -
+      boost::posix_time::second_clock::universal_time());
+  this->dataBuffer->writeInt(
+      static_cast<int32_t>(timeZoneOffset.total_milliseconds()));
+
+  // C++20: Use std::chrono::time_zone
   auto now = std::chrono::system_clock::now();
-  auto tm_val = apache::geode::util::chrono::localtime(now);
-  char buf[512] = {0};
-  std::strftime(buf, sizeof(buf), "%Z", &tm_val);
-  std::string tzId(buf);
-  this->dataBuffer->writeUTF(tzId);
-
-  std::string sysDirPath = sampler->getSystemDirectoryPath();
-  this->dataBuffer->writeUTF(sysDirPath);
-  std::string prodDesc = sampler->getProductDescription();
-
-  this->dataBuffer->writeUTF(prodDesc);
-  ACE_utsname u;
-  ACE_OS::uname(&u);
-  std::string os(u.sysname);
-  os += " ";
-  /* This version name returns date of release of the version which
-   creates confusion about the creation time of the vsd file. Hence
-   removing it now. Later I'll change it to just show version without
-   date. For now only name of the OS will be displayed.
-   */
-  // os += u.version;
+  auto localTime = apache::geode::util::chrono::localtime(now);
+  std::ostringstream timeZoneId;
+  timeZoneId << std::put_time(&localTime, "%Z");
+  this->dataBuffer->writeUTF(timeZoneId.str());
 
-  this->dataBuffer->writeUTF(os);
-  std::string machineInfo(u.machine);
-  machineInfo += " ";
-  machineInfo += u.nodename;
-  this->dataBuffer->writeUTF(machineInfo);
+  this->dataBuffer->writeUTF(sampler->getSystemDirectoryPath());
+  this->dataBuffer->writeUTF(sampler->getProductDescription());
+  this->dataBuffer->writeUTF(GEODE_SYSTEM_NAME);
+  this->dataBuffer->writeUTF(std::string(GEODE_SYSTEM_PROCESSOR) + " " +
+                             boost::asio::ip::host_name());
 
   resampleResources();
 }
@@ -393,9 +378,9 @@ StatArchiveWriter::~StatArchiveWriter() {
   }
 }
 
-int64_t StatArchiveWriter::bytesWritten() { return bytesWrittenToFile; }
+size_t StatArchiveWriter::bytesWritten() { return bytesWrittenToFile; }
 
-int64_t StatArchiveWriter::getSampleSize() { return m_samplesize; }
+size_t StatArchiveWriter::getSampleSize() { return m_samplesize; }
 
 void StatArchiveWriter::sample(const steady_clock::time_point &timeStamp) {
   std::lock_guard<decltype(sampler->getStatListMutex())> guard(
diff --git a/cppcache/src/statistics/StatArchiveWriter.hpp b/cppcache/src/statistics/StatArchiveWriter.hpp
index 3193573..a343647 100644
--- a/cppcache/src/statistics/StatArchiveWriter.hpp
+++ b/cppcache/src/statistics/StatArchiveWriter.hpp
@@ -1,8 +1,3 @@
-#pragma once
-
-#ifndef GEODE_STATISTICS_STATARCHIVEWRITER_H_
-#define GEODE_STATISTICS_STATARCHIVEWRITER_H_
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -20,6 +15,11 @@
  * limitations under the License.
  */
 
+#pragma once
+
+#ifndef GEODE_STATISTICS_STATARCHIVEWRITER_H_
+#define GEODE_STATISTICS_STATARCHIVEWRITER_H_
+
 #include <chrono>
 #include <list>
 #include <map>
@@ -32,27 +32,28 @@
 
 #include "../SerializationRegistry.hpp"
 #include "../util/Log.hpp"
+#include "HostStatSampler.hpp"
 #include "StatisticDescriptor.hpp"
 #include "StatisticDescriptorImpl.hpp"
 #include "Statistics.hpp"
 #include "StatisticsType.hpp"
 #include "StatsDef.hpp"
 
-const int8_t ARCHIVE_VERSION = 4;
-const int8_t SAMPLE_TOKEN = 0;
-const int8_t RESOURCE_TYPE_TOKEN = 1;
-const int8_t RESOURCE_INSTANCE_CREATE_TOKEN = 2;
-const int8_t RESOURCE_INSTANCE_DELETE_TOKEN = 3;
-const int8_t RESOURCE_INSTANCE_INITIALIZE_TOKEN = 4;
-const int8_t HEADER_TOKEN = 77;
-const int8_t ILLEGAL_RESOURCE_INST_ID = -1;
-const int16_t MAX_BYTE_RESOURCE_INST_ID = 252;
-const int16_t SHORT_RESOURCE_INST_ID_TOKEN = 253;
-const int32_t INT_RESOURCE_INST_ID_TOKEN = 254;
-const int16_t ILLEGAL_RESOURCE_INST_ID_TOKEN = -1;
-const int32_t MAX_SHORT_RESOURCE_INST_ID = 65535;
-const int32_t MAX_SHORT_TIMESTAMP = 65534;
-const int32_t INT_TIMESTAMP_TOKEN = 65535;
+constexpr int8_t ARCHIVE_VERSION = 4;
+constexpr int8_t SAMPLE_TOKEN = 0;
+constexpr int8_t RESOURCE_TYPE_TOKEN = 1;
+constexpr int8_t RESOURCE_INSTANCE_CREATE_TOKEN = 2;
+constexpr int8_t RESOURCE_INSTANCE_DELETE_TOKEN = 3;
+constexpr int8_t RESOURCE_INSTANCE_INITIALIZE_TOKEN = 4;
+constexpr int8_t HEADER_TOKEN = 77;
+constexpr int8_t ILLEGAL_RESOURCE_INST_ID = -1;
+constexpr int16_t MAX_BYTE_RESOURCE_INST_ID = 252;
+constexpr int16_t SHORT_RESOURCE_INST_ID_TOKEN = 253;
+constexpr int32_t INT_RESOURCE_INST_ID_TOKEN = 254;
+constexpr int16_t ILLEGAL_RESOURCE_INST_ID_TOKEN = -1;
+constexpr int32_t MAX_SHORT_RESOURCE_INST_ID = 65535;
+constexpr int32_t MAX_SHORT_TIMESTAMP = 65534;
+constexpr int32_t INT_TIMESTAMP_TOKEN = 65535;
 
 namespace apache {
 namespace geode {
@@ -185,8 +186,8 @@ class APACHE_GEODE_EXPORT StatArchiveWriter {
   int32_t resourceTypeId;
   int32_t resourceInstId;
   int32_t statResourcesModCount;
-  int64_t bytesWrittenToFile;
-  int64_t m_samplesize;
+  size_t bytesWrittenToFile;
+  size_t m_samplesize;
   std::string archiveFile;
   std::map<Statistics *, std::shared_ptr<ResourceInst>> resourceInstMap;
   std::map<const StatisticsType *, const ResourceType *> resourceTypeMap;
@@ -209,7 +210,7 @@ class APACHE_GEODE_EXPORT StatArchiveWriter {
    * Returns the number of bytes written so far to this archive.
    * This does not take compression into account.
    */
-  int64_t bytesWritten();
+  size_t bytesWritten();
   /**
    * Archives a sample snapshot at the given timeStamp.
    * @param timeStamp a value obtained using NanoTimer::now.
@@ -239,7 +240,7 @@ class APACHE_GEODE_EXPORT StatArchiveWriter {
   /**
    * Returns the size of number of bytes written so far to this archive.
    */
-  int64_t getSampleSize();
+  size_t getSampleSize();
 
   /**
    * Flushes the contents of the dataBuffer to the archiveFile
diff --git a/cppcache/src/statistics/StatisticsManager.cpp b/cppcache/src/statistics/StatisticsManager.cpp
index 0da86e8..4f7b8d2 100644
--- a/cppcache/src/statistics/StatisticsManager.cpp
+++ b/cppcache/src/statistics/StatisticsManager.cpp
@@ -22,6 +22,7 @@
 #include <geode/Exception.hpp>
 #include <geode/internal/geode_globals.hpp>
 
+#include "../AdminRegion.hpp"
 #include "../util/Log.hpp"
 #include "AtomicStatisticsImpl.hpp"
 #include "GeodeStatisticsFactory.hpp"
@@ -230,11 +231,11 @@ void StatisticsManager::deleteStatistics(Statistics*& stat) {
 }
 
 void StatisticsManager::RegisterAdminRegion(
-    std::shared_ptr<AdminRegion> adminRegPtr) {
+    std::shared_ptr<client::AdminRegion> adminRegPtr) {
   m_adminRegion = adminRegPtr;
 }
 
-std::shared_ptr<AdminRegion> StatisticsManager::getAdminRegion() {
+std::shared_ptr<client::AdminRegion> StatisticsManager::getAdminRegion() {
   return m_adminRegion;
 }
 
diff --git a/cppcache/src/statistics/StatisticsManager.hpp b/cppcache/src/statistics/StatisticsManager.hpp
index d10f4db..cae80ba 100644
--- a/cppcache/src/statistics/StatisticsManager.hpp
+++ b/cppcache/src/statistics/StatisticsManager.hpp
@@ -27,16 +27,21 @@
 #include <geode/ExceptionTypes.hpp>
 #include <geode/internal/geode_globals.hpp>
 
-#include "../AdminRegion.hpp"
 #include "GeodeStatisticsFactory.hpp"
 #include "Statistics.hpp"
 #include "StatisticsTypeImpl.hpp"
 
 namespace apache {
 namespace geode {
-namespace statistics {
 
-using apache::geode::client::AdminRegion;
+namespace client {
+
+class AdminRegion;
+class CacheImpl;
+
+}  // namespace client
+
+namespace statistics {
 
 class GeodeStatisticsFactory;
 class HostStatSampler;
@@ -61,7 +66,7 @@ class StatisticsManager {
   // Mutex to lock the list of Stats
   std::recursive_mutex m_statsListLock;
 
-  std::shared_ptr<AdminRegion> m_adminRegion;
+  std::shared_ptr<client::AdminRegion> m_adminRegion;
 
   std::unique_ptr<GeodeStatisticsFactory> m_statisticsFactory;
 
@@ -73,9 +78,9 @@ class StatisticsManager {
                     client::CacheImpl* cache, int64_t statFileLimit = 0,
                     int64_t statDiskSpaceLimit = 0);
 
-  void RegisterAdminRegion(std::shared_ptr<AdminRegion> adminRegPtr);
+  void RegisterAdminRegion(std::shared_ptr<client::AdminRegion> adminRegPtr);
 
-  std::shared_ptr<AdminRegion> getAdminRegion();
+  std::shared_ptr<client::AdminRegion> getAdminRegion();
 
   void forceSample();
 
diff --git a/cppcache/test/CMakeLists.txt b/cppcache/test/CMakeLists.txt
index 565c8e8..ef7c193 100644
--- a/cppcache/test/CMakeLists.txt
+++ b/cppcache/test/CMakeLists.txt
@@ -48,6 +48,7 @@ add_executable(apache-geode_unittests
   StructSetTest.cpp
   TcrMessageTest.cpp
   ThreadPoolTest.cpp
+  statistics/HostStatSamplerTest.cpp
   util/functionalTests.cpp
   util/JavaModifiedUtf8Tests.cpp
   util/queueTest.cpp
@@ -72,8 +73,6 @@ target_link_libraries(apache-geode_unittests
     GTest::gtest
     GTest::gtest_main
     GTest::gmock
-    Boost::boost
-    Boost::thread
     _WarningsAsError
     _CppCodeCoverage
 )
diff --git a/cppcache/test/QueueConnectionRequestTest.cpp b/cppcache/test/QueueConnectionRequestTest.cpp
index 1aebd6b..6aa11ef 100644
--- a/cppcache/test/QueueConnectionRequestTest.cpp
+++ b/cppcache/test/QueueConnectionRequestTest.cpp
@@ -39,11 +39,13 @@ TEST_F(QueueConnectionRequestTest, testToData) {
   ServerLocation srv("server", 10);
   std::set<ServerLocation> servLoc;
   servLoc.insert(srv);
-  std::string dsName = "dsName";
-  std::string randNum = "randNum";
+  const std::string dsName = "dsName";
+  const std::string randString = "randNum";
+  const std::string hostname = "name";
+  const std::string durableClientId = "id-1";
 
-  ClientProxyMembershipID qCR(dsName, randNum, "name", addr, 10, "id-1",
-                              std::chrono::seconds(0));
+  const ClientProxyMembershipID qCR(dsName, randString, hostname, addr, 10,
+                                    durableClientId);
 
   QueueConnectionRequest queueConnReq(qCR, servLoc, -1, false);
   queueConnReq.toData(dataOutput);
diff --git a/cppcache/test/statistics/HostStatSamplerTest.cpp b/cppcache/test/statistics/HostStatSamplerTest.cpp
new file mode 100644
index 0000000..f3efbd8
--- /dev/null
+++ b/cppcache/test/statistics/HostStatSamplerTest.cpp
@@ -0,0 +1,494 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+
+#include <boost/filesystem.hpp>
+#include <boost/process/environment.hpp>
+
+#include <gtest/gtest.h>
+
+#include "CacheImpl.hpp"
+#include "statistics/HostStatSampler.hpp"
+#include "statistics/StatArchiveWriter.hpp"
+
+using ::testing::Eq;
+using ::testing::IsEmpty;
+using ::testing::IsFalse;
+using ::testing::IsTrue;
+using ::testing::StrEq;
+
+using apache::geode::statistics::HostStatSampler;
+using apache::geode::statistics::StatArchiveWriter;
+
+constexpr size_t kibibyte = 1024;
+constexpr size_t mebibyte = kibibyte * 1024;
+constexpr size_t gibibyte = mebibyte * 1024;
+
+class TestableHostStatSampler : public HostStatSampler {
+ public:
+  explicit TestableHostStatSampler(std::string filePath,
+                                   std::chrono::milliseconds sampleRate,
+                                   size_t statFileLimit,
+                                   size_t statDiskSpaceLimit)
+      : HostStatSampler(filePath, sampleRate, statFileLimit,
+                        statDiskSpaceLimit) {}
+
+  boost::filesystem::path chkForGFSExt(boost::filesystem::path filename) const {
+    return HostStatSampler::chkForGFSExt(filename);
+  }
+
+  boost::filesystem::path initStatFileWithExt() {
+    return HostStatSampler::initStatFileWithExt();
+  }
+
+  void rollArchive(std::string filename) {
+    HostStatSampler::rollArchive(filename);
+  }
+
+  void initStatDiskSpaceEnabled() {
+    HostStatSampler::initStatDiskSpaceEnabled();
+  }
+
+  void initRollIndex() { HostStatSampler::initRollIndex(); }
+
+  int32_t getRollIndex() { return HostStatSampler::m_rollIndex; }
+
+  size_t getSpaceUsed() { return HostStatSampler::m_spaceUsed; }
+};
+
+TEST(HostStatSamplerTest,
+     constructEmptyPathZeroSampleRateZeroFileLimitZeroDiskLimit) {
+  const TestableHostStatSampler hostStatSampler(
+      "", std::chrono::milliseconds::zero(), 0, 0);
+
+  EXPECT_THAT(hostStatSampler.getArchiveFilename(), Eq(""));
+  EXPECT_THAT(hostStatSampler.getSampleRate(),
+              Eq(std::chrono::milliseconds::zero()));
+  EXPECT_THAT(hostStatSampler.getArchiveFileSizeLimit(), Eq(0));
+  EXPECT_THAT(hostStatSampler.getArchiveDiskSpaceLimit(), Eq(0));
+}
+
+TEST(HostStatSamplerTest, constructWithFileLimitOverMax) {
+  const TestableHostStatSampler hostStatSampler(
+      "", std::chrono::milliseconds::zero(), 1025, 0);
+
+  EXPECT_THAT(hostStatSampler.getArchiveFileSizeLimit(), Eq(1 * gibibyte));
+}
+
+TEST(HostStatSamplerTest, constructWithDiskLimitLessThanFileLimit) {
+  const TestableHostStatSampler hostStatSampler(
+      "", std::chrono::milliseconds::zero(), 5, 4);
+
+  EXPECT_THAT(hostStatSampler.getArchiveDiskSpaceLimit(), Eq(4 * mebibyte));
+}
+
+TEST(HostStatSamplerTest, chkForGFSExtWithoutDiskLimit) {
+  const TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 0);
+
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("x.gfs"), Eq("x.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("/tmp/x.gfs"), Eq("/tmp/x.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("x"), Eq("x.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("/tmp/x"), Eq("/tmp/x.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("x.ext"), Eq("x.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("/tmp/x.ext"), Eq("/tmp/x.gfs"));
+}
+
+TEST(HostStatSamplerTest, chkForGFSExtWithDiskSpaceLimit) {
+  const TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 1);
+
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("x.gfs"), Eq("x.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("/tmp/x.gfs"), Eq("/tmp/x.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("x"), Eq("x.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("/tmp/x"), Eq("/tmp/x.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("x.ext"), Eq("x.ext.gfs"));
+  EXPECT_THAT(hostStatSampler.chkForGFSExt("/tmp/x.ext"), Eq("/tmp/x.ext.gfs"));
+}
+
+TEST(HostStatSamplerTest, createArchiveFilenameWithoutDiskSpaceLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 0);
+
+  EXPECT_THAT(
+      hostStatSampler.createArchiveFilename(),
+      Eq("stats-" + std::to_string(boost::this_process::get_id()) + ".gfs"));
+}
+
+TEST(HostStatSamplerTest,
+     createArchiveFilenameWithAlternativeExtensionWithoutDiskSpaceLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.ext", std::chrono::milliseconds::zero(), 0, 0);
+
+  EXPECT_THAT(
+      hostStatSampler.createArchiveFilename(),
+      Eq("stats-" + std::to_string(boost::this_process::get_id()) + ".gfs"));
+}
+
+TEST(HostStatSamplerTest,
+     createArchiveFilenameWithoutExtensionOrDiskSpaceLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats", std::chrono::milliseconds::zero(), 0, 0);
+
+  EXPECT_THAT(
+      hostStatSampler.createArchiveFilename(),
+      Eq("stats-" + std::to_string(boost::this_process::get_id()) + ".gfs"));
+}
+
+TEST(HostStatSamplerTest, createArchiveFilenameWithDiskSpaceLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 1);
+
+  EXPECT_THAT(hostStatSampler.createArchiveFilename(), Eq("stats.gfs"));
+}
+
+TEST(HostStatSamplerTest, initStatFileWithExtWithoutDiskSpaceLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 0);
+
+  EXPECT_THAT(
+      hostStatSampler.initStatFileWithExt(),
+      Eq("stats-" + std::to_string(boost::this_process::get_id()) + ".gfs"));
+}
+
+TEST(HostStatSamplerTest,
+     initStatFileWithExtWithAlternativeExtensionWithoutDiskSpaceLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.ext", std::chrono::milliseconds::zero(), 0, 0);
+
+  EXPECT_THAT(
+      hostStatSampler.initStatFileWithExt(),
+      Eq("stats-" + std::to_string(boost::this_process::get_id()) + ".gfs"));
+}
+
+TEST(HostStatSamplerTest, initStatFileWithExtWithoutExtensionOrDiskSpaceLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats", std::chrono::milliseconds::zero(), 0, 0);
+
+  EXPECT_THAT(
+      hostStatSampler.initStatFileWithExt(),
+      Eq("stats-" + std::to_string(boost::this_process::get_id()) + ".gfs"));
+}
+
+TEST(HostStatSamplerTest, initStatFileWithExtWithDiskSpaceLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 1);
+
+  EXPECT_THAT(hostStatSampler.initStatFileWithExt(), Eq("stats.gfs"));
+}
+
+// TODO integration test
+
+TEST(HostStatSamplerTest, DISABLED_changeArchive) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 0);
+
+  //  const auto archiver = hostStatSampler.getArchiver();
+
+  hostStatSampler.changeArchive("changed.gfs");
+
+  // EXPECT_THAT(hostStatSampler.getArchiver(), Eq(archiver));
+  EXPECT_THAT(hostStatSampler.isRunning(), IsTrue());
+}
+
+TEST(HostStatSamplerTest, rollArchiveFileWithNonexistentFile) {
+  boost::filesystem::path file("nonexistent.gfs");
+  TestableHostStatSampler hostStatSampler(
+      file.string(), std::chrono::milliseconds::zero(), 0, 0);
+
+  boost::filesystem::remove(file);
+  ASSERT_THAT(boost::filesystem::exists(file), IsFalse());
+
+  hostStatSampler.rollArchive(file.string());
+
+  EXPECT_THAT(boost::filesystem::exists(file), IsFalse());
+}
+
+TEST(HostStatSamplerTest, rollArchiveFileWithEmptyFile) {
+  boost::filesystem::path file{"empty.gfs"};
+  TestableHostStatSampler hostStatSampler(
+      file.string(), std::chrono::milliseconds::zero(), 0, 0);
+
+  {
+    boost::filesystem::remove(file);
+    boost::filesystem::ofstream ofs{file};
+  }
+
+  ASSERT_THAT(boost::filesystem::exists(file), IsTrue());
+  ASSERT_THAT(boost::filesystem::is_empty(file), IsTrue());
+
+  hostStatSampler.rollArchive(file.string());
+
+  EXPECT_THAT(boost::filesystem::exists(file), IsTrue());
+  EXPECT_THAT(boost::filesystem::is_empty(file), IsTrue());
+
+  boost::filesystem::remove(file);
+}
+
+TEST(HostStatSamplerTest, rollArchiveFile) {
+  boost::filesystem::path file{"stats.gfs"};
+  boost::filesystem::path file0{"stats-0.gfs"};
+  TestableHostStatSampler hostStatSampler(
+      file.string(), std::chrono::milliseconds::zero(), 0, 0);
+
+  {
+    boost::filesystem::remove(file);
+    boost::filesystem::remove(file0);
+    boost::filesystem::ofstream ofs{file};
+    ofs << "original content";
+  }
+
+  ASSERT_THAT(boost::filesystem::exists(file), IsTrue());
+  ASSERT_THAT(boost::filesystem::is_empty(file), IsFalse());
+  ASSERT_THAT(boost::filesystem::exists(file0), IsFalse());
+
+  hostStatSampler.rollArchive(file.string());
+
+  EXPECT_THAT(boost::filesystem::exists(file), IsFalse());
+  EXPECT_THAT(boost::filesystem::exists(file0), IsTrue());
+  EXPECT_THAT(boost::filesystem::is_empty(file0), IsFalse());
+
+  boost::filesystem::remove(file);
+  boost::filesystem::remove(file0);
+}
+
+TEST(HostStatSamplerTest, rollArchiveFileWithDirectory) {
+  auto file = boost::filesystem::temp_directory_path() / "stats.gfs";
+  auto file0 = boost::filesystem::temp_directory_path() / "stats-0.gfs";
+  TestableHostStatSampler hostStatSampler(
+      file.string(), std::chrono::milliseconds::zero(), 0, 0);
+
+  {
+    boost::filesystem::remove(file);
+    boost::filesystem::remove(file0);
+    boost::filesystem::ofstream ofs{file};
+    ofs << "original content";
+  }
+
+  ASSERT_THAT(boost::filesystem::exists(file), IsTrue());
+  ASSERT_THAT(boost::filesystem::is_empty(file), IsFalse());
+  ASSERT_THAT(boost::filesystem::exists(file0), IsFalse());
+
+  hostStatSampler.rollArchive(file.string());
+
+  EXPECT_THAT(boost::filesystem::exists(file), IsFalse());
+  EXPECT_THAT(boost::filesystem::exists(file0), IsTrue());
+  EXPECT_THAT(boost::filesystem::is_empty(file0), IsFalse());
+
+  boost::filesystem::remove(file);
+  boost::filesystem::remove(file0);
+}
+
+TEST(HostStatSamplerTest, rollArchiveFileWithoutExtensionThrows) {
+  boost::filesystem::path file{"stats"};
+  boost::filesystem::path file0{"stats-0"};
+  TestableHostStatSampler hostStatSampler(
+      file.string(), std::chrono::milliseconds::zero(), 0, 0);
+
+  {
+    boost::filesystem::remove(file);
+    boost::filesystem::remove(file0);
+    boost::filesystem::ofstream ofs{file};
+    ofs << "original content";
+  }
+
+  ASSERT_THAT(boost::filesystem::exists(file), IsTrue());
+  ASSERT_THAT(boost::filesystem::is_empty(file), IsFalse());
+  ASSERT_THAT(boost::filesystem::exists(file0), IsFalse());
+
+  EXPECT_THROW(hostStatSampler.rollArchive(file.string()),
+               apache::geode::client::IllegalArgumentException);
+
+  EXPECT_THAT(boost::filesystem::exists(file), IsTrue());
+  EXPECT_THAT(boost::filesystem::is_empty(file), IsFalse());
+  EXPECT_THAT(boost::filesystem::exists(file0), IsFalse());
+
+  boost::filesystem::remove(file);
+  boost::filesystem::remove(file0);
+}
+
+TEST(HostStatSamplerTest, rollArchiveFileNextFileExists) {
+  boost::filesystem::path file{"stats.gfs"};
+  boost::filesystem::path file0{"stats-0.gfs"};
+  boost::filesystem::path file1{"stats-1.gfs"};
+  TestableHostStatSampler hostStatSampler(
+      file.string(), std::chrono::milliseconds::zero(), 0, 0);
+
+  {
+    boost::filesystem::remove(file);
+    boost::filesystem::remove(file0);
+    boost::filesystem::remove(file1);
+    boost::filesystem::ofstream ofs{file};
+    ofs << "more content";
+    boost::filesystem::ofstream ofs0{file0};
+    ofs0 << "original content";
+  }
+
+  ASSERT_THAT(boost::filesystem::exists(file), IsTrue());
+  ASSERT_THAT(boost::filesystem::is_empty(file), IsFalse());
+  ASSERT_THAT(boost::filesystem::exists(file0), IsTrue());
+  ASSERT_THAT(boost::filesystem::is_empty(file0), IsFalse());
+  ASSERT_THAT(boost::filesystem::exists(file1), IsFalse());
+
+  hostStatSampler.rollArchive(file.string());
+
+  EXPECT_THAT(boost::filesystem::exists(file), IsFalse());
+  EXPECT_THAT(boost::filesystem::exists(file0), IsTrue());
+  EXPECT_THAT(boost::filesystem::is_empty(file0), IsFalse());
+  EXPECT_THAT(boost::filesystem::exists(file1), IsTrue());
+  EXPECT_THAT(boost::filesystem::is_empty(file1), IsFalse());
+
+  boost::filesystem::remove(file);
+  boost::filesystem::remove(file0);
+  boost::filesystem::remove(file1);
+}
+
+TEST(HostStatSamplerTest, initStatDiskSpaceEnabledWithZeroDiskLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 0);
+  hostStatSampler.initStatDiskSpaceEnabled();
+
+  EXPECT_THAT(hostStatSampler.getArchiveFilename(), Eq("stats.gfs"));
+}
+
+TEST(HostStatSamplerTest,
+     DISABLED_initStatDiskSpaceEnabledWithNonzeronDiskLimit) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 1);
+  hostStatSampler.initStatDiskSpaceEnabled();
+
+  EXPECT_THAT(hostStatSampler.getArchiveFilename(), Eq("stats.gfs"));
+}
+
+TEST(
+    HostStatSamplerTest,
+    DISABLED_initStatDiskSpaceEnabledWithNonzeroFileLimitNonzeronDiskLimitAndExistingFile) {
+  boost::filesystem::path file{"stats.gfs"};
+  boost::filesystem::remove(file);
+  { boost::filesystem::ofstream ofs{file}; }
+  boost::filesystem::path file0{"stats-0.gfs"};
+  boost::filesystem::remove(file0);
+
+  TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 1, 1);
+
+  ASSERT_THAT(boost::filesystem::exists(file), IsTrue());
+
+  hostStatSampler.initStatDiskSpaceEnabled();
+
+  EXPECT_THAT(boost::filesystem::exists(file), IsFalse());
+  EXPECT_THAT(boost::filesystem::exists(file0), IsTrue());
+}
+
+TEST(HostStatSamplerTest, initRollIndexNoFiles) {
+  TestableHostStatSampler hostStatSampler(
+      "stats.gfs", std::chrono::milliseconds::zero(), 0, 1);
+  hostStatSampler.initRollIndex();
+
+  EXPECT_THAT(hostStatSampler.getRollIndex(), Eq(0));
+}
+
+TEST(HostStatSamplerTest, initRollIndex2Files) {
+  boost::filesystem::path file{"stats.gfs"};
+  boost::filesystem::path file0{"stats-0.gfs"};
+
+  TestableHostStatSampler hostStatSampler(
+      file.string(), std::chrono::milliseconds::zero(), 0, 1);
+
+  {
+    boost::filesystem::remove(file);
+    boost::filesystem::remove(file0);
+    boost::filesystem::ofstream ofs{file};
+    boost::filesystem::ofstream ofs0{file0};
+  }
+
+  hostStatSampler.initRollIndex();
+
+  EXPECT_THAT(hostStatSampler.getRollIndex(), Eq(1));
+
+  boost::filesystem::remove(file);
+  boost::filesystem::remove(file0);
+}
+
+TEST(HostStatSamplerTest, checkDiskLimitUnderLimit) {
+  boost::filesystem::path file{"stats.gfs"};
+  boost::filesystem::path file0{"stats-0.gfs"};
+
+  TestableHostStatSampler hostStatSampler(
+      file.string(), std::chrono::milliseconds::zero(), 0, 1);
+
+  {
+    boost::filesystem::remove(file);
+    boost::filesystem::remove(file0);
+    boost::filesystem::ofstream ofs{file};
+    ofs << "more content";
+    boost::filesystem::ofstream ofs0{file0};
+    ofs0 << "original content";
+  }
+
+  EXPECT_THAT(boost::filesystem::exists(file), IsTrue());
+  EXPECT_THAT(boost::filesystem::exists(file0), IsTrue());
+  EXPECT_THAT(boost::filesystem::file_size(file0), Eq(16));
+
+  hostStatSampler.checkDiskLimit();
+
+  EXPECT_THAT(hostStatSampler.getSpaceUsed(), Eq(16));
+  EXPECT_THAT(boost::filesystem::exists(file), IsTrue());
+  EXPECT_THAT(boost::filesystem::exists(file0), IsTrue());
+
+  boost::filesystem::remove(file);
+  boost::filesystem::remove(file0);
+}
+
+TEST(HostStatSamplerTest, checkDiskLimitOverLimit) {
+  boost::filesystem::path file{"stats.gfs"};
+  boost::filesystem::path file0{"stats-0.gfs"};
+  boost::filesystem::path file1{"stats-1.gfs"};
+
+  TestableHostStatSampler hostStatSampler(
+      file.string(), std::chrono::milliseconds::zero(), 0, 1);
+
+  {
+    boost::filesystem::remove(file);
+    boost::filesystem::remove(file0);
+    boost::filesystem::ofstream ofs{file};
+    ofs << "more content";
+    boost::filesystem::ofstream ofs0{file0};
+    ofs0 << std::string(1 * mebibyte, 'a');
+    boost::filesystem::ofstream ofs1{file1};
+    ofs1 << std::string(1, 'a');
+  }
+
+  EXPECT_THAT(boost::filesystem::exists(file), IsTrue());
+  EXPECT_THAT(boost::filesystem::exists(file0), IsTrue());
+  EXPECT_THAT(boost::filesystem::file_size(file0), Eq(1 * mebibyte));
+  EXPECT_THAT(boost::filesystem::exists(file1), IsTrue());
+  EXPECT_THAT(boost::filesystem::file_size(file1), Eq(1));
+
+  hostStatSampler.checkDiskLimit();
+
+  EXPECT_THAT(hostStatSampler.getSpaceUsed(), Eq(1));
+  EXPECT_THAT(boost::filesystem::exists(file), IsTrue());
+  EXPECT_THAT(boost::filesystem::exists(file0), IsFalse());
+  EXPECT_THAT(boost::filesystem::exists(file1), IsTrue());
+  //  EXPECT_THAT(boost::filesystem::file_size(file1), Eq(1));
+
+  boost::filesystem::remove(file);
+  boost::filesystem::remove(file0);
+  boost::filesystem::remove(file1);
+}