GEODE-2408: Refactor CacheableDate with C++11 standards.

Project: http://git-wip-us.apache.org/repos/asf/geode-native/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode-native/commit/1d16b3be
Tree: http://git-wip-us.apache.org/repos/asf/geode-native/tree/1d16b3be
Diff: http://git-wip-us.apache.org/repos/asf/geode-native/diff/1d16b3be

Branch: refs/heads/develop
Commit: 1d16b3be249693b7bd5bf4422445a0635c9d1379
Parents: 24cbfd3
Author: Jacob Barrett <[email protected]>
Authored: Mon Dec 5 17:52:31 2016 -0800
Committer: Jacob Barrett <[email protected]>
Committed: Mon Feb 13 13:41:41 2017 -0800

----------------------------------------------------------------------
 src/cppcache/include/gfcpp/CacheableDate.hpp | 184 ++++++++++++++++------
 src/cppcache/include/gfcpp/gfcpp_globals.hpp |  10 ++
 src/cppcache/src/CacheableDate.cpp           | 143 +++++++++--------
 3 files changed, 224 insertions(+), 113 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode-native/blob/1d16b3be/src/cppcache/include/gfcpp/CacheableDate.hpp
----------------------------------------------------------------------
diff --git a/src/cppcache/include/gfcpp/CacheableDate.hpp 
b/src/cppcache/include/gfcpp/CacheableDate.hpp
index 0686550..5b465ee 100644
--- a/src/cppcache/include/gfcpp/CacheableDate.hpp
+++ b/src/cppcache/include/gfcpp/CacheableDate.hpp
@@ -26,15 +26,14 @@
 #include "CacheableString.hpp"
 #include "GeodeTypeIds.hpp"
 #include "ExceptionTypes.hpp"
+
+#include <string>
+#include <chrono>
 #include <time.h>
 #ifdef _WIN32
-#include <WinSock2.h>  //for struct timeval
-#define GF_LOCALTIME(X, Y) localtime_s(Y, X)
+#include <WinSock2.h> // timeval
 #else
-#include <sys/time.h>
-#if defined(_LINUX) || defined(_SOLARIS) || defined(_MACOSX)
-#define GF_LOCALTIME(X, Y) localtime_r(X, Y)
-#endif
+#include <sys/time.h> // timeval
 #endif
 
 /** @file
@@ -44,108 +43,205 @@ namespace geode {
 namespace client {
 
 /**
- * Implement a date object based on system epoch that can serve as a
+ * Implement a date object based on epoch of January 1, 1970 00:00:00 GMT that 
can serve as a
  * distributable key object for caching as well as being a date value.
  */
