This commit is contained in:
J. Nick Koston
2025-06-06 21:40:18 +01:00
parent 259e513293
commit b2bd0d2318
3 changed files with 27 additions and 20 deletions

View File

@@ -1778,7 +1778,7 @@ void APIConnection::process_batch_() {
}
// Pre-allocate storage for packet info
std::vector<std::tuple<uint16_t, uint32_t, uint16_t>> packet_info;
std::vector<PacketInfo> packet_info;
packet_info.reserve(num_items);
// Cache these values to avoid repeated virtual calls
@@ -1787,7 +1787,7 @@ void APIConnection::process_batch_() {
// Initialize buffer and tracking variables
this->proto_write_buffer_.clear();
// Reserve based on typical message size (24 bytes) + overhead per message
// Reserve based on typical message size + overhead per message
this->proto_write_buffer_.reserve((24 + header_padding + footer_size) * num_items);
this->batch_first_message_ = true;

View File

@@ -612,14 +612,13 @@ APIError APINoiseFrameHelper::write_protobuf_packet(uint16_t type, ProtoWriteBuf
raw_buffer->resize(raw_buffer->size() + frame_footer_size_);
// Use write_protobuf_packets with a single packet
std::vector<std::tuple<uint16_t, uint32_t, uint16_t>> packets;
std::vector<PacketInfo> packets;
packets.emplace_back(type, 0, payload_len);
return write_protobuf_packets(buffer, packets);
}
APIError APINoiseFrameHelper::write_protobuf_packets(
ProtoWriteBuffer buffer, const std::vector<std::tuple<uint16_t, uint32_t, uint16_t>> &packets) {
APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, const std::vector<PacketInfo> &packets) {
APIError aerr = state_action_();
if (aerr != APIError::OK) {
return aerr;
@@ -639,9 +638,9 @@ APIError APINoiseFrameHelper::write_protobuf_packets(
// We need to encrypt each packet in place
for (const auto &packet : packets) {
uint16_t type = std::get<0>(packet);
uint32_t offset = std::get<1>(packet);
uint16_t payload_len = std::get<2>(packet);
uint16_t type = packet.message_type;
uint16_t offset = packet.offset;
uint16_t payload_len = packet.payload_size;
uint16_t msg_len = 4 + payload_len; // type(2) + data_len(2) + payload
// The buffer already has padding at offset
@@ -1031,14 +1030,14 @@ APIError APIPlaintextFrameHelper::write_protobuf_packet(uint16_t type, ProtoWrit
uint16_t payload_len = static_cast<uint16_t>(raw_buffer->size() - frame_header_padding_);
// Use write_protobuf_packets with a single packet
std::vector<std::tuple<uint16_t, uint32_t, uint16_t>> packets;
std::vector<PacketInfo> packets;
packets.emplace_back(type, 0, payload_len);
return write_protobuf_packets(buffer, packets);
}
APIError APIPlaintextFrameHelper::write_protobuf_packets(
ProtoWriteBuffer buffer, const std::vector<std::tuple<uint16_t, uint32_t, uint16_t>> &packets) {
APIError APIPlaintextFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer,
const std::vector<PacketInfo> &packets) {
if (state_ != State::DATA) {
return APIError::BAD_STATE;
}
@@ -1052,9 +1051,9 @@ APIError APIPlaintextFrameHelper::write_protobuf_packets(
iovs.reserve(packets.size());
for (const auto &packet : packets) {
uint16_t type = std::get<0>(packet);
uint32_t offset = std::get<1>(packet);
uint16_t payload_len = std::get<2>(packet);
uint16_t type = packet.message_type;
uint16_t offset = packet.offset;
uint16_t payload_len = packet.payload_size;
// Calculate varint sizes for header components
uint8_t size_varint_len = api::ProtoSize::varint(static_cast<uint32_t>(payload_len));

View File

@@ -27,6 +27,17 @@ struct ReadPacketBuffer {
uint16_t data_len;
};
// Packed packet info structure to minimize memory usage
struct PacketInfo {
uint16_t message_type; // 2 bytes
uint16_t offset; // 2 bytes (sufficient for packet size ~1460 bytes)
uint16_t payload_size; // 2 bytes (up to 65535 bytes)
uint16_t padding; // 2 bytes (for alignment)
PacketInfo(uint16_t type, uint16_t off, uint16_t size)
: message_type(type), offset(off), payload_size(size), padding(0) {}
};
enum class APIError : int {
OK = 0,
WOULD_BLOCK = 1001,
@@ -90,8 +101,7 @@ class APIFrameHelper {
// Write multiple protobuf packets in a single operation
// packets contains (message_type, offset, length) for each message in the buffer
// The buffer contains all messages with appropriate padding before each
virtual APIError write_protobuf_packets(ProtoWriteBuffer buffer,
const std::vector<std::tuple<uint16_t, uint32_t, uint16_t>> &packets) = 0;
virtual APIError write_protobuf_packets(ProtoWriteBuffer buffer, const std::vector<PacketInfo> &packets) = 0;
// Get the frame header padding required by this protocol
virtual uint8_t frame_header_padding() = 0;
// Get the frame footer size required by this protocol
@@ -189,8 +199,7 @@ class APINoiseFrameHelper : public APIFrameHelper {
APIError loop() override;
APIError read_packet(ReadPacketBuffer *buffer) override;
APIError write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) override;
APIError write_protobuf_packets(ProtoWriteBuffer buffer,
const std::vector<std::tuple<uint16_t, uint32_t, uint16_t>> &packets) override;
APIError write_protobuf_packets(ProtoWriteBuffer buffer, const std::vector<PacketInfo> &packets) override;
// Get the frame header padding required by this protocol
uint8_t frame_header_padding() override { return frame_header_padding_; }
// Get the frame footer size required by this protocol
@@ -240,8 +249,7 @@ class APIPlaintextFrameHelper : public APIFrameHelper {
APIError loop() override;
APIError read_packet(ReadPacketBuffer *buffer) override;
APIError write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) override;
APIError write_protobuf_packets(ProtoWriteBuffer buffer,
const std::vector<std::tuple<uint16_t, uint32_t, uint16_t>> &packets) override;
APIError write_protobuf_packets(ProtoWriteBuffer buffer, const std::vector<PacketInfo> &packets) override;
uint8_t frame_header_padding() override { return frame_header_padding_; }
// Get the frame footer size required by this protocol
uint8_t frame_footer_size() override { return frame_footer_size_; }