Merge remote-tracking branch 'andrew/flatbuffers-fixes2' into flatbuffers-fixes2

This commit is contained in:
mpilman 2019-07-11 23:06:13 -07:00
commit 4870362dbb
2 changed files with 10 additions and 39 deletions

View File

@ -70,13 +70,6 @@ struct IReplicationPolicy : public ReferenceCounted<IReplicationPolicy> {
return keys; return keys;
} }
virtual void attributeKeys(std::set<std::string>*) const = 0; virtual void attributeKeys(std::set<std::string>*) const = 0;
// For flatbuffers, IReplicationPolicy is just encoded as a string using
// |serializeReplicationPolicy|. |writer| is a member of IReplicationPolicy
// so that this string outlives all calls to
// dynamic_size_traits<Reference<IReplicationPolicy>>::save
mutable BinaryWriter writer{ IncludeVersion() };
mutable bool alreadyWritten = false;
}; };
template <class Archive> template <class Archive>
@ -288,34 +281,18 @@ private:
public: public:
static size_t size(const T& value) { static size_t size(const T& value) {
bool present = true; // size gets called multiple times. If this becomes a performance problem, we can perform the
if (value.getPtr() == nullptr) { // serialization once and cache the result as a mutable member of IReplicationPolicy
present = false;
BinaryWriter writer{ IncludeVersion() }; BinaryWriter writer{ IncludeVersion() };
writer << present; ::save(writer, value);
return writer.getLength(); return writer.getLength();
} }
if (!value->alreadyWritten) {
value->writer = BinaryWriter{ IncludeVersion() };
value->writer << present;
serializeReplicationPolicy(value->writer, const_cast<Reference<IReplicationPolicy>&>(value));
value->alreadyWritten = true;
}
return value->writer.getLength();
}
// Guaranteed to be called only once during serialization // Guaranteed to be called only once during serialization
static void save(uint8_t* out, const T& value) { static void save(uint8_t* out, const T& value) {
if (value.getPtr() == nullptr) {
bool present = false;
BinaryWriter writer{ IncludeVersion() }; BinaryWriter writer{ IncludeVersion() };
writer << present; ::save(writer, value);
memcpy(out, writer.getData(), writer.getLength()); memcpy(out, writer.getData(), writer.getLength());
} else {
ASSERT(value->alreadyWritten)
memcpy(out, value->writer.getData(), value->writer.getLength());
value->alreadyWritten = false;
}
} }
// Context is an arbitrary type that is plumbed by reference throughout the // Context is an arbitrary type that is plumbed by reference throughout the
@ -324,13 +301,7 @@ public:
static void load(const uint8_t* buf, size_t sz, Reference<IReplicationPolicy>& value, Context&) { static void load(const uint8_t* buf, size_t sz, Reference<IReplicationPolicy>& value, Context&) {
StringRef str(buf, sz); StringRef str(buf, sz);
BinaryReader reader(str, IncludeVersion()); BinaryReader reader(str, IncludeVersion());
bool present = false; ::load(reader, value);
reader >> present;
if (present) {
serializeReplicationPolicy(reader, value);
} else {
value.clear();
}
} }
}; };