-class CPPCACHE_EXPORT CacheableDate : public CacheableKey {
- private:
-  struct timeval m_timevalue;
-  uint32_t m_hash;
+class CPPCACHE_EXPORT CacheableDate
+  : public CacheableKey
+{
+  private:
+
+    /**
+     * Milliseconds since January 1, 1970, 00:00:00 GMT to be consistent with 
Java Date.
+     */
+    int64_t m_timevalue;
+
+  public:
+    typedef std::chrono::system_clock clock;
+    typedef std::chrono::time_point<clock> time_point;
+    typedef std::chrono::milliseconds duration;
 
- public:
   /**
-   *@brief serialize this object
+   * @brief serialize this object
    **/
-  virtual void toData(DataOutput& output) const;
+  virtual void toData( DataOutput& output ) const;
 
   /**
-   *@brief deserialize this object
+   * @brief deserialize this object
    **/
-  virtual Serializable* fromData(DataInput& input);
+  virtual Serializable* fromData( DataInput& input );
 
   /**
    * @brief creation function for dates.
    */
-  static Serializable* createDeserializable();
+  static Serializable* createDeserializable( );
 
   /**
-   *@brief Return the classId of the instance being serialized.
+   * @brief Return the classId of the instance being serialized.
    * This is used by deserialization to determine what instance
    * type to create and deserialize into.
    */
-  virtual int32_t classId() const;
+  virtual int32_t classId( ) const;
 
   /**
    *@brief return the typeId byte of the instance being serialized.
    * This is used by deserialization to determine what instance
    * type to create and deserialize into.
    */
-  virtual int8_t typeId() const;
+  virtual int8_t typeId( ) const;
 
   /** @return the size of the object in bytes */
-  virtual uint32_t objectSize() const { return sizeof(CacheableDate); }
+  virtual uint32_t objectSize() const {
+    return sizeof(CacheableDate);
+  }
 
   /** @return true if this key matches other. */
-  virtual bool operator==(const CacheableKey& other) const;
+  virtual bool operator==( const CacheableKey& other ) const;
 
-  /** @return day of the month. */
+  /**
+   * @return day of the month.
+   * @deprecated Use localtime or similar for calendar conversions.
+   */
+  __DEPRECATED__("Use localtime or similar for calendar conversions.")
   virtual int day() const;
 
-  /** @return month 1(Jan) - 12(Dec) . */
+  /**
+   * @return month 1(Jan) - 12(Dec) .
+   * @deprecated Use localtime or similar for calendar conversions.
+   */
+  __DEPRECATED__("Use localtime or similar for calendar conversions.")
   virtual int month() const;
 
-  /** @return year, example 1999. */
+  /**
+   * @return year, example 1999.
+   * @deprecated Use localtime or similar for calendar conversions.
+   */
+  __DEPRECATED__("Use localtime or similar for calendar conversions.")
   virtual int year() const;
 
-  /** @return milliseconds elapsed as per epoch time. */
+  /** @return milliseconds elapsed since January 1, 1970, 00:00:00 GMT. */
   virtual int64_t milliseconds() const;
 
-  /** @return the hashcode for this key. */
+  /**
+   * Returns a hash code value for this object. The result is the exclusive OR
+   * of the two halves of the primitive long value returned by the 
milliseconds()
+   * method.
+   *
+   * @return the hashcode for this object. */
   virtual uint32_t hashcode() const;
 
+  operator time_t() const { return m_timevalue / 1000; }
+  operator time_point() const { return clock::from_time_t(0) + 
duration(m_timevalue); }
+  operator duration() const { return duration(m_timevalue); }
+
   /**
    * Factory method for creating an instance of CacheableDate
    */
-  static CacheableDatePtr create() {
+  static CacheableDatePtr create( )
+  {
     return CacheableDatePtr(new CacheableDate());
   }
 
-  static CacheableDatePtr create(const time_t& value) {
+  static CacheableDatePtr create( const time_t& value )
+  {
+    return CacheableDatePtr(new CacheableDate(value));
+  }
+
+  static CacheableDatePtr create( const time_point& value )
+  {
     return CacheableDatePtr(new CacheableDate(value));
   }
 
-  static CacheableDatePtr create(const timeval& value) {
+  static CacheableDatePtr create( const duration& value )
+  {
     return CacheableDatePtr(new CacheableDate(value));
   }
 
-  virtual CacheableStringPtr toString() const;
+  /**
+   * @deprecated Use other standard time types.
+   */
+  __DEPRECATED__("Use other standard time types.")
+  static CacheableDatePtr create( const timeval& value )
+  {
+    return CacheableDatePtr(new CacheableDate(toDuration(value)));
+  }
+
+  virtual CacheableStringPtr toString( ) const;
 
   /** Destructor */
-  virtual ~CacheableDate();
+  virtual ~CacheableDate( );
 
   /** used to render as a string for logging. */
-  virtual int32_t logString(char* buffer, int32_t maxLength) const;
+  virtual int32_t logString( char* buffer, int32_t maxLength ) const;
+
+  protected:
+
+  /** Constructor, given a timeval value.
+   *
+   * @deprecated Use other constructors.
+   */
+  __DEPRECATED__("Use other standard time types.")
+  CacheableDate( const timeval& value );
 
- protected:
-  /** Constructor, given a timeval value. */
-  CacheableDate(const timeval& value);
 
   /** Constructor, used for deserialization. */
-  CacheableDate(const time_t value = 0);
+  CacheableDate( const time_t value = 0 );
+
+  /**
+   * Construct from std::chrono::time_point<std::chrono::system_clock>.
+   */
+  CacheableDate( const time_point& value );
+
+  /**
+   * Construct from std::chrono::seconds since POSIX epoch.
+   */
+  CacheableDate( const duration& value );
+
+  private:
 
- private:
   // never implemented.
-  void operator=(const CacheableDate& other);
-  CacheableDate(const CacheableDate& other);
+  void operator=( const CacheableDate& other );
+  CacheableDate( const CacheableDate& other );
+
+  static duration toDuration(const timeval& value) {
+    return std::chrono::duration_cast<CacheableDate::duration>(
+        std::chrono::seconds(value.tv_sec) +
+        std::chrono::microseconds(value.tv_usec));
+  }
+
+  public:
+  friend CacheableKeyPtr createKey( const timeval& value );
+  friend CacheablePtr createValue( const timeval& value );
 };
 
-inline CacheableKeyPtr createKey(const timeval& value) {
-  return CacheableKeyPtr(CacheableDate::create(value));
+/**
+ * @deprecated Use other standard time types.
+ */
+__DEPRECATED__("Use other standard time types.")
+inline CacheableKeyPtr createKey( const timeval& value )
+{
+  return CacheableKeyPtr( CacheableDate::create( 
CacheableDate::toDuration(value) ) );
+}
+
+/**
+ * @deprecated Use other standard time types.
+ */
+__DEPRECATED__("Use other standard time types.")
+inline CacheablePtr createValue( const timeval& value )
+{
+  return CacheablePtr( CacheableDate::create( CacheableDate::toDuration(value) 
) );
 }
 
-inline CacheablePtr createValue(const timeval& value) {
-  return CacheablePtr(CacheableDate::create(value));
+inline CacheableKeyPtr createKey( const CacheableDate::time_point& value )
+{
+  return CacheableKeyPtr( CacheableDate::create( value ) );
 }
+
+inline CacheablePtr createValue( const CacheableDate::time_point& value )
+{
+  return CacheablePtr( CacheableDate::create( value ) );
+}
+
 }  // namespace client
 }  // namespace geode
 }  // namespace apache

http://git-wip-us.apache.org/repos/asf/geode-native/blob/1d16b3be/src/cppcache/include/gfcpp/gfcpp_globals.hpp
----------------------------------------------------------------------
diff --git a/src/cppcache/include/gfcpp/gfcpp_globals.hpp 
b/src/cppcache/include/gfcpp/gfcpp_globals.hpp
index e2ccdaf..712fd59 100644
--- a/src/cppcache/include/gfcpp/gfcpp_globals.hpp
+++ b/src/cppcache/include/gfcpp/gfcpp_globals.hpp
@@ -92,6 +92,16 @@
 
 #endif
 
+#if defined(__has_cpp_attribute) && __has_cpp_attribute(deprecated)
+#define __DEPRECATED__(msg) [[deprecated(msg)]]
+#elif defined(__GNUC__)
+#define __DEPRECATED__(msg) __attribute__(deprecated(msg))
+#elif defined(_MSC_VER)
+#define __DEPRECATED__(msg) __declspec(deprecated(msg))
+#else
+#define __DEPRECATED__(msg)
+#endif
+
 #ifdef _WIN32
 #if WINVER == 0x0500
 #endif

http://git-wip-us.apache.org/repos/asf/geode-native/blob/1d16b3be/src/cppcache/src/CacheableDate.cpp
----------------------------------------------------------------------
diff --git a/src/cppcache/src/CacheableDate.cpp 
b/src/cppcache/src/CacheableDate.cpp
index 602b5f9..d208b43 100644
--- a/src/cppcache/src/CacheableDate.cpp
+++ b/src/cppcache/src/CacheableDate.cpp
@@ -26,27 +26,27 @@
 #include <cwchar>
 #include <ace/OS.h>
 
+#include <chrono>
+#include <time.h>
+#ifdef _WIN32
+#include <WinSock2.h>  // timeval
+#else
+#include <sys/time.h>  // timeval
+#endif
+
 namespace apache {
 namespace geode {
 namespace client {
 
+static CacheableDate::time_point posixEpoch =
+    CacheableDate::clock::from_time_t(0);
+
 void CacheableDate::toData(DataOutput& output) const {
-  int64_t msec = static_cast<int64_t>(m_timevalue.tv_sec);
-  msec *= 1000;
-  msec += (m_timevalue.tv_usec / 1000);
-  output.writeInt(msec);
+  output.writeInt(m_timevalue);
 }
 
 Serializable* CacheableDate::fromData(DataInput& input) {
-  m_hash = 0;
-  int64_t msec;
-  input.readInt(&msec);
-
-  // GF_D_ASSERT( sizeof(time_t)!=4 || (msec/1000)==(time_t)(msec/1000) );
-
-  m_timevalue.tv_sec = static_cast<long>(msec / 1000);
-  m_timevalue.tv_usec = (static_cast<suseconds_t>(msec % 1000) * 1000);
-
+  input.readInt(&m_timevalue);
   return this;
 }
 
@@ -56,90 +56,95 @@ Serializable* CacheableDate::createDeserializable() {
 
 int32_t CacheableDate::classId() const { return 0; }
 
-int8_t CacheableDate::typeId() const { return GeodeTypeIds::CacheableDate; }
+int8_t CacheableDate::typeId() const { return GemfireTypeIds::CacheableDate; }
 
 bool CacheableDate::operator==(const CacheableKey& other) const {
-  if (other.typeId() != GeodeTypeIds::CacheableDate) {
+  if (other.typeId() != GemfireTypeIds::CacheableDate) {
     return false;
   }
 
   const CacheableDate& otherDt = static_cast<const CacheableDate&>(other);
 
-  return ((m_timevalue.tv_sec == otherDt.m_timevalue.tv_sec) &&
-          (m_timevalue.tv_usec == otherDt.m_timevalue.tv_usec));
+  return m_timevalue == otherDt.m_timevalue;
 }
-int CacheableDate::day() const {
-  struct tm date = {0};
-  time_t sec = m_timevalue.tv_sec;
-  GF_LOCALTIME(&sec, &date);
+
+int CacheableDate::day() const 
+{ 
+  struct tm date = { 0 };
+  time_t sec = m_timevalue / 1000;
+  ACE_OS::localtime_r( &sec, &date );
   return date.tm_mday;
 }
 
-int CacheableDate::month() const {
-  struct tm date = {0};
-  time_t sec = m_timevalue.tv_sec;
-  GF_LOCALTIME(&sec, &date);
-  return date.tm_mon + 1;
+int CacheableDate::month() const 
+{ 
+  struct tm date = { 0 };
+  time_t sec = m_timevalue / 1000;
+  ACE_OS::localtime_r( &sec, &date );
+  return date.tm_mon + 1; 
 }
 
-int CacheableDate::year() const {
-  struct tm date = {0};
-  time_t sec = m_timevalue.tv_sec;
-  GF_LOCALTIME(&sec, &date);
-  return date.tm_year + 1900;
+int CacheableDate::year() const 
+{ 
+  struct tm date = { 0 };
+  time_t sec = m_timevalue / 1000;
+  ACE_OS::localtime_r( &sec, &date );
+  return date.tm_year + 1900; 
 }
 
-int64_t CacheableDate::milliseconds() const {
-  int64_t tmp = 0;
-  tmp = static_cast<int64_t>(m_timevalue.tv_sec);
-  tmp *= 1000;
-  tmp += (m_timevalue.tv_usec / 1000);
-  return tmp;
+int64_t CacheableDate::milliseconds() const
+{
+  return m_timevalue;
 }
 
-uint32_t CacheableDate::hashcode() const {
-  if (m_hash == 0) {
-    CacheableDate* self = const_cast<CacheableDate*>(this);
-    int64_t hash = self->milliseconds();
-    self->m_hash = static_cast<int>(hash) ^ static_cast<int>(hash >> 32);
-  }
-  return m_hash;
+uint32_t CacheableDate::hashcode( ) const
+{
+  return (int) m_timevalue ^ (int) (m_timevalue >> 32);
 }
 
-CacheableDate::CacheableDate(const timeval& value) : m_hash(0) {
-  m_timevalue = value;
+CacheableDate::CacheableDate( const timeval& value )
+{ 
+  m_timevalue = (((int64_t) value.tv_sec) * 1000) + (value.tv_usec / 1000);
 }
 
-CacheableDate::CacheableDate(const time_t value) : m_hash(0) {
-  m_timevalue.tv_sec = static_cast<long>(value);
-  m_timevalue.tv_usec = 0;
+CacheableDate::CacheableDate( const time_t value )
+{
+  m_timevalue = ((int64_t) value) * 1000;
 }
 
-CacheableDate::~CacheableDate() {
-  m_hash = 0;
-  m_timevalue.tv_sec = 0;
-  m_timevalue.tv_usec = 0;
+CacheableDate::CacheableDate(const CacheableDate::time_point& value) {
+  // Set based on time since local system clock epoch plus time since POSIX
+  // epoch since local system clock epoch to get milliseconds since POSIX 
epoch.
+  m_timevalue =
+      std::chrono::duration_cast<CacheableDate::duration>(value - posixEpoch)
+          .count();
+}
+
+CacheableDate::CacheableDate(const CacheableDate::duration& value) {
+  m_timevalue = value.count();
+}
+
+CacheableDate::~CacheableDate( )
+{
 }
 
 CacheableStringPtr CacheableDate::toString() const {
   char buffer[25];
-  struct tm date = {0};
-  time_t sec = m_timevalue.tv_sec;
-  GF_LOCALTIME(&sec, &date);
-  ACE_OS::snprintf(buffer, 24, "%d/%d/%d %d:%d:%d", date.tm_mon + 1,
-                   date.tm_mday, date.tm_year + 1900, date.tm_hour, 
date.tm_min,
-                   date.tm_sec);
-  return CacheableString::create(buffer);
-}
-
-int32_t CacheableDate::logString(char* buffer, int32_t maxLength) const {
-  struct tm date = {0};
-  time_t sec = m_timevalue.tv_sec;
-  GF_LOCALTIME(&sec, &date);
-  return ACE_OS::snprintf(buffer, maxLength,
-                          "CacheableDate (mm/dd/yyyy) ( %d/%d/%d )",
-                          date.tm_mon + 1, date.tm_mday, date.tm_year + 1900);
+  struct tm date = { 0 };
+  time_t sec = m_timevalue / 1000;
+  ACE_OS::localtime_r(&sec, &date);
+  ACE_OS::snprintf(buffer, 24, "%d/%d/%d %d:%d:%d", date.tm_mon+1, 
date.tm_mday, date.tm_year+1900, date.tm_hour, date.tm_min, date.tm_sec);
+  return CacheableString::create( buffer );
 }
+
+int32_t CacheableDate::logString( char* buffer, int32_t maxLength ) const
+{
+  struct tm date = { 0 };
+  time_t sec = m_timevalue / 1000;
+  ACE_OS::localtime_r(&sec, &date);
+  return ACE_OS::snprintf( buffer, maxLength, "CacheableDate (mm/dd/yyyy) ( 
%d/%d/%d )", date.tm_mon+1, date.tm_mday, date.tm_year+1900 );
+}
+
 }  // namespace client
 }  // namespace geode
 }  // namespace apache

Reply via email to