diff options
| author | 2025-04-30 20:30:39 -0400 | |
|---|---|---|
| committer | 2025-04-30 20:30:39 -0400 | |
| commit | 10048b0d31d0db923ae39c6bbd67139ed6252f6f (patch) | |
| tree | 65df1666aacd102f59b4ac0844ccc7f7ddda91db /src/CanonData.zig | |
| parent | Setup variants for all allocating modules (diff) | |
| download | zg-10048b0d31d0db923ae39c6bbd67139ed6252f6f.tar.gz zg-10048b0d31d0db923ae39c6bbd67139ed6252f6f.tar.xz zg-10048b0d31d0db923ae39c6bbd67139ed6252f6f.zip | |
Allocation Failure Tests
These turned up an excessive amount of allocations in CanonData and
CompatData, which have been reduced to two through the somewhat
squirrely use of 'magic numbers'.
There are now allocation tests for every allocated structure in the
library, and they run to completion in a reasonable amount of time.
So, that's nice.
Diffstat (limited to 'src/CanonData.zig')
| -rw-r--r-- | src/CanonData.zig | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/CanonData.zig b/src/CanonData.zig index d95a5be..5d2332a 100644 --- a/src/CanonData.zig +++ b/src/CanonData.zig | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | nfc: std.AutoHashMapUnmanaged([2]u21, u21), | 3 | nfc: std.AutoHashMapUnmanaged([2]u21, u21), |
| 4 | nfd: [][]u21 = undefined, | 4 | nfd: [][]u21 = undefined, |
| 5 | cps: []u21 = undefined, | ||
| 5 | 6 | ||
| 6 | const CanonData = @This(); | 7 | const CanonData = @This(); |
| 7 | 8 | ||
| @@ -17,23 +18,29 @@ pub fn init(allocator: mem.Allocator) !CanonData { | |||
| 17 | .nfc = .empty, | 18 | .nfc = .empty, |
| 18 | .nfd = try allocator.alloc([]u21, 0x110000), | 19 | .nfd = try allocator.alloc([]u21, 0x110000), |
| 19 | }; | 20 | }; |
| 20 | var _cp: u24 = undefined; | 21 | { |
| 22 | errdefer allocator.free(cdata.nfd); | ||
| 23 | cdata.cps = try allocator.alloc(u21, magic.canon_size); | ||
| 24 | } | ||
| 25 | |||
| 26 | var total_cp: u24 = undefined; | ||
| 21 | 27 | ||
| 22 | errdefer { | 28 | errdefer { |
| 23 | cdata.nfc.deinit(allocator); | 29 | cdata.nfc.deinit(allocator); |
| 24 | for (cdata.nfd[0.._cp]) |slice| allocator.free(slice); | 30 | allocator.free(cdata.cps); |
| 25 | allocator.free(cdata.nfd); | 31 | allocator.free(cdata.nfd); |
| 26 | } | 32 | } |
| 27 | 33 | ||
| 28 | @memset(cdata.nfd, &.{}); | 34 | @memset(cdata.nfd, &.{}); |
| 29 | 35 | ||
| 36 | var total_len: usize = 0; | ||
| 37 | |||
| 30 | while (true) { | 38 | while (true) { |
| 31 | const len: u8 = try reader.readInt(u8, endian); | 39 | const len: u8 = try reader.readInt(u8, endian); |
| 32 | if (len == 0) break; | 40 | if (len == 0) break; |
| 33 | const cp = try reader.readInt(u24, endian); | 41 | const cp = try reader.readInt(u24, endian); |
| 34 | _cp = cp; | 42 | total_cp = cp; |
| 35 | const nfd_cp = try allocator.alloc(u21, len - 1); | 43 | const nfd_cp = cdata.cps[total_len..][0 .. len - 1]; |
| 36 | errdefer allocator.free(nfd_cp); | ||
| 37 | for (0..len - 1) |i| { | 44 | for (0..len - 1) |i| { |
| 38 | nfd_cp[i] = @intCast(try reader.readInt(u24, endian)); | 45 | nfd_cp[i] = @intCast(try reader.readInt(u24, endian)); |
| 39 | } | 46 | } |
| @@ -41,14 +48,17 @@ pub fn init(allocator: mem.Allocator) !CanonData { | |||
| 41 | try cdata.nfc.put(allocator, nfd_cp[0..2].*, @intCast(cp)); | 48 | try cdata.nfc.put(allocator, nfd_cp[0..2].*, @intCast(cp)); |
| 42 | } | 49 | } |
| 43 | cdata.nfd[cp] = nfd_cp; | 50 | cdata.nfd[cp] = nfd_cp; |
| 51 | total_len += len - 1; | ||
| 44 | } | 52 | } |
| 45 | 53 | ||
| 54 | if (comptime magic.print) std.debug.print("CanonData magic number: {d}\n", .{total_len}); | ||
| 55 | |||
| 46 | return cdata; | 56 | return cdata; |
| 47 | } | 57 | } |
| 48 | 58 | ||
| 49 | pub fn deinit(cdata: *CanonData, allocator: mem.Allocator) void { | 59 | pub fn deinit(cdata: *CanonData, allocator: mem.Allocator) void { |
| 50 | cdata.nfc.deinit(allocator); | 60 | cdata.nfc.deinit(allocator); |
| 51 | for (cdata.nfd) |slice| allocator.free(slice); | 61 | allocator.free(cdata.cps); |
| 52 | allocator.free(cdata.nfd); | 62 | allocator.free(cdata.nfd); |
| 53 | } | 63 | } |
| 54 | 64 | ||
| @@ -66,3 +76,5 @@ const std = @import("std"); | |||
| 66 | const builtin = @import("builtin"); | 76 | const builtin = @import("builtin"); |
| 67 | const compress = std.compress; | 77 | const compress = std.compress; |
| 68 | const mem = std.mem; | 78 | const mem = std.mem; |
| 79 | const magic = @import("magic"); | ||
| 80 | const options = @import("options"); | ||