summaryrefslogtreecommitdiff
path: root/src/CanonData.zig
diff options
context:
space:
mode:
authorGravatar Sam Atman2025-04-30 20:30:39 -0400
committerGravatar Sam Atman2025-04-30 20:30:39 -0400
commit10048b0d31d0db923ae39c6bbd67139ed6252f6f (patch)
tree65df1666aacd102f59b4ac0844ccc7f7ddda91db /src/CanonData.zig
parentSetup variants for all allocating modules (diff)
downloadzg-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.zig24
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
3nfc: std.AutoHashMapUnmanaged([2]u21, u21), 3nfc: std.AutoHashMapUnmanaged([2]u21, u21),
4nfd: [][]u21 = undefined, 4nfd: [][]u21 = undefined,
5cps: []u21 = undefined,
5 6
6const CanonData = @This(); 7const 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
49pub fn deinit(cdata: *CanonData, allocator: mem.Allocator) void { 59pub 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");
66const builtin = @import("builtin"); 76const builtin = @import("builtin");
67const compress = std.compress; 77const compress = std.compress;
68const mem = std.mem; 78const mem = std.mem;
79const magic = @import("magic");
80const options = @import("options");