Skip to content

Instantly share code, notes, and snippets.

@andrewgotow
Created January 16, 2026 23:06
Show Gist options
  • Select an option

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

Select an option

Save andrewgotow/e8b4e1a1ed0a4ff6e5314c64202da3bc to your computer and use it in GitHub Desktop.
Resource Linked List
#include <iostream>
#include <vector>
#include <algorithm>
struct Resource;
struct ListLink {
Resource* item;
unsigned slot;
bool used;
ListLink()
: item(nullptr), slot(0), used(false)
{}
ListLink(Resource *item, unsigned slot, bool used = false)
: item(item), slot(slot), used(used)
{}
};
struct Resource {
std::string name;
std::vector<ListLink> links;
unsigned refCount = 0;
Resource(const std::string& name)
: name(name)
{}
unsigned AllocSlot() {
// Find the first unused link in our vector of links.
for (size_t slot = 0; slot < links.size(); ++slot)
{
if (links[slot].used == true)
continue;
return slot;
}
// All links are currently in use! Push and return a new one!
links.emplace_back();
return links.size()-1;
}
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();
unsigned slot = res.AllocSlot();
res.links[slot] = refs;
refs.item = &res;
refs.slot = slot;
refs.used = true;
}
void ReleaseAll() {
ListLink& link = refs;
while (link.item)
{
Resource* res = link.item;
link.used = false;
link = link.item->links[link.slot];
res->DecRef();
}
}
};
int main() {
Resource resA("A");
Resource resB("B");
Resource resC("C");
CommandBuffer cmdA;
CommandBuffer cmdB;
cmdA.RefResource(resA);
cmdA.RefResource(resB);
cmdB.RefResource(resA);
cmdB.RefResource(resC);
cmdA.ReleaseAll();
cmdB.ReleaseAll();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment