diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig index cfb75f077ed7177f4ab21d2ce7819eddefd29cd3..3952ecb4b2052443a5057cece7bead1ef73f4596 100644 --- a/lib/std/hash_map.zig +++ b/lib/std/hash_map.zig @@ -24,6 +24,10 @@ pub fn StringHashMap(comptime V: type) type { return HashMap([]const u8, V, hashString, eqlString, true); } +pub fn StringHashMapUnmanaged(comptime V: type) type { + return HashMapUnmanaged([]const u8, V, hashString, eqlString, true); +} + pub fn eqlString(a: []const u8, b: []const u8) bool { return mem.eql(u8, a, b); } diff --git a/lib/std/http/headers.zig b/lib/std/http/headers.zig index f5465d4151e3994c3133f4fa5cc9ab180e550706..86aff5f36443804af3c2303ecebf19ad86a5355c 100644 --- a/lib/std/http/headers.zig +++ b/lib/std/http/headers.zig @@ -27,7 +27,6 @@ fn never_index_default(name: []const u8) bool { } const HeaderEntry = struct { - allocator: *Allocator, name: []const u8, value: []u8, never_index: bool, @@ -36,23 +35,22 @@ const HeaderEntry = struct { fn init(allocator: *Allocator, name: []const u8, value: []const u8, never_index: ?bool) !Self { return Self{ - .allocator = allocator, .name = name, // takes reference .value = try allocator.dupe(u8, value), .never_index = never_index orelse never_index_default(name), }; } - fn deinit(self: Self) void { - self.allocator.free(self.value); + fn deinit(self: Self, allocator: *Allocator) void { + allocator.free(self.value); } - pub fn modify(self: *Self, value: []const u8, never_index: ?bool) !void { + pub fn modify(self: *Self, allocator: *Allocator, value: []const u8, never_index: ?bool) !void { const old_len = self.value.len; if (value.len > old_len) { - self.value = try self.allocator.realloc(self.value, value.len); + self.value = try allocator.realloc(self.value, value.len); } else if (value.len < old_len) { - self.value = self.allocator.shrink(self.value, value.len); + self.value = allocator.shrink(self.value, value.len); } mem.copy(u8, self.value, value); self.never_index = never_index orelse never_index_default(self.name); @@ -85,22 +83,22 @@ const HeaderEntry = struct { test "HeaderEntry" { var e = try HeaderEntry.init(testing.allocator, "foo", "bar", null); - defer e.deinit(); + defer e.deinit(testing.allocator); testing.expectEqualSlices(u8, "foo", e.name); testing.expectEqualSlices(u8, "bar", e.value); testing.expectEqual(false, e.never_index); - try e.modify("longer value", null); + try e.modify(testing.allocator, "longer value", null); testing.expectEqualSlices(u8, "longer value", e.value); // shorter value - try e.modify("x", null); + try e.modify(testing.allocator, "x", null); testing.expectEqualSlices(u8, "x", e.value); } -const HeaderList = std.ArrayList(HeaderEntry); -const HeaderIndexList = std.ArrayList(usize); -const HeaderIndex = std.StringHashMap(HeaderIndexList); +const HeaderList = std.ArrayListUnmanaged(HeaderEntry); +const HeaderIndexList = std.ArrayListUnmanaged(usize); +const HeaderIndex = std.StringHashMapUnmanaged(HeaderIndexList); pub const Headers = struct { // the owned header field name is stored in the index as part of the key @@ -113,8 +111,8 @@ pub const Headers = struct { pub fn init(allocator: *Allocator) Self { return Self{ .allocator = allocator, - .data = HeaderList.init(allocator), - .index = HeaderIndex.init(allocator), + .data = HeaderList{}, + .index = HeaderIndex{}, }; } @@ -122,16 +120,16 @@ pub const Headers = struct { { for (self.index.items()) |*entry| { const dex = &entry.value; - dex.deinit(); + dex.deinit(self.allocator); self.allocator.free(entry.key); } - self.index.deinit(); + self.index.deinit(self.allocator); } { - for (self.data.span()) |entry| { - entry.deinit(); + for (self.data.items) |entry| { + entry.deinit(self.allocator); } - self.data.deinit(); + self.data.deinit(self.allocator); } self.* = undefined; } @@ -139,36 +137,36 @@ pub const Headers = struct { pub fn clone(self: Self, allocator: *Allocator) !Self { var other = Headers.init(allocator); errdefer other.deinit(); - try other.data.ensureCapacity(self.data.items.len); - try other.index.initCapacity(self.index.entries.len); - for (self.data.span()) |entry| { + try other.data.ensureCapacity(allocator, self.data.items.len); + try other.index.initCapacity(allocator, self.index.entries.len); + for (self.data.items) |entry| { try other.append(entry.name, entry.value, entry.never_index); } return other; } pub fn toSlice(self: Self) []const HeaderEntry { - return self.data.span(); + return self.data.items; } pub fn append(self: *Self, name: []const u8, value: []const u8, never_index: ?bool) !void { const n = self.data.items.len + 1; - try self.data.ensureCapacity(n); + try self.data.ensureCapacity(self.allocator, n); var entry: HeaderEntry = undefined; if (self.index.getEntry(name)) |kv| { entry = try HeaderEntry.init(self.allocator, kv.key, value, never_index); - errdefer entry.deinit(); + errdefer entry.deinit(self.allocator); const dex = &kv.value; - try dex.append(n - 1); + try dex.append(self.allocator, n - 1); } else { const name_dup = try self.allocator.dupe(u8, name); errdefer self.allocator.free(name_dup); entry = try HeaderEntry.init(self.allocator, name_dup, value, never_index); - errdefer entry.deinit(); - var dex = HeaderIndexList.init(self.allocator); - try dex.append(n - 1); - errdefer dex.deinit(); - _ = try self.index.put(name_dup, dex); + errdefer entry.deinit(self.allocator); + var dex = HeaderIndexList{}; + try dex.append(self.allocator, n - 1); + errdefer dex.deinit(self.allocator); + _ = try self.index.put(self.allocator, name_dup, dex); } self.data.appendAssumeCapacity(entry); } @@ -194,7 +192,7 @@ pub const Headers = struct { /// Returns boolean indicating if something was deleted. pub fn delete(self: *Self, name: []const u8) bool { - if (self.index.remove(name)) |kv| { + if (self.index.remove(name)) |*kv| { const dex = &kv.value; // iterate backwards var i = dex.items.len; @@ -203,9 +201,9 @@ pub const Headers = struct { const data_index = dex.items[i]; const removed = self.data.orderedRemove(data_index); assert(mem.eql(u8, removed.name, name)); - removed.deinit(); + removed.deinit(self.allocator); } - dex.deinit(); + dex.deinit(self.allocator); self.allocator.free(kv.key); self.rebuildIndex(); return true; @@ -225,14 +223,14 @@ pub const Headers = struct { const dex = &kv.value; if (dex.items.len == 1) { // was last item; delete the index - dex.deinit(); - removed.deinit(); + dex.deinit(self.allocator); + removed.deinit(self.allocator); const key = kv.key; _ = self.index.remove(key); // invalidates `kv` and `dex` self.allocator.free(key); } else { - dex.shrink(dex.items.len - 1); - removed.deinit(); + dex.shrink(self.allocator, dex.items.len - 1); + removed.deinit(self.allocator); } // if it was the last item; no need to rebuild index if (i != self.data.items.len) { @@ -250,14 +248,14 @@ pub const Headers = struct { const dex = &kv.value; if (dex.items.len == 1) { // was last item; delete the index - dex.deinit(); - removed.deinit(); + dex.deinit(self.allocator); + removed.deinit(self.allocator); const key = kv.key; _ = self.index.remove(key); // invalidates `kv` and `dex` self.allocator.free(key); } else { - dex.shrink(dex.items.len - 1); - removed.deinit(); + dex.shrink(self.allocator, dex.items.len - 1); + removed.deinit(self.allocator); } // if it was the last item; no need to rebuild index if (i != self.data.items.len) { @@ -282,7 +280,7 @@ pub const Headers = struct { const buf = try allocator.alloc(HeaderEntry, dex.items.len); var n: usize = 0; - for (dex.span()) |idx| { + for (dex.items) |idx| { buf[n] = self.data.items[idx]; n += 1; } @@ -305,7 +303,7 @@ pub const Headers = struct { // adapted from mem.join const total_len = blk: { var sum: usize = dex.items.len - 1; // space for separator(s) - for (dex.span()) |idx| + for (dex.items) |idx| sum += self.data.items[idx].value.len; break :blk sum; }; @@ -493,8 +491,8 @@ test "Headers.getIndices" { try h.append("set-cookie", "y=2", null); testing.expect(null == h.getIndices("not-present")); - testing.expectEqualSlices(usize, &[_]usize{0}, h.getIndices("foo").?.span()); - testing.expectEqualSlices(usize, &[_]usize{ 1, 2 }, h.getIndices("set-cookie").?.span()); + testing.expectEqualSlices(usize, &[_]usize{0}, h.getIndices("foo").?.items); + testing.expectEqualSlices(usize, &[_]usize{ 1, 2 }, h.getIndices("set-cookie").?.items); } test "Headers.get" { diff --git a/lib/std/std.zig b/lib/std/std.zig index be4aad5f0d9d44fb41fd724c94a9fafb1cea91b5..50aaef6f118e39062d8c31e4ae018e6f99b91d01 100644 --- a/lib/std/std.zig +++ b/lib/std/std.zig @@ -25,6 +25,7 @@ pub const SegmentedList = @import("segmented_list.zig").SegmentedList; pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList; pub const SpinLock = @import("spinlock.zig").SpinLock; pub const StringHashMap = hash_map.StringHashMap; +pub const StringHashMapUnmanaged = hash_map.StringHashMapUnmanaged; pub const TailQueue = @import("linked_list.zig").TailQueue; pub const Target = @import("target.zig").Target; pub const Thread = @import("thread.zig").Thread;