Skip to content

Commit 94531cb

Browse files
committed
Improve memory and performance of url.Query
1 - Use getOrPut to avoid making 2 map lookups where possible. 2 - Use an arena allocator for Values, which makes memory management simpler. 3 - Because of #2, we no longer need to allocate key or values which don't need to be unescaped. The downside is that the input string has to outlive the query.Values (but I think this is currently always the case) 4 - Optimize unescape logic & allocations 5 - Improve test coverage
1 parent 8427602 commit 94531cb

File tree

2 files changed

+309
-122
lines changed

2 files changed

+309
-122
lines changed

src/str/parser.zig

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,27 @@ pub const Reader = struct {
5252
}
5353
};
5454

55+
// converts a comptime-known string (i.e. null terminated) to an uint
56+
pub fn asUint(comptime string: anytype) AsUintReturn(string) {
57+
const byteLength = @bitSizeOf(@TypeOf(string.*)) / 8 - 1;
58+
const expectedType = *const [byteLength:0]u8;
59+
if (@TypeOf(string) != expectedType) {
60+
@compileError("expected : " ++ @typeName(expectedType) ++
61+
", got: " ++ @typeName(@TypeOf(string)));
62+
}
63+
64+
return @bitCast(@as(*const [byteLength]u8, string).*);
65+
}
66+
67+
fn AsUintReturn(comptime string: anytype) type {
68+
return @Type(.{
69+
.Int = .{
70+
.bits = @bitSizeOf(@TypeOf(string.*)) - 8, // (- 8) to exclude sentinel 0
71+
.signedness = .unsigned,
72+
},
73+
});
74+
}
75+
5576
const testing = std.testing;
5677
test "parser.Reader: skip" {
5778
var r = Reader{ .data = "foo" };
@@ -85,3 +106,20 @@ test "parser.Reader: until" {
85106
try testing.expectEqualStrings("", r.until('.'));
86107
try testing.expectEqualStrings("", r.tail());
87108
}
109+
110+
test "parser: asUint" {
111+
const ASCII_x = @as(u8, @bitCast([1]u8{'x'}));
112+
const ASCII_ab = @as(u16, @bitCast([2]u8{ 'a', 'b' }));
113+
const ASCII_xyz = @as(u24, @bitCast([3]u8{ 'x', 'y', 'z' }));
114+
const ASCII_abcd = @as(u32, @bitCast([4]u8{ 'a', 'b', 'c', 'd' }));
115+
116+
try testing.expectEqual(ASCII_x, asUint("x"));
117+
try testing.expectEqual(ASCII_ab, asUint("ab"));
118+
try testing.expectEqual(ASCII_xyz, asUint("xyz"));
119+
try testing.expectEqual(ASCII_abcd, asUint("abcd"));
120+
121+
try testing.expectEqual(u8, @TypeOf(asUint("x")));
122+
try testing.expectEqual(u16, @TypeOf(asUint("ab")));
123+
try testing.expectEqual(u24, @TypeOf(asUint("xyz")));
124+
try testing.expectEqual(u32, @TypeOf(asUint("abcd")));
125+
}

0 commit comments

Comments
 (0)