#reference counting?

1 messages · Page 1 of 1 (latest)

quaint rune
#

My project is getting larger, and suddenly some of the assumptions I made about who should own a pointer/who allocs it/who deallocs it were wrong. I'm working on restructuring things to make it more explicit, but I can't help but wonder...

is there a generic-ish reference counting pointer pattern that people use in zig? it'd be really nice to just call retain/release on some of these complicated graphs of objects.

half kelp
half kelp
#

☝️ its untested and still very crude, but maybe you can make something useful with it. i've wanted something similar before myself.

#

one thought i had: it might make sense to use this with a std.SegmentedList(T) so that the list could grow while maintaining pointer stability.

#

not sure what a nice api would look like yet though.

quaint rune
#

I'm not sure I'm in love with storing the ref_count in the pointer itself like this. I know its almost a time honored tradition and things like this have been done before, but i've also certainly got enough memory to store it in its own word.

but I guess it does make the API simpler...

oak raven
#

wrappers

fn RefCounted(comptime T: type) type {
    return struct {
        value: T,
        ref_count: usize,
        allocator: std.mem.Allocator,
    };
}

pub fn create(allocator: std.mem.Allocator, comptime T: type) !*T {
    const rc = try allocator.create(RefCounted(T));
    rc.ref_count = 1;
    rc.allocator = allocator;
    return &rc.value;
}

pub fn retain(value_ptr: anytype) void {
    const rc = @fieldParentPtr(RefCounted(@TypeOf(value_ptr.*)), "value", value_ptr);
    rc.ref_count += 1;
}

pub fn release(value_ptr: anytype) void {
    const rc = @fieldParentPtr(RefCounted(@TypeOf(value_ptr.*)), "value", value_ptr);
    rc.ref_count -= 1;
    if (rc.ref_count == 0) rc.allocator.destroy(rc);
}
quaint rune
#

whoa, fieldParentPtr.