Skip to content

Instantly share code, notes, and snippets.

@andrewgotow
Last active January 15, 2026 04:54
Show Gist options
  • Select an option

  • Save andrewgotow/e66ec493e4aedfb8f47287f5203d7e2b to your computer and use it in GitHub Desktop.

Select an option

Save andrewgotow/e66ec493e4aedfb8f47287f5203d7e2b to your computer and use it in GitHub Desktop.
Resource Linked List
#include <iostream>
#include <vector>
#include <algorithm>
struct Resource;
struct ListLink {
Resource* ptr;
unsigned idx;
ListLink()
: ptr(nullptr), idx(0)
{}
ListLink(Resource *ptr, unsigned idx)
: ptr(ptr), idx(idx)
{}
};
struct Resource {
std::vector<ListLink> links;
unsigned refCount = 0;
std::string name;
Resource(const std::string& name)
: name(name)
{}
ListLink AllocLink() {
// Find the first unused link in our vector of links.
for (unsigned idx = 0; idx < links.size(); ++idx) {
if (links[idx].ptr == nullptr)
return {this, idx};
}
// All links are currently in use! Push and return a new one!
links.emplace_back();
return {this, (unsigned)links.size()};
}
void IncRef() {
std::cout << "IncRef: " << name << "\n";
++refCount;
}
void DecRef() {
std::cout << "DecRef: " << name << "\n";
if (--refCount == 0)
delete this;
}
};
struct CommandBuffer {
ListLink refs;
void RefResource(Resource& res) {
res.IncRef();
// Allocate a "next" link within the resource.
// This link will be used as a "next pointer" in the linked resource list.
ListLink link = res.AllocLink();
// Now swap the current refs list with the allocated link.
// This will push the link into the front of the list.
res.links[link.idx] = refs;
refs = link;
}
void ReleaseAll() {
// Iterate over the list of links and decrement refs.
ListLink link = refs;
while (link.ptr)
{
Resource* res = link.ptr;
link = res->links[link.idx];
res->links[link.idx].ptr = nullptr;
res->DecRef();
}
}
};
int main() {
Resource resA("A");
Resource resB("B");
CommandBuffer cmdA;
CommandBuffer cmdB;
cmdA.RefResource(resA);
cmdB.RefResource(resA);
cmdA.RefResource(resB);
cmdB.ReleaseAll();
cmdA.ReleaseAll();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment