Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const std = @import("std");
- const SlabError = error{
- OutOfRange,
- SlotOccupied,
- EmptySlot,
- RemoveEmptySlot,
- };
- const SlabConfig = struct {
- safe: bool = true,
- storage: enum {
- dynamic,
- static,
- },
- size: comptime_int,
- };
- pub fn createSlab(comptime T: type, comptime cfg: SlabConfig) type {
- return struct {
- const Self = @This();
- allocator: std.mem.Allocator,
- data: switch (cfg.storage) {
- .dynamic => []?T,
- .static => [cfg.size]?T,
- },
- fn init(allocator: ?std.mem.Allocator) !Self {
- if (cfg.storage == .dynamic) {
- const alloc = allocator orelse @panic("Allocator is required for dynamic slab.");
- const data = try alloc.alloc(?T, cfg.size);
- @memset(data, null);
- return Self{
- .allocator = alloc,
- .data = data,
- };
- } else {
- return Self{
- .allocator = undefined,
- .data = @splat(null),
- };
- }
- }
- pub fn deinit(self: *Self, alloc: ?std.mem.Allocator) void {
- if (cfg.storage == .dynamic) {
- alloc.?.free(self.data);
- }
- }
- inline fn checkOutOfRage(self: *Self, index: usize) !void {
- if (cfg.safe and index >= self.data.len) return SlabError.OutOfRange;
- }
- pub fn insertAt(self: *Self, index: usize, value: T) SlabError!void {
- try self.checkOutOfRage(index);
- if (self.data[index] != null) return SlabError.SlotOccupied;
- self.data[index] = value;
- }
- pub fn remove(self: *Self, index: usize) SlabError!void {
- if (comptime cfg.safe and self.data[index] == null) return SlabError.RemoveEmptySlot;
- self.data[index] = null;
- }
- pub fn get(self: *Self, index: usize) SlabError!*T {
- try self.checkOutOfRage(index);
- const maybe = &(self.data[index] orelse return SlabError.EmptySlot);
- return maybe;
- }
- };
- }
- test "init static" {
- const Slab = createSlab(u32, .{ .storage = .static, .size = 3000, .safe = false });
- var slab = try Slab.init(null);
- try slab.insertAt(2500, 25);
- std.debug.print("{}\n", .{(try slab.get(2500)).*});
- }
- test "init dynamic" {
- const Slab = createSlab(u32, .{ .storage = .dynamic, .size = 3000, .safe = false });
- var slab = try Slab.init(std.testing.allocator);
- defer slab.deinit(std.testing.allocator);
- try slab.insertAt(2500, 25);
- std.debug.print("{}\n", .{(try slab.get(2500)).*});
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement