From 57caed2829335ced7e99e835eb4002a6b293db38 Mon Sep 17 00:00:00 2001
From: Eric Cano <Eric.Cano@cern.ch>
Date: Fri, 27 Oct 2017 16:19:44 +0200
Subject: [PATCH] In preparation for async garbage collection, made the
 GenericObject more standard.

This allows previously developped asyncLockfreeFetch to apply to it.
---
 objectstore/GenericObject.cpp | 33 ++++++++++++++++++---------------
 objectstore/GenericObject.hpp | 10 +++++++---
 objectstore/ObjectOps.hpp     |  8 ++++----
 3 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/objectstore/GenericObject.cpp b/objectstore/GenericObject.cpp
index 9cdf1f0636..3edfca13d6 100644
--- a/objectstore/GenericObject.cpp
+++ b/objectstore/GenericObject.cpp
@@ -32,27 +32,29 @@
 
 namespace cta {  namespace objectstore {
 
-void GenericObject::fetch() {
-  // Check that the object is locked, one way or another
-  if(!m_locksCount)
-    throw NotLocked("In ObjectOps::fetch(): object not locked");
-  m_existingObject = true;
-  // Get the header from the object store. We don't care for the type
-  auto objData=m_objectStore.read(getAddressIfSet());
+serializers::ObjectType GenericObject::type() {
+  checkHeaderReadable();
+  return m_header.type();
+}
+
+void GenericObject::getHeaderFromObjectData(const std::string& objData) {
   if (!m_header.ParseFromString(objData)) {
-    // Use a the tolerant parser to assess the situation.
+    // Use the tolerant parser to assess the situation.
     m_header.ParsePartialFromString(objData);
-    throw cta::exception::Exception(std::string("In GenericObject::fetch: could not parse header: ") + 
-      m_header.InitializationErrorString());
+    // Base64 encode the header for diagnostics.
+    const bool noNewLineInBase64Output = false;
+    std::string objDataBase64;
+    CryptoPP::StringSource ss1(objData, true,
+      new CryptoPP::Base64Encoder(
+         new CryptoPP::StringSink(objDataBase64), noNewLineInBase64Output));
+    throw cta::exception::Exception(std::string("In <GenericObject::getHeaderFromObjectData(): could not parse header: ") + 
+            m_header.InitializationErrorString() + 
+            " size=" + std::to_string(objData.size()) + " data(b64)=\"" + 
+            objDataBase64 + "\"");
   }
   m_headerInterpreted = true;
 }
 
-serializers::ObjectType GenericObject::type() {
-  checkHeaderReadable();
-  return m_header.type();
-}
-
 void GenericObject::commit() {
   checkHeaderWritable();
   m_objectStore.atomicOverwrite(getAddressIfSet(), m_header.SerializeAsString());
@@ -72,6 +74,7 @@ void GenericObject::transplantHeader(ObjectOpsBase& destination) {
   destination.m_headerInterpreted = m_headerInterpreted;
   destination.m_name = m_name;
   destination.m_nameSet = m_nameSet;
+  destination.m_noLock = m_noLock;
   destination.m_payloadInterpreted = false;
 }
 
diff --git a/objectstore/GenericObject.hpp b/objectstore/GenericObject.hpp
index 597b25ac0b..45e6320ce1 100644
--- a/objectstore/GenericObject.hpp
+++ b/objectstore/GenericObject.hpp
@@ -30,9 +30,13 @@ public:
     
   CTA_GENERATE_EXCEPTION_CLASS(ForbiddenOperation);
   
-  /** Overload of ObjectOps's implementation: this special object tolerates all
-   * types of objects */
-  void fetch();
+  /** This object has a special, relaxed version of header parsing as all types
+   * of objects are accepted here. */
+  void getHeaderFromObjectData(const std::string& objData) override;
+
+  /** Overload of ObjectOps's implementation: this special object does not really 
+   parse its payload */
+  void getPayloadFromHeader() override {}
   
   /** Overload of ObjectOps's implementation: we will leave the payload transparently
    * untouched and only deal with header parameters */
diff --git a/objectstore/ObjectOps.hpp b/objectstore/ObjectOps.hpp
index b5b6dd2426..a88ea5f7a6 100644
--- a/objectstore/ObjectOps.hpp
+++ b/objectstore/ObjectOps.hpp
@@ -355,7 +355,7 @@ public:
   
 protected:
   
-  void getPayloadFromHeader () {
+  virtual void getPayloadFromHeader () {
     if (!m_payload.ParseFromString(m_header.payload())) {
       // Use the tolerant parser to assess the situation.
       m_header.ParsePartialFromString(m_header.payload());
@@ -373,7 +373,7 @@ protected:
     m_payloadInterpreted = true;
   }
   
-  void getHeaderFromObjectData(const std::string & objData) {
+  virtual void getHeaderFromObjectData(const std::string & objData) {
     if (!m_header.ParseFromString(objData)) {
       // Use the tolerant parser to assess the situation.
       m_header.ParsePartialFromString(objData);
@@ -383,8 +383,8 @@ protected:
       CryptoPP::StringSource ss1(objData, true,
         new CryptoPP::Base64Encoder(
            new CryptoPP::StringSink(objDataBase64), noNewLineInBase64Output));
-      throw cta::exception::Exception(std::string("In <ObjectOps") + typeid(PayloadType).name() + 
-              ">::getHeaderFromObjectStore(): could not parse header: " + m_header.InitializationErrorString() + 
+      throw cta::exception::Exception(std::string("In ObjectOps<") + typeid(PayloadType).name() + 
+              ">::getHeaderFromObjectData(): could not parse header: " + m_header.InitializationErrorString() + 
               " size=" + std::to_string(objData.size()) + " data(b64)=\"" + 
               objDataBase64 + "\"");
     }
-- 
GitLab