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