summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/MetadataSerializable.hpp
diff options
context:
space:
mode:
authorMark Rowe <mrowe@bdash.net.nz>2024-11-13 15:48:14 -0800
committerkat <kat@vector35.com>2024-12-10 10:39:14 -0500
commitce88a94adc42807f1cda3b97a7fa8f16320d48a8 (patch)
tree30bd98dc08dff4cf494c202de01fa7d1d0fc0eed /view/sharedcache/core/MetadataSerializable.hpp
parenta371d925e2957c2dd7adf9722a803e7bf7fba4e1 (diff)
[SharedCache] Rework metadata serialization to reduce memory overhead
api/MetadataSerializable.hpp is removed in favor of including core/MetadataSerializable.hpp. Both headers defined types with the same name leading to One Definition Rule violations and surprising behavior. The serialization and deserialization context are now created on-demand during serialization rather than being a member of `MetadataSerializable`. This reduces the size of every serializable object by ~220 bytes. The context is passed explicitly as an argument to `Serialize` / `Deserialize`. As a result, `Serialize` / `Deserialize` can now be free functions rather than member functions. Since `MetadataSerializable` is not used for dynamic dispatch, the virtual methods are removed and the class is updated to be a class template using CRTP. This allows delegating to the derived class's `Load` and `Store` methods without the additional size overhead of the vtable pointer in every serializable object. These changes reduce the memory footprint of Binary Ninja after loading the macOS shared cache and loading a single dylib from it from 8.3GB to 4.6GB.
Diffstat (limited to 'view/sharedcache/core/MetadataSerializable.hpp')
-rw-r--r--view/sharedcache/core/MetadataSerializable.hpp816
1 files changed, 399 insertions, 417 deletions
diff --git a/view/sharedcache/core/MetadataSerializable.hpp b/view/sharedcache/core/MetadataSerializable.hpp
index c49a9e8c..1b7a03d0 100644
--- a/view/sharedcache/core/MetadataSerializable.hpp
+++ b/view/sharedcache/core/MetadataSerializable.hpp
@@ -12,15 +12,17 @@
*
* Great news.
*
- * Implement these on your `public MetadataSerializable` subclass:
+ * Implement these on your `public MetadataSerializable<T>` subclass:
* ```
- void Store() override {
- MSS(m_someVariable);
- MSS(m_someOtherVariable);
- }
- void Load() override {
- MSL(m_someVariable);
- MSL(m_someOtherVariable);
+ class MyClass : public MetadataSerializable<MyClass> {
+ void Store(SerializationContext& context) const {
+ MSS(m_someVariable);
+ MSS(m_someOtherVariable);
+ }
+ void Load(DeserializationContext& context) {
+ MSL(m_someVariable);
+ MSL(m_someOtherVariable);
+ }
}
```
* Then, you can turn your object into a Metadata object with `AsMetadata()`, and load it back with
@@ -37,501 +39,481 @@
#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
-#ifndef SHAREDCACHE_METADATASERIALIZABLE_HPP
-#define SHAREDCACHE_METADATASERIALIZABLE_HPP
+#ifndef SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP
+#define SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP
+
+namespace SharedCacheCore {
-#define MSS(name) store(#name, name)
-#define MSS_CAST(name, type) store(#name, (type) name)
-#define MSS_SUBCLASS(name) Serialize(#name, name)
-#define MSL(name) name = load(#name, name)
-#define MSL_CAST(name, storedType, type) name = (type)load(#name, (storedType) name)
-#define MSL_SUBCLASS(name) Deserialize(#name, name)
+#define MSS(name) context.store(#name, name)
+#define MSS_CAST(name, type) context.store(#name, (type) name)
+#define MSS_SUBCLASS(name) Serialize(context, #name, name)
+#define MSL(name) name = context.load<decltype(name)>(#name)
+#define MSL_CAST(name, storedType, type) name = (type)context.load<storedType>(#name)
+#define MSL_SUBCLASS(name) Deserialize(context, #name, name)
using namespace BinaryNinja;
-class MetadataSerializable
-{
-protected:
- struct SerialContext
- {
- rapidjson::Document doc;
- rapidjson::Document::AllocatorType allocator;
- };
- struct DeserContext
- {
- rapidjson::Document doc;
- };
+struct DeserializationContext;
- DeserContext m_activeDeserContext;
- SerialContext m_activeContext;
+struct SerializationContext {
+ rapidjson::Document doc;
+ rapidjson::Document::AllocatorType allocator;
-public:
- MetadataSerializable()
- {
- m_activeContext.doc.SetObject();
- m_activeContext.allocator = m_activeContext.doc.GetAllocator();
+ SerializationContext() {
+ doc.SetObject();
+ allocator = doc.GetAllocator();
}
- // copy constructor
- MetadataSerializable(const MetadataSerializable& other)
+ template <typename T>
+ void store(std::string_view x, const T& y)
{
- m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator());
+ Serialize(*this, x, y);
}
+};
- // copy assignment
- MetadataSerializable& operator=(const MetadataSerializable& other)
- {
- m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator());
- return *this;
- }
+struct DeserializationContext {
+ rapidjson::Document doc;
- virtual ~MetadataSerializable()
+ template <typename T>
+ T load(std::string_view x)
{
+ T value;
+ Deserialize(*this, x, value);
+ return value;
}
+};
- void SetupSerContext(rapidjson::Document::AllocatorType* alloc = nullptr)
- {
- m_activeContext.doc.SetObject();
- m_activeContext.allocator = m_activeContext.doc.GetAllocator();
- }
- void S()
- {
- // fixme factor out
- }
- void Serialize(std::string& name, bool b)
+template <typename Derived>
+class MetadataSerializable
+{
+public:
+ std::string AsString() const
{
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, b, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, bool& b) { b = m_activeDeserContext.doc[name.c_str()].GetBool(); }
+ rapidjson::StringBuffer strbuf;
+ rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strbuf);
+ AsDocument().Accept(writer);
- void Serialize(std::string& name, uint8_t b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, b, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, uint8_t& b)
- {
- b = static_cast<uint8_t>(m_activeDeserContext.doc[name.c_str()].GetUint64());
+ return strbuf.GetString();
}
- void Serialize(std::string& name, uint16_t b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, b, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, uint16_t& b)
- {
- b = static_cast<uint16_t>(m_activeDeserContext.doc[name.c_str()].GetUint64());
+ rapidjson::Document AsDocument() const {
+ SerializationContext context;
+ AsDerived().Store(context);
+ return std::move(context.doc);
}
- void Serialize(std::string& name, uint32_t b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, b, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, uint32_t& b)
+ void LoadFromString(const std::string& s)
{
- b = static_cast<uint32_t>(m_activeDeserContext.doc[name.c_str()].GetUint64());
+ DeserializationContext context;
+ context.doc.Parse(s.c_str());
+ AsDerived().Load(context);
}
- void Serialize(std::string& name, uint64_t b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, b, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, uint64_t& b)
+ void LoadFromValue(rapidjson::Value& s)
{
- b = m_activeDeserContext.doc[name.c_str()].GetUint64();
+ DeserializationContext context;
+ context.doc.CopyFrom(s, context.doc.GetAllocator());
+ AsDerived().Load(context);
}
- void Serialize(std::string& name, int8_t b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, b, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, int8_t& b)
- {
- b = m_activeDeserContext.doc[name.c_str()].GetInt64();
- }
+ Ref<Metadata> AsMetadata() { return new Metadata(AsString()); }
- void Serialize(std::string& name, int16_t b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, b, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, int16_t& b)
+ bool LoadFromMetadata(const Ref<Metadata>& meta)
{
- b = m_activeDeserContext.doc[name.c_str()].GetInt64();
+ if (!meta->IsString())
+ return false;
+ LoadFromString(meta->GetString());
+ return true;
}
- void Serialize(std::string& name, int32_t b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, b, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, int32_t& b)
- {
- b = m_activeDeserContext.doc[name.c_str()].GetInt();
- }
+private:
+ const Derived& AsDerived() const { return static_cast<const Derived&>(*this); }
+ Derived& AsDerived() { return static_cast<Derived&>(*this); }
+};
- void Serialize(std::string& name, int64_t b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, b, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, int64_t& b)
- {
- b = m_activeDeserContext.doc[name.c_str()].GetInt64();
- }
+inline void Serialize(SerializationContext& context, std::string_view name, bool b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ context.doc.AddMember(key, b, context.allocator);
+}
- void Serialize(std::string& name, std::string b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value value(b.c_str(), m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, value, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, std::string& b)
- {
- b = m_activeDeserContext.doc[name.c_str()].GetString();
- }
+inline void Deserialize(DeserializationContext& context, std::string_view name, bool& b) {
+ b = context.doc[name.data()].GetBool();
+}
- void Serialize(std::string& name, std::map<uint64_t, std::string> b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& i : b)
- {
- rapidjson::Value p(rapidjson::kArrayType);
- p.PushBack(i.first, m_activeContext.allocator);
- rapidjson::Value value(i.second.c_str(), m_activeContext.allocator);
- p.PushBack(value, m_activeContext.allocator);
- bArr.PushBack(p, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, std::map<uint64_t, std::string>& b)
- {
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
- b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString();
- }
+inline void Serialize(SerializationContext& context, std::string_view name, uint8_t b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ context.doc.AddMember(key, b, context.allocator);
+}
- void Serialize(std::string& name, std::unordered_map<uint64_t, std::string> b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& i : b)
- {
- rapidjson::Value p(rapidjson::kArrayType);
- p.PushBack(i.first, m_activeContext.allocator);
- rapidjson::Value value(i.second.c_str(), m_activeContext.allocator);
- p.PushBack(value, m_activeContext.allocator);
- bArr.PushBack(p, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
+inline void Deserialize(DeserializationContext& context, std::string_view name, uint8_t& b)
+{
+ b = static_cast<uint8_t>(context.doc[name.data()].GetUint64());
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, uint16_t b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ context.doc.AddMember(key, b, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, uint16_t& b)
+{
+ b = static_cast<uint16_t>(context.doc[name.data()].GetUint64());
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, uint32_t b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ context.doc.AddMember(key, b, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, uint32_t& b)
+{
+ b = static_cast<uint32_t>(context.doc[name.data()].GetUint64());
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, uint64_t b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ context.doc.AddMember(key, b, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, uint64_t& b)
+{
+ b = context.doc[name.data()].GetUint64();
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, int8_t b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ context.doc.AddMember(key, b, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, int8_t& b)
+{
+ b = context.doc[name.data()].GetInt64();
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, int16_t b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ context.doc.AddMember(key, b, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, int16_t& b)
+{
+ b = context.doc[name.data()].GetInt64();
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, int32_t b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ context.doc.AddMember(key, b, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, int32_t& b)
+{
+ b = context.doc[name.data()].GetInt();
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, int64_t b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ context.doc.AddMember(key, b, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, int64_t& b)
+{
+ b = context.doc[name.data()].GetInt64();
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, std::string_view b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value value(b.data(), context.allocator);
+ context.doc.AddMember(key, value, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::string& b)
+{
+ b = context.doc[name.data()].GetString();
+}
- void Serialize(std::string& name, std::unordered_map<std::string, std::string> b)
+inline void Serialize(SerializationContext& context, std::string_view name, const std::map<uint64_t, std::string>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (auto& i : b)
{
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& i : b)
- {
- rapidjson::Value p(rapidjson::kArrayType);
- rapidjson::Value _key(i.first.c_str(), m_activeContext.allocator);
- rapidjson::Value value(i.second.c_str(), m_activeContext.allocator);
- p.PushBack(_key, m_activeContext.allocator);
- p.PushBack(value, m_activeContext.allocator);
- bArr.PushBack(p, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
+ rapidjson::Value p(rapidjson::kArrayType);
+ p.PushBack(i.first, context.allocator);
+ rapidjson::Value value(i.second.c_str(), context.allocator);
+ p.PushBack(value, context.allocator);
+ bArr.PushBack(p, context.allocator);
}
- void Deserialize(std::string& name, std::unordered_map<uint64_t, std::string>& b)
+ context.doc.AddMember(key, bArr, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::map<uint64_t, std::string>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
+ b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString();
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<uint64_t, std::string>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (auto& i : b)
{
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
- b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString();
+ rapidjson::Value p(rapidjson::kArrayType);
+ p.PushBack(i.first, context.allocator);
+ rapidjson::Value value(i.second.c_str(), context.allocator);
+ p.PushBack(value, context.allocator);
+ bArr.PushBack(p, context.allocator);
}
+ context.doc.AddMember(key, bArr, context.allocator);
+}
- void Serialize(std::string& name, std::unordered_map<uint64_t, uint64_t> b)
+inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<std::string, std::string>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (auto& i : b)
{
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& i : b)
- {
- rapidjson::Value p(rapidjson::kArrayType);
- p.PushBack(i.first, m_activeContext.allocator);
- p.PushBack(i.second, m_activeContext.allocator);
- bArr.PushBack(p, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
+ rapidjson::Value p(rapidjson::kArrayType);
+ rapidjson::Value _key(i.first.c_str(), context.allocator);
+ rapidjson::Value value(i.second.c_str(), context.allocator);
+ p.PushBack(_key, context.allocator);
+ p.PushBack(value, context.allocator);
+ bArr.PushBack(p, context.allocator);
}
- void Deserialize(std::string& name, std::unordered_map<uint64_t, uint64_t>& b)
+ context.doc.AddMember(key, bArr, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<uint64_t, std::string>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
+ b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString();
+}
+
+inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<uint64_t, uint64_t>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (auto& i : b)
{
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
- b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64();
+ rapidjson::Value p(rapidjson::kArrayType);
+ p.PushBack(i.first, context.allocator);
+ p.PushBack(i.second, context.allocator);
+ bArr.PushBack(p, context.allocator);
}
+ context.doc.AddMember(key, bArr, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<uint64_t, uint64_t>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
+ b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64();
+}
- // std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>>
- void Serialize(std::string& name, std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>> b)
+// std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>>
+inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value classes(rapidjson::kArrayType);
+ for (auto& i : b)
{
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value classes(rapidjson::kArrayType);
- for (auto& i : b)
+ rapidjson::Value classArr(rapidjson::kArrayType);
+ rapidjson::Value classKey(i.first.c_str(), context.allocator);
+ classArr.PushBack(classKey, context.allocator);
+ rapidjson::Value membersArr(rapidjson::kArrayType);
+ for (auto& j : i.second)
{
- rapidjson::Value classArr(rapidjson::kArrayType);
- rapidjson::Value classKey(i.first.c_str(), m_activeContext.allocator);
- classArr.PushBack(classKey, m_activeContext.allocator);
- rapidjson::Value membersArr(rapidjson::kArrayType);
- for (auto& j : i.second)
- {
- rapidjson::Value member(rapidjson::kArrayType);
- member.PushBack(j.first, m_activeContext.allocator);
- member.PushBack(j.second, m_activeContext.allocator);
- membersArr.PushBack(member, m_activeContext.allocator);
- }
- classArr.PushBack(membersArr, m_activeContext.allocator);
- classes.PushBack(classArr, m_activeContext.allocator);
+ rapidjson::Value member(rapidjson::kArrayType);
+ member.PushBack(j.first, context.allocator);
+ member.PushBack(j.second, context.allocator);
+ membersArr.PushBack(member, context.allocator);
}
- m_activeContext.doc.AddMember(key, classes, m_activeContext.allocator);
+ classArr.PushBack(membersArr, context.allocator);
+ classes.PushBack(classArr, context.allocator);
}
- void Deserialize(std::string& name, std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>>& b)
+ context.doc.AddMember(key, classes, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
{
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
+ std::string key = i.GetArray()[0].GetString();
+ std::unordered_map<uint64_t, uint64_t> memArray;
+ for (auto& member : i.GetArray()[1].GetArray())
{
- std::string key = i.GetArray()[0].GetString();
- std::unordered_map<uint64_t, uint64_t> memArray;
- for (auto& member : i.GetArray()[1].GetArray())
- {
- memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64();
- }
- b[key] = memArray;
+ memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64();
}
+ b[key] = memArray;
}
+}
- void Deserialize(std::string& name, std::unordered_map<std::string, std::string>& b)
- {
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
- b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString();
- }
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, std::string>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
+ b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString();
+}
- void Serialize(std::string& name, std::vector<std::string> b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (const auto& s : b)
- {
- rapidjson::Value value(s.c_str(), m_activeContext.allocator);
- bArr.PushBack(value, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
- void Deserialize(std::string& name, std::vector<std::string>& b)
+inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<std::string>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (const auto& s : b)
{
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
- b.emplace_back(i.GetString());
+ rapidjson::Value value(s.c_str(), context.allocator);
+ bArr.PushBack(value, context.allocator);
}
+ context.doc.AddMember(key, bArr, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::string>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
+ b.emplace_back(i.GetString());
+}
- void Serialize(std::string& name, std::vector<std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> b)
+inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<std::pair<uint64_t, std::pair<uint64_t, uint64_t>>>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (auto& i : b)
{
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& i : b)
- {
- rapidjson::Value segV(rapidjson::kArrayType);
- segV.PushBack(i.first, m_activeContext.allocator);
- segV.PushBack(i.second.first, m_activeContext.allocator);
- segV.PushBack(i.second.second, m_activeContext.allocator);
- bArr.PushBack(segV, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
+ rapidjson::Value segV(rapidjson::kArrayType);
+ segV.PushBack(i.first, context.allocator);
+ segV.PushBack(i.second.first, context.allocator);
+ segV.PushBack(i.second.second, context.allocator);
+ bArr.PushBack(segV, context.allocator);
}
- void Deserialize(std::string& name, std::vector<std::pair<uint64_t, std::pair<uint64_t, uint64_t>>>& b)
+ context.doc.AddMember(key, bArr, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, std::pair<uint64_t, uint64_t>>>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
{
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
- {
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> j;
- j.first = i.GetArray()[0].GetUint64();
- j.second.first = i.GetArray()[1].GetUint64();
- j.second.second = i.GetArray()[2].GetUint64();
- b.push_back(j);
- }
+ std::pair<uint64_t, std::pair<uint64_t, uint64_t>> j;
+ j.first = i.GetArray()[0].GetUint64();
+ j.second.first = i.GetArray()[1].GetUint64();
+ j.second.second = i.GetArray()[2].GetUint64();
+ b.push_back(j);
}
+}
- void Serialize(std::string& name, std::vector<std::pair<uint64_t, bool>> b)
+inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<std::pair<uint64_t, bool>>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (auto& i : b)
{
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& i : b)
- {
- rapidjson::Value segV(rapidjson::kArrayType);
- segV.PushBack(i.first, m_activeContext.allocator);
- segV.PushBack(i.second, m_activeContext.allocator);
- bArr.PushBack(segV, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
+ rapidjson::Value segV(rapidjson::kArrayType);
+ segV.PushBack(i.first, context.allocator);
+ segV.PushBack(i.second, context.allocator);
+ bArr.PushBack(segV, context.allocator);
}
- void Deserialize(std::string& name, std::vector<std::pair<uint64_t, bool>>& b)
+ context.doc.AddMember(key, bArr, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, bool>>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
{
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
- {
- std::pair<uint64_t, bool> j;
- j.first = i.GetArray()[0].GetUint64();
- j.second = i.GetArray()[1].GetBool();
- b.push_back(j);
- }
+ std::pair<uint64_t, bool> j;
+ j.first = i.GetArray()[0].GetUint64();
+ j.second = i.GetArray()[1].GetBool();
+ b.push_back(j);
}
+}
- void Serialize(std::string& name, std::vector<uint64_t> b)
+inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<uint64_t>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (auto& i : b)
{
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& i : b)
- {
- bArr.PushBack(i, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
+ bArr.PushBack(i, context.allocator);
}
- void Deserialize(std::string& name, std::vector<uint64_t>& b)
+ context.doc.AddMember(key, bArr, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<uint64_t>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
{
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
- {
- b.push_back(i.GetUint64());
- }
+ b.push_back(i.GetUint64());
}
+}
- // std::unordered_map<std::string, uint64_t>
- void Serialize(std::string& name, std::unordered_map<std::string, uint64_t> b)
+// std::unordered_map<std::string, uint64_t>
+inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<std::string, uint64_t>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (auto& i : b)
{
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& i : b)
- {
- rapidjson::Value p(rapidjson::kArrayType);
- rapidjson::Value _key(i.first.c_str(), m_activeContext.allocator);
- p.PushBack(_key, m_activeContext.allocator);
- p.PushBack(i.second, m_activeContext.allocator);
- bArr.PushBack(p, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
+ rapidjson::Value p(rapidjson::kArrayType);
+ rapidjson::Value _key(i.first.c_str(), context.allocator);
+ p.PushBack(_key, context.allocator);
+ p.PushBack(i.second, context.allocator);
+ bArr.PushBack(p, context.allocator);
}
- void Deserialize(std::string& name, std::unordered_map<std::string, uint64_t>& b)
+ context.doc.AddMember(key, bArr, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, uint64_t>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
{
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
- {
- b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64();
- }
+ b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64();
}
- // std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>>
- void Serialize(std::string& name, std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>> b)
+}
+
+// std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>>
+inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>>& b)
+{
+ rapidjson::Value key(name.data(), context.allocator);
+ rapidjson::Value bArr(rapidjson::kArrayType);
+ for (auto& i : b)
{
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& i : b)
+ rapidjson::Value segV(rapidjson::kArrayType);
+ segV.PushBack(i.first, context.allocator);
+ rapidjson::Value segArr(rapidjson::kArrayType);
+ for (auto& j : i.second)
{
- rapidjson::Value segV(rapidjson::kArrayType);
- segV.PushBack(i.first, m_activeContext.allocator);
- rapidjson::Value segArr(rapidjson::kArrayType);
- for (auto& j : i.second)
- {
- rapidjson::Value segPair(rapidjson::kArrayType);
- segPair.PushBack(j.first, m_activeContext.allocator);
- rapidjson::Value segStr(j.second.c_str(), m_activeContext.allocator);
- segPair.PushBack(segStr, m_activeContext.allocator);
- segArr.PushBack(segPair, m_activeContext.allocator);
- }
- segV.PushBack(segArr, m_activeContext.allocator);
- bArr.PushBack(segV, m_activeContext.allocator);
+ rapidjson::Value segPair(rapidjson::kArrayType);
+ segPair.PushBack(j.first, context.allocator);
+ rapidjson::Value segStr(j.second.c_str(), context.allocator);
+ segPair.PushBack(segStr, context.allocator);
+ segArr.PushBack(segPair, context.allocator);
}
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
+ segV.PushBack(segArr, context.allocator);
+ bArr.PushBack(segV, context.allocator);
}
- void Deserialize(std::string& name, std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>>& b)
+ context.doc.AddMember(key, bArr, context.allocator);
+}
+
+inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>>& b)
+{
+ for (auto& i : context.doc[name.data()].GetArray())
{
- for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray())
+ std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>> j;
+ j.first = i.GetArray()[0].GetUint64();
+ for (auto& k : i.GetArray()[1].GetArray())
{
- std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>> j;
- j.first = i.GetArray()[0].GetUint64();
- for (auto& k : i.GetArray()[1].GetArray())
- {
- j.second.push_back({k.GetArray()[0].GetUint64(), k.GetArray()[1].GetString()});
- }
- b.push_back(j);
+ j.second.push_back({k.GetArray()[0].GetUint64(), k.GetArray()[1].GetString()});
}
+ b.push_back(j);
}
+}
- template <typename T>
- void store(std::string x, T y)
- {
- Serialize(x, y);
- }
-
- template <typename T>
- T load(std::string x, T y)
- {
- T val;
- Deserialize(x, val);
- return val;
- }
-
- rapidjson::Document& GetDoc()
- {
- S();
- Store();
- return m_activeContext.doc;
- }
-
-public:
- virtual void Store() = 0;
- virtual void Load() = 0;
-
- std::string AsString()
- {
- rapidjson::StringBuffer strbuf;
- rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strbuf);
- GetDoc().Accept(writer);
-
- std::string s = strbuf.GetString();
- return s;
- }
- rapidjson::Document& AsDocument() { return GetDoc(); }
- void LoadFromString(const std::string& s)
- {
- m_activeDeserContext.doc.Parse(s.c_str());
- Load();
- }
- void LoadFromValue(rapidjson::Value& s)
- {
- m_activeDeserContext.doc.CopyFrom(s, m_activeDeserContext.doc.GetAllocator());
- Load();
- }
- Ref<Metadata> AsMetadata() { return new Metadata(AsString()); }
- bool LoadFromMetadata(const Ref<Metadata>& meta)
- {
- if (!meta->IsString())
- return false;
- LoadFromString(meta->GetString());
- return true;
- }
-};
+} // namespace SharedCacheCore
#endif // SHAREDCACHE_METADATASERIALIZABLE_HPP