@@ -30,21 +30,26 @@ const Headers = @This();
3030// This allows us to avoid having to allocate lowercase keys all the time.
3131const HeaderHashMap = std .HashMapUnmanaged ([]const u8 , []const u8 , struct {
3232 pub fn hash (_ : @This (), s : []const u8 ) u64 {
33+ var buf : [64 ]u8 = undefined ;
3334 var hasher = std .hash .Wyhash .init (s .len );
34- for (s ) | c | {
35- hasher .update (&.{std .ascii .toLower (c )});
35+
36+ var key = s ;
37+ while (key .len >= 64 ) {
38+ const lower = std .ascii .lowerString (buf [0.. ], key [0.. 64]);
39+ hasher .update (lower );
40+ key = key [64.. ];
41+ }
42+
43+ if (key .len > 0 ) {
44+ const lower = std .ascii .lowerString (buf [0.. key .len ], key );
45+ hasher .update (lower );
3646 }
3747
3848 return hasher .final ();
3949 }
40- pub fn eql (_ : @This (), a : []const u8 , b : []const u8 ) bool {
41- if (a .len != b .len ) return false ;
42-
43- for (a , b ) | c1 , c2 | {
44- if (std .ascii .toLower (c1 ) != std .ascii .toLower (c2 )) return false ;
45- }
4650
47- return true ;
51+ pub fn eql (_ : @This (), a : []const u8 , b : []const u8 ) bool {
52+ return std .ascii .eqlIgnoreCase (a , b );
4853 }
4954}, 80 );
5055
@@ -103,17 +108,15 @@ pub fn clone(self: *const Headers, allocator: std.mem.Allocator) !Headers {
103108}
104109
105110pub fn append (self : * Headers , name : []const u8 , value : []const u8 , allocator : std.mem.Allocator ) ! void {
106- if (self .headers .getEntry (name )) | entry | {
111+ const gop = try self .headers .getOrPut (allocator , name );
112+
113+ if (gop .found_existing ) {
107114 // If we found it, append the value.
108- const new_value = try std .fmt .allocPrint (allocator , "{s}, {s}" , .{ entry .value_ptr .* , value });
109- entry .value_ptr .* = new_value ;
115+ const new_value = try std .fmt .allocPrint (allocator , "{s}, {s}" , .{ gop .value_ptr .* , value });
116+ gop .value_ptr .* = new_value ;
110117 } else {
111118 // Otherwise, we should just put it in.
112- try self .headers .putNoClobber (
113- allocator ,
114- try allocator .dupe (u8 , name ),
115- try allocator .dupe (u8 , value ),
116- );
119+ gop .value_ptr .* = try allocator .dupe (u8 , value );
117120 }
118121}
119122
@@ -152,10 +155,8 @@ pub fn _forEach(self: *Headers, callback_fn: Env.Function, this_arg: ?Env.JsObje
152155 }
153156}
154157
155- pub fn _get (self : * const Headers , name : []const u8 , page : * Page ) ! ? []const u8 {
156- const arena = page .arena ;
157- const value = (self .headers .getEntry (name ) orelse return null ).value_ptr .* ;
158- return try arena .dupe (u8 , value );
158+ pub fn _get (self : * const Headers , name : []const u8 ) ? []const u8 {
159+ return self .headers .get (name );
159160}
160161
161162pub fn _has (self : * const Headers , name : []const u8 ) bool {
@@ -167,17 +168,8 @@ pub fn _has(self: *const Headers, name: []const u8) bool {
167168pub fn _set (self : * Headers , name : []const u8 , value : []const u8 , page : * Page ) ! void {
168169 const arena = page .arena ;
169170
170- if (self .headers .getEntry (name )) | entry | {
171- // If we found it, set the value.
172- entry .value_ptr .* = try arena .dupe (u8 , value );
173- } else {
174- // Otherwise, we should just put it in.
175- try self .headers .putNoClobber (
176- arena ,
177- try arena .dupe (u8 , name ),
178- try arena .dupe (u8 , value ),
179- );
180- }
171+ const gop = try self .headers .getOrPut (arena , name );
172+ gop .value_ptr .* = try arena .dupe (u8 , value );
181173}
182174
183175// TODO: values iterator
0 commit comments