aboutsummaryrefslogtreecommitdiff
path: root/src/blob.zig
blob: 65679978dd0b15b5e1dd9a1ebfbcc7d69ba406f7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
const std = @import("std");
const Lock = @import("./lock.zig").Lock;
const _global = @import("./global.zig");
const string = _global.string;
const Output = _global.Output;
const Global = _global.Global;
const Environment = _global.Environment;
const strings = _global.strings;
const MutableString = _global.MutableString;
const stringZ = _global.stringZ;
const default_allocator = _global.default_allocator;
const C = _global.C;

const Blob = @This();

ptr: [*]const u8,
len: usize,

pub const Map = struct {
    const MapContext = struct {
        pub fn hash(_: @This(), s: u64) u32 {
            return @truncate(u32, s);
        }
        pub fn eql(_: @This(), a: u64, b: u64) bool {
            return a == b;
        }
    };

    const HashMap = std.ArrayHashMap(u64, Blob, MapContext, false);
    lock: Lock,
    map: HashMap,
    allocator: std.mem.Allocator,

    pub fn init(allocator: std.mem.Allocator) Map {
        return Map{
            .lock = Lock.init(),
            .map = HashMap.init(allocator),
            .allocator = allocator,
        };
    }

    pub fn get(this: *Map, key: string) ?Blob {
        this.lock.lock();
        defer this.lock.unlock();
        return this.map.get(std.hash.Wyhash.hash(0, key));
    }

    pub fn put(this: *Map, key: string, blob: Blob) !void {
        this.lock.lock();
        defer this.lock.unlock();

        return try this.map.put(std.hash.Wyhash.hash(0, key), blob);
    }

    pub fn reset(this: *Map) !void {
        this.lock.lock();
        defer this.lock.unlock();
        this.map.clearRetainingCapacity();
    }
};

pub const Group = struct {
    persistent: Map,
    temporary: Map,
    allocator: std.mem.Allocator,

    pub fn init(allocator: std.mem.Allocator) !*Group {
        var group = try allocator.create(Group);
        group.* = Group{ .persistent = Map.init(allocator), .temporary = Map.init(allocator), .allocator = allocator };
        return group;
    }

    pub fn get(this: *Group, key: string) ?Blob {
        return this.temporary.get(key) orelse this.persistent.get(key);
    }
};