mirror of
https://github.com/apple/foundationdb.git
synced 2025-06-02 11:15:50 +08:00
Eliminate unnecessary memcpy
This commit is contained in:
parent
70f0726185
commit
137936762d
@ -53,11 +53,11 @@ void PacketWriter::serializeBytesAcrossBoundary(const void* data, int bytes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacketWriter::nextBuffer() {
|
void PacketWriter::nextBuffer(size_t size) {
|
||||||
auto last_buffer_bytes_written = buffer->bytes_written;
|
auto last_buffer_bytes_written = buffer->bytes_written;
|
||||||
length += last_buffer_bytes_written;
|
length += last_buffer_bytes_written;
|
||||||
|
|
||||||
buffer->next = PacketBuffer::create();
|
buffer->next = PacketBuffer::create(size);
|
||||||
buffer = buffer->nextPacketBuffer();
|
buffer = buffer->nextPacketBuffer();
|
||||||
|
|
||||||
if (reliable) {
|
if (reliable) {
|
||||||
|
@ -99,18 +99,24 @@ private:
|
|||||||
|
|
||||||
class ObjectWriter {
|
class ObjectWriter {
|
||||||
public:
|
public:
|
||||||
|
ObjectWriter() = default;
|
||||||
|
explicit ObjectWriter(std::function<uint8_t*(size_t)> customAllocator) : customAllocator(customAllocator) {}
|
||||||
template <class... Items>
|
template <class... Items>
|
||||||
void serialize(FileIdentifier file_identifier, Items const&... items) {
|
void serialize(FileIdentifier file_identifier, Items const&... items) {
|
||||||
ASSERT(data == nullptr); // object serializer can only serialize one object
|
ASSERT(data == nullptr); // object serializer can only serialize one object
|
||||||
int allocations = 0;
|
if (customAllocator) {
|
||||||
auto allocator = [this, &allocations](size_t size_) {
|
save_members(customAllocator, file_identifier, items...);
|
||||||
++allocations;
|
} else {
|
||||||
size = size_;
|
int allocations = 0;
|
||||||
data = new (arena) uint8_t[size];
|
auto allocator = [this, &allocations](size_t size_) {
|
||||||
return data;
|
++allocations;
|
||||||
};
|
size = size_;
|
||||||
save_members(allocator, file_identifier, items...);
|
data = new (arena) uint8_t[size];
|
||||||
ASSERT(allocations == 1);
|
return data;
|
||||||
|
};
|
||||||
|
save_members(allocator, file_identifier, items...);
|
||||||
|
ASSERT(allocations == 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Item>
|
template <class Item>
|
||||||
@ -123,6 +129,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Standalone<StringRef> toString() const {
|
Standalone<StringRef> toString() const {
|
||||||
|
ASSERT(!customAllocator);
|
||||||
return Standalone<StringRef>(toStringRef(), arena);
|
return Standalone<StringRef>(toStringRef(), arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +142,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Arena arena;
|
Arena arena;
|
||||||
|
std::function<uint8_t*(size_t)> customAllocator;
|
||||||
uint8_t* data = nullptr;
|
uint8_t* data = nullptr;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
};
|
};
|
||||||
|
@ -732,7 +732,7 @@ struct PacketWriter {
|
|||||||
}
|
}
|
||||||
void serializeBytesAcrossBoundary(const void* data, int bytes);
|
void serializeBytesAcrossBoundary(const void* data, int bytes);
|
||||||
void writeAhead( int bytes, struct SplitBuffer* );
|
void writeAhead( int bytes, struct SplitBuffer* );
|
||||||
void nextBuffer();
|
void nextBuffer(size_t size = 0 /* downstream it will default to at least 4k minus some padding */);
|
||||||
PacketBuffer* finish();
|
PacketBuffer* finish();
|
||||||
int size() { return length; }
|
int size() { return length; }
|
||||||
|
|
||||||
@ -750,7 +750,21 @@ struct PacketWriter {
|
|||||||
}
|
}
|
||||||
ProtocolVersion protocolVersion() const { return m_protocolVersion; }
|
ProtocolVersion protocolVersion() const { return m_protocolVersion; }
|
||||||
void setProtocolVersion(ProtocolVersion pv) { m_protocolVersion = pv; }
|
void setProtocolVersion(ProtocolVersion pv) { m_protocolVersion = pv; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint8_t* writeBytes(size_t size) {
|
||||||
|
if (size > buffer->bytes_unwritten()) {
|
||||||
|
nextBuffer(size);
|
||||||
|
ASSERT(buffer->size() >= size);
|
||||||
|
}
|
||||||
|
uint8_t* result = buffer->data() + buffer->bytes_written;
|
||||||
|
buffer->bytes_written += size;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class, class>
|
||||||
|
friend class MakeSerializeSource;
|
||||||
|
|
||||||
void init( PacketBuffer* buf, ReliablePacket* reliable );
|
void init( PacketBuffer* buf, ReliablePacket* reliable );
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -765,9 +779,8 @@ struct MakeSerializeSource : ISerializeSource {
|
|||||||
using value_type = V;
|
using value_type = V;
|
||||||
virtual void serializePacketWriter(PacketWriter& w, bool useObjectSerializer) const {
|
virtual void serializePacketWriter(PacketWriter& w, bool useObjectSerializer) const {
|
||||||
if (useObjectSerializer) {
|
if (useObjectSerializer) {
|
||||||
ObjectWriter writer;
|
ObjectWriter writer([&](size_t size) { return w.writeBytes(size); });
|
||||||
writer.serialize(get());
|
writer.serialize(get()); // Writes directly into buffer supplied by |w|
|
||||||
w.serializeBytes(writer.toStringRef()); // TODO(atn34) Eliminate unnecessary memcpy
|
|
||||||
} else {
|
} else {
|
||||||
static_cast<T const*>(this)->serialize(w);
|
static_cast<T const*>(this)->serialize(w);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user