| ... | ... | @@ -68,17 +68,7 @@ pub const Headers = struct { |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | pub fn deinit(headers: *Headers) void { |
| 71 | | var it = headers.index.iterator(); |
| 72 | | while (it.next()) |entry| { |
| 73 | | entry.value_ptr.deinit(headers.allocator); |
| 74 | | |
| 75 | | if (headers.owned) headers.allocator.free(entry.key_ptr.*); |
| 76 | | } |
| 77 | | |
| 78 | | for (headers.list.items) |entry| { |
| 79 | | if (headers.owned) headers.allocator.free(entry.value); |
| 80 | | } |
| 81 | | |
| 71 | headers.deallocateIndexListsAndFields(); |
| 82 | 72 | headers.index.deinit(headers.allocator); |
| 83 | 73 | headers.list.deinit(headers.allocator); |
| 84 | 74 | |
| ... | ... | @@ -255,6 +245,39 @@ pub const Headers = struct { |
| 255 | 245 | |
| 256 | 246 | try out_stream.writeAll("\r\n"); |
| 257 | 247 | } |
| 248 | |
| 249 | /// Frees all `HeaderIndexList`s within `index` |
| 250 | /// Frees names and values of all fields if they are owned. |
| 251 | fn deallocateIndexListsAndFields(headers: *Headers) void { |
| 252 | var it = headers.index.iterator(); |
| 253 | while (it.next()) |entry| { |
| 254 | entry.value_ptr.deinit(headers.allocator); |
| 255 | |
| 256 | if (headers.owned) headers.allocator.free(entry.key_ptr.*); |
| 257 | } |
| 258 | |
| 259 | if (headers.owned) { |
| 260 | for (headers.list.items) |entry| { |
| 261 | headers.allocator.free(entry.value); |
| 262 | } |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | /// Clears and frees the underlying data structures. |
| 267 | /// Frees names and values if they are owned. |
| 268 | pub fn clearAndFree(headers: *Headers) void { |
| 269 | headers.deallocateIndexListsAndFields(); |
| 270 | headers.index.clearAndFree(headers.allocator); |
| 271 | headers.list.clearAndFree(headers.allocator); |
| 272 | } |
| 273 | |
| 274 | /// Clears the underlying data structures while retaining their capacities. |
| 275 | /// Frees names and values if they are owned. |
| 276 | pub fn clearRetainingCapacity(headers: *Headers) void { |
| 277 | headers.deallocateIndexListsAndFields(); |
| 278 | headers.index.clearRetainingCapacity(); |
| 279 | headers.list.clearRetainingCapacity(); |
| 280 | } |
| 258 | 281 | }; |
| 259 | 282 | |
| 260 | 283 | test "Headers.append" { |
| ... | ... | @@ -384,3 +407,42 @@ test "Headers consistency" { |
| 384 | 407 | try h.formatCommaSeparated("foo", writer); |
| 385 | 408 | try testing.expectEqualStrings("foo: bar, baz\r\n", fbs.getWritten()); |
| 386 | 409 | } |
| 410 | |
| 411 | test "Headers.clearRetainingCapacity and clearAndFree" { |
| 412 | var h = Headers.init(std.testing.allocator); |
| 413 | defer h.deinit(); |
| 414 | |
| 415 | h.clearRetainingCapacity(); |
| 416 | |
| 417 | try h.append("foo", "bar"); |
| 418 | try h.append("bar", "world"); |
| 419 | try h.append("foo", "baz"); |
| 420 | try h.append("baz", "hello"); |
| 421 | try testing.expectEqual(@as(usize, 4), h.list.items.len); |
| 422 | try testing.expectEqual(@as(usize, 3), h.index.count()); |
| 423 | const list_capacity = h.list.capacity; |
| 424 | const index_capacity = h.index.capacity(); |
| 425 | |
| 426 | h.clearRetainingCapacity(); |
| 427 | try testing.expectEqual(@as(usize, 0), h.list.items.len); |
| 428 | try testing.expectEqual(@as(usize, 0), h.index.count()); |
| 429 | try testing.expectEqual(list_capacity, h.list.capacity); |
| 430 | try testing.expectEqual(index_capacity, h.index.capacity()); |
| 431 | |
| 432 | try h.append("foo", "bar"); |
| 433 | try h.append("bar", "world"); |
| 434 | try h.append("foo", "baz"); |
| 435 | try h.append("baz", "hello"); |
| 436 | try testing.expectEqual(@as(usize, 4), h.list.items.len); |
| 437 | try testing.expectEqual(@as(usize, 3), h.index.count()); |
| 438 | // Capacity should still be the same since we shouldn't have needed to grow |
| 439 | // when adding back the same fields |
| 440 | try testing.expectEqual(list_capacity, h.list.capacity); |
| 441 | try testing.expectEqual(index_capacity, h.index.capacity()); |
| 442 | |
| 443 | h.clearAndFree(); |
| 444 | try testing.expectEqual(@as(usize, 0), h.list.items.len); |
| 445 | try testing.expectEqual(@as(usize, 0), h.index.count()); |
| 446 | try testing.expectEqual(@as(usize, 0), h.list.capacity); |
| 447 | try testing.expectEqual(@as(usize, 0), h.index.capacity()); |
| 448 | } |