lib/deadalloc/src/class.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 
 3 pub const min_alignment: usize = 16;
 4 pub const page_size: usize = 4096;
 5 pub const max_small_size: usize = 1024 * 1024;
 6 
 7 pub const sizes = [_]usize{
 8     16,
 9     32,
10     64,
11     128,
12     256,
13     512,
14     1024,
15     2048,
16     4096,
17     8192,
18     16384,
19     32768,
20     65536,
21     131072,
22     262144,
23     524288,
24     1048576,
25 };
26 
27 pub const count = sizes.len;
28 
29 pub fn indexFor(len: usize, alignment: std.mem.Alignment) ?usize {
30     const requested_len = @max(len, min_alignment);
31     if (requested_len > max_small_size) return null;
32 
33     const requested_alignment = @max(alignment.toByteUnits(), min_alignment);
34     for (sizes, 0..) |class_size, index| {
35         if (class_size >= requested_len and class_size >= requested_alignment) return index;
36     }
37     return null;
38 }
39 
40 pub fn size(index: usize) usize {
41     return sizes[index];
42 }
43 
44 pub fn nextPowerOfTwo(value: usize) ?usize {
45     if (value == 0) return 1;
46     if (value > (std.math.maxInt(usize) >> 1) + 1) return null;
47     return std.math.ceilPowerOfTwo(usize, value) catch null;
48 }
49 
50 test "classes are powers of two and cover the small range" {
51     var previous: usize = 0;
52     for (sizes) |class_size| {
53         try std.testing.expect(class_size > previous);
54         try std.testing.expect(std.math.isPowerOfTwo(class_size));
55         previous = class_size;
56     }
57     try std.testing.expectEqual(max_small_size, sizes[sizes.len - 1]);
58 }
59 
60 test "lookup respects requested size and alignment" {
61     inline for (.{ 1, 8, 16, 32, 4096, 65536 }) |alignment| {
62         var len: usize = 1;
63         while (len <= max_small_size) : (len *= 2) {
64             const index = indexFor(len, .fromByteUnits(alignment)) orelse return error.MissingClass;
65             const class_size = size(index);
66             try std.testing.expect(class_size >= len);
67             try std.testing.expect(class_size >= @max(alignment, min_alignment));
68         }
69     }
70 }