View difference between Paste ID: Zrmbxski and 1bTancwt
SHOW: | | - or go back to the newest paste.
1
2
const std = @import("std");
3
4
const SlabError = error{
5
    OutOfRange,
6
    SlotOccupied,
7
    EmptySlot,
8
    RemoveEmptySlot,
9
};
10
11
const SlabConfig = struct {
12-
    dynamic: bool = true,
12+
13
    storage: enum {
14
        dynamic,
15
        static,
16
    },
17
    size: comptime_int,
18
};
19
20-
        data: []?T,
20+
21
    return struct {
22-
        pub fn init(allocator: ?std.mem.Allocator) !Self {
22+
23-
            if (comptime cfg.dynamic) {
23+
24-
                if (allocator == null) @compileError("Allocator is required for dynamic slab.");
24+
25-
                const data = try allocator.?.alloc(?T, cfg.size);
25+
        data: switch (cfg.storage) {
26-
                for (data) |*slot| slot.* = null;
26+
            .dynamic => []?T,
27
            .static => [cfg.size]?T,
28-
                    .allocator = allocator.?,
28+
        },
29-
                    // .data = comptime @as(&T, &[_]?T{null} ** cfg.size),
29+
30
        fn init(allocator: ?std.mem.Allocator) !Self {
31
            if (cfg.storage == .dynamic) {
32
                const alloc = allocator orelse @panic("Allocator is required for dynamic slab.");
33
                const data = try alloc.alloc(?T, cfg.size);
34-
                    .data = @memset(, elem),
34+
                @memset(data, null);
35
                return Self{
36
                    .allocator = alloc,
37
                    .data = data,
38
                };
39
            } else {
40
                return Self{
41
                    .allocator = undefined,
42
                    .data = @splat(null),
43
                };
44-
            try checkOutOfRage(index);
44+
45
        }
46
47
        pub fn deinit(self: *Self, alloc: ?std.mem.Allocator) void {
48
            if (cfg.storage == .dynamic) {
49
                alloc.?.free(self.data);
50
            }
51
        }
52
53
        inline fn checkOutOfRage(self: *Self, index: usize) !void {
54
            if (cfg.safe and index >= self.data.len) return SlabError.OutOfRange;
55-
            try checkOutOfRage(index);
55+
56
57-
            const maybe = self.data[index] orelse return SlabError.EmptySlot;
57+
58-
            return &maybe;
58+
            try self.checkOutOfRage(index);
59
            if (self.data[index] != null) return SlabError.SlotOccupied;
60
            self.data[index] = value;
61
        }
62
63-
test "init" {
63+
64-
    const Slab = createSlab(u32, .{ .dynamic = false, .size = 3000, .safe = false });
64+
65-
    const slab = try Slab.init(null);
65+
66
        }
67-
    std.debug.print("{}\n", .{slab.get(2500)});
67+
68
        pub fn get(self: *Self, index: usize) SlabError!*T {
69
            try self.checkOutOfRage(index);
70
71
            const maybe = &(self.data[index] orelse return SlabError.EmptySlot);
72
            return maybe;
73
        }
74
    };
75
}
76
77
test "init static" {
78
    const Slab = createSlab(u32, .{ .storage = .static, .size = 3000, .safe = false });
79
    var slab = try Slab.init(null);
80
    try slab.insertAt(2500, 25);
81
    std.debug.print("{}\n", .{(try slab.get(2500)).*});
82
}
83
84
test "init dynamic" {
85
    const Slab = createSlab(u32, .{ .storage = .dynamic, .size = 3000, .safe = false });
86
87
    var slab = try Slab.init(std.testing.allocator);
88
    defer slab.deinit(std.testing.allocator);
89
90
    try slab.insertAt(2500, 25);
91
    std.debug.print("{}\n", .{(try slab.get(2500)).*});
92
}
93