aboutsummaryrefslogtreecommitdiff
path: root/src/proto/data_row.zig
diff options
context:
space:
mode:
authorMartin Ashby <martin@ashbysoft.com>2023-09-28 10:54:58 +0100
committerMartin Ashby <martin@ashbysoft.com>2023-09-28 10:54:58 +0100
commit35494bc81b59165ee9264cd1004bb05a120279a3 (patch)
tree8d11946f8fc20e1f254301100e860f28bade5ee0 /src/proto/data_row.zig
parent0c063d42430077881e563120ebfcf92c2cecf463 (diff)
downloadpgz-35494bc81b59165ee9264cd1004bb05a120279a3.tar.gz
pgz-35494bc81b59165ee9264cd1004bb05a120279a3.tar.bz2
pgz-35494bc81b59165ee9264cd1004bb05a120279a3.tar.xz
pgz-35494bc81b59165ee9264cd1004bb05a120279a3.zip
Reduce allocations, the message takes ownership of the bytes read from
the stream and is responsible for deallocating, rather than copying them to their own storage.
Diffstat (limited to 'src/proto/data_row.zig')
-rw-r--r--src/proto/data_row.zig23
1 files changed, 10 insertions, 13 deletions
diff --git a/src/proto/data_row.zig b/src/proto/data_row.zig
index c20b794..43c4526 100644
--- a/src/proto/data_row.zig
+++ b/src/proto/data_row.zig
@@ -12,25 +12,23 @@ const DataRow = @This();
buf: ?[]const u8 = null, // owned
columns: [][]const u8, // also owned
-pub fn read(a: std.mem.Allocator, b: []const u8) !DataRow {
- if (b.len < 2) return ProtocolError.InvalidMessageLength;
- var buf = try a.dupe(u8, b);
- var res: DataRow = undefined;
- res.buf = buf;
- errdefer res.deinit(a);
-
+pub fn read(a: std.mem.Allocator, buf: []const u8) !DataRow {
+ if (buf.len < 2) return ProtocolError.InvalidMessageLength;
+ errdefer a.free(buf);
const n_columns = std.mem.readIntBig(u16, buf[0..2]);
const columns = try a.alloc([]const u8, n_columns);
errdefer a.free(columns);
var pos: usize = 2;
for (0..n_columns) |col| {
- const len = std.mem.readIntBig(u32, buf[pos..(pos+4)][0..4]); // second slice forces the slice size to be known at comptime and satisfy the type check on readIntBig!
- const data = if (len > 0) buf[(pos+4)..(pos+4+len)] else &[_]u8{};
+ const len = std.mem.readIntBig(u32, buf[pos..(pos + 4)][0..4]); // second slice forces the slice size to be known at comptime and satisfy the type check on readIntBig!
+ const data = if (len > 0) buf[(pos + 4)..(pos + 4 + len)] else &[_]u8{};
columns[col] = data;
- pos += (4+len);
+ pos += (4 + len);
}
- res.columns = columns;
- return res;
+ return .{
+ .buf = buf,
+ .columns = columns,
+ };
}
pub fn write(self: DataRow, a: std.mem.Allocator, stream_writer: anytype) !void {
@@ -77,7 +75,6 @@ test "round trip" {
try std.testing.expectEqual(Tag, tag);
const len = try reader.readIntBig(u32);
const buf = try allocator.alloc(u8, len - 4);
- defer allocator.free(buf);
try reader.readNoEof(buf);
var sm2 = try DataRow.read(allocator, buf);
defer sm2.deinit(allocator);