Skip to content

Commit d762688

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 1594f14 commit d762688

File tree

2 files changed

+305
-119
lines changed

2 files changed

+305
-119
lines changed

src/str/parser.zig

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,27 @@ pub const Reader = struct {
4848
}
4949
};
5050

51+
// converts a comptime-known string (i.e. null terminated) to an uint
52+
pub fn asUint(comptime string: anytype) AsUintReturn(string) {
53+
const byteLength = @bitSizeOf(@TypeOf(string.*)) / 8 - 1;
54+
const expectedType = *const [byteLength:0]u8;
55+
if (@TypeOf(string) != expectedType) {
56+
@compileError("expected : " ++ @typeName(expectedType) ++
57+
", got: " ++ @typeName(@TypeOf(string)));
58+
}
59+
60+
return @bitCast(@as(*const [byteLength]u8, string).*);
61+
}
62+
63+
fn AsUintReturn(comptime string: anytype) type {
64+
return @Type(.{
65+
.Int = .{
66+
.bits = @bitSizeOf(@TypeOf(string.*)) - 8, // (- 8) to exclude sentinel 0
67+
.signedness = .unsigned,
68+
},
69+
});
70+
}
71+
5172
test "Reader.skip" {
5273
var r = Reader{ .s = "foo" };
5374
try testing.expect(r.skip());
@@ -104,3 +125,20 @@ test "trim" {
104125
try testing.expectEqualStrings("foo", trim(" \n\tfoo"));
105126
try testing.expectEqualStrings("foo", trim("foo \n\t"));
106127
}
128+
129+
test "parser: asUint" {
130+
const ASCII_x = @as(u8, @bitCast([1]u8{'x'}));
131+
const ASCII_ab = @as(u16, @bitCast([2]u8{ 'a', 'b' }));
132+
const ASCII_xyz = @as(u24, @bitCast([3]u8{ 'x', 'y', 'z' }));
133+
const ASCII_abcd = @as(u32, @bitCast([4]u8{ 'a', 'b', 'c', 'd' }));
134+
135+
try testing.expectEqual(ASCII_x, asUint("x"));
136+
try testing.expectEqual(ASCII_ab, asUint("ab"));
137+
try testing.expectEqual(ASCII_xyz, asUint("xyz"));
138+
try testing.expectEqual(ASCII_abcd, asUint("abcd"));
139+
140+
try testing.expectEqual(u8, @TypeOf(asUint("x")));
141+
try testing.expectEqual(u16, @TypeOf(asUint("ab")));
142+
try testing.expectEqual(u24, @TypeOf(asUint("xyz")));
143+
try testing.expectEqual(u32, @TypeOf(asUint("abcd")));
144+
}

0 commit comments

Comments
 (0)