summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2026-01-05 19:47:08 -0500
committerRobby Zambito <contact@robbyzambito.me>2026-01-05 20:13:24 -0500
commit318d467f5c692e78d16df9c0c32b5e7999343e65 (patch)
treebf9913150ef37a0a0026694665cdd6c0ef136ea6
parent3342aa22ab5b6aedf31d787d6c7089457b0d7210 (diff)
Optimize PUB and HPUB parsing
This will try to take better advantage of the buffered reading. Instead of pushing one byte at a time to the array list for each section, find the end index for each section, then alloc the arraylist and copy the data into it all at once.
-rw-r--r--src/server/message_parser.zig108
1 files changed, 59 insertions, 49 deletions
diff --git a/src/server/message_parser.zig b/src/server/message_parser.zig
index bf472af..fd1b5b1 100644
--- a/src/server/message_parser.zig
+++ b/src/server/message_parser.zig
@@ -404,12 +404,14 @@ fn parseSub(alloc: Allocator, in: *Reader) !Message {
continue :sw .in_second;
},
.in_second => {
- const byte = try in.peekByte();
- if (!isWhitespace(byte)) {
- try second.append(alloc, byte);
- in.toss(1);
- continue :sw .in_second;
- }
+ for (1..in.buffer.len) |i| {
+ try in.fill(i + 1);
+ if (isWhitespace(in.buffered()[i])) {
+ @memcpy(try second.addManyAsSlice(alloc, i), in.buffered()[0..i]);
+ in.toss(i);
+ break;
+ }
+ } else return error.EndOfStream;
continue :sw .after_second;
},
.after_second => {
@@ -424,13 +426,15 @@ fn parseSub(alloc: Allocator, in: *Reader) !Message {
continue :sw .in_third;
},
.in_third => {
- const byte = try in.peekByte();
- if (byte == '\r') {
- continue :sw .in_end;
- }
- try third.?.append(alloc, byte);
- in.toss(1);
- continue :sw .in_third;
+ for (1..in.buffer.len) |i| {
+ try in.fill(i + 1);
+ if (isWhitespace(in.buffered()[i])) {
+ @memcpy(try third.?.addManyAsSlice(alloc, i), in.buffered()[0..i]);
+ in.toss(i);
+ break;
+ }
+ } else return error.EndOfStream;
+ continue :sw .in_end;
},
.in_end => {
try expectStreamBytes(in, "\r\n");
@@ -674,12 +678,14 @@ fn parsePub(alloc: Allocator, in: *Reader) !Message {
continue :sw .in_second;
},
.in_second => {
- const byte = try in.peekByte();
- if (!isWhitespace(byte)) {
- try second.append(alloc, byte);
- in.toss(1);
- continue :sw .in_second;
- }
+ for (1..in.buffer.len) |i| {
+ try in.fill(i + 1);
+ if (isWhitespace(in.buffered()[i])) {
+ @memcpy(try second.addManyAsSlice(alloc, i), in.buffered()[0..i]);
+ in.toss(i);
+ break;
+ }
+ } else return error.EndOfStream;
continue :sw .after_second;
},
.after_second => {
@@ -694,15 +700,15 @@ fn parsePub(alloc: Allocator, in: *Reader) !Message {
continue :sw .in_third;
},
.in_third => {
- const byte = try in.peekByte();
- if (byte == '\r') {
- continue :sw .in_end;
- } else if (isDigit(byte)) {
- try third.?.append(alloc, byte);
- in.toss(1);
- continue :sw .in_third;
- }
- return error.InvalidStream;
+ for (1..in.buffer.len) |i| {
+ try in.fill(i + 1);
+ if (isWhitespace(in.buffered()[i])) {
+ @memcpy(try third.?.addManyAsSlice(alloc, i), in.buffered()[0..i]);
+ in.toss(i);
+ break;
+ }
+ } else return error.EndOfStream;
+ continue :sw .in_end;
},
.in_end => {
try expectStreamBytes(in, "\r\n");
@@ -847,12 +853,14 @@ fn parseHPub(alloc: Allocator, in: *Reader) !Message {
continue :sw .in_second;
},
.in_second => {
- const byte = try in.peekByte();
- if (!isWhitespace(byte)) {
- try second.append(alloc, byte);
- in.toss(1);
- continue :sw .in_second;
- }
+ for (1..in.buffer.len) |i| {
+ try in.fill(i + 1);
+ if (isWhitespace(in.buffered()[i])) {
+ @memcpy(try second.addManyAsSlice(alloc, i), in.buffered()[0..i]);
+ in.toss(i);
+ break;
+ }
+ } else return error.EndOfStream;
continue :sw .after_second;
},
.after_second => {
@@ -867,12 +875,14 @@ fn parseHPub(alloc: Allocator, in: *Reader) !Message {
continue :sw .in_third;
},
.in_third => {
- const byte = try in.peekByte();
- if (!isWhitespace(byte)) {
- try third.append(alloc, byte);
- in.toss(1);
- continue :sw .in_third;
- }
+ for (1..in.buffer.len) |i| {
+ try in.fill(i + 1);
+ if (isWhitespace(in.buffered()[i])) {
+ @memcpy(try third.addManyAsSlice(alloc, i), in.buffered()[0..i]);
+ in.toss(i);
+ break;
+ }
+ } else return error.EndOfStream;
continue :sw .after_third;
},
.after_third => {
@@ -887,15 +897,15 @@ fn parseHPub(alloc: Allocator, in: *Reader) !Message {
continue :sw .in_fourth;
},
.in_fourth => {
- const byte = try in.peekByte();
- if (byte == '\r') {
- continue :sw .in_end;
- } else if (isDigit(byte)) {
- try fourth.?.append(alloc, byte);
- in.toss(1);
- continue :sw .in_fourth;
- }
- return error.InvalidStream;
+ for (1..in.buffer.len) |i| {
+ try in.fill(i + 1);
+ if (isWhitespace(in.buffered()[i])) {
+ @memcpy(try fourth.?.addManyAsSlice(alloc, i), in.buffered()[0..i]);
+ in.toss(i);
+ break;
+ }
+ } else return error.EndOfStream;
+ continue :sw .in_end;
},
.in_end => {
try expectStreamBytes(in, "\r\n");