rename all 'buckets' -> 'bins'

This commit is contained in:
jacob 2025-02-25 12:03:13 -06:00
parent 50da5f1bc6
commit a6d103f391
12 changed files with 251 additions and 251 deletions

View File

@ -29,8 +29,8 @@
#define IMAGE_PIXELS_PER_UNIT 256.0
/* 256^2 = 65536 buckets */
#define SPACE_CELL_BUCKETS_SQRT (256)
/* 64^2 = 4096 bins */
#define SPACE_CELL_BINS_SQRT (64)
#define SPACE_CELL_SIZE 1.0f
#define SIM_TICKS_PER_SECOND 50

View File

@ -26,8 +26,8 @@
#define PACKET_MSG_CHUNK_MAX_LEN 1024
#define PACKET_DATA_MAX_LEN 1280 /* Give enough space for msg chunk + header */
#define NUM_CHANNEL_LOOKUP_BUCKETS 512
#define NUM_MSG_ASSEMBLER_LOOKUP_BUCKETS 16384
#define NUM_CHANNEL_LOOKUP_BINS 512
#define NUM_MSG_ASSEMBLER_LOOKUP_BINS 16384
enum host_packet_kind {
HOST_PACKET_KIND_NONE,
@ -91,7 +91,7 @@ struct host_channel_list {
struct host_channel_node *last;
};
struct host_channel_lookup_bucket {
struct host_channel_lookup_bin {
struct host_channel *first;
struct host_channel *last;
};
@ -143,7 +143,7 @@ struct host_msg_assembler {
u8 *chunk_data;
};
struct host_msg_assembler_lookup_bucket {
struct host_msg_assembler_lookup_bin {
struct host_msg_assembler *first;
struct host_msg_assembler *last;
};
@ -189,11 +189,11 @@ struct host *host_alloc(u16 listen_port)
host->channels = arena_dry_push(&host->channel_arena, struct host_channel);
host->num_channel_lookup_buckets = NUM_CHANNEL_LOOKUP_BUCKETS;
host->channel_lookup_buckets = arena_push_array_zero(&host->arena, struct host_channel_lookup_bucket, host->num_channel_lookup_buckets);
host->num_channel_lookup_bins = NUM_CHANNEL_LOOKUP_BINS;
host->channel_lookup_bins = arena_push_array_zero(&host->arena, struct host_channel_lookup_bin, host->num_channel_lookup_bins);
host->num_msg_assembler_lookup_buckets = NUM_MSG_ASSEMBLER_LOOKUP_BUCKETS;
host->msg_assembler_lookup_buckets = arena_push_array_zero(&host->arena, struct host_msg_assembler_lookup_bucket, host->num_msg_assembler_lookup_buckets);
host->num_msg_assembler_lookup_bins = NUM_MSG_ASSEMBLER_LOOKUP_BINS;
host->msg_assembler_lookup_bins = arena_push_array_zero(&host->arena, struct host_msg_assembler_lookup_bin, host->num_msg_assembler_lookup_bins);
host->sock = sock_alloc(listen_port, MEGABYTE(2), MEGABYTE(2));
@ -234,8 +234,8 @@ INTERNAL u64 hash_from_address(struct sock_address address)
INTERNAL struct host_channel *host_channel_from_address(struct host *host, struct sock_address address)
{
u64 hash = hash_from_address(address);
struct host_channel_lookup_bucket *bucket = &host->channel_lookup_buckets[hash % host->num_channel_lookup_buckets];
for (struct host_channel *channel = bucket->first; channel; channel = channel->next_address_hash) {
struct host_channel_lookup_bin *bin = &host->channel_lookup_bins[hash % host->num_channel_lookup_bins];
for (struct host_channel *channel = bin->first; channel; channel = channel->next_address_hash) {
if (channel->address_hash == hash && sock_address_eq(channel->address, address)) {
return channel;
}
@ -307,15 +307,15 @@ INTERNAL struct host_channel *host_channel_alloc(struct host *host, struct sock_
u64 address_hash = hash_from_address(address);
channel->address_hash = address_hash;
u64 bucket_index = address_hash % host->num_channel_lookup_buckets;
struct host_channel_lookup_bucket *bucket = &host->channel_lookup_buckets[bucket_index];
if (bucket->last) {
channel->prev_address_hash = bucket->last;
bucket->last->next_address_hash = channel;
u64 bin_index = address_hash % host->num_channel_lookup_bins;
struct host_channel_lookup_bin *bin = &host->channel_lookup_bins[bin_index];
if (bin->last) {
channel->prev_address_hash = bin->last;
bin->last->next_address_hash = channel;
} else {
bucket->first = channel;
bin->first = channel;
}
bucket->last = channel;
bin->last = channel;
return channel;
}
@ -326,18 +326,18 @@ INTERNAL void host_channel_release(struct host_channel *channel)
/* Release from lookup table */
{
struct host_channel_lookup_bucket *bucket = &host->channel_lookup_buckets[channel->address_hash % host->num_channel_lookup_buckets];
struct host_channel_lookup_bin *bin = &host->channel_lookup_bins[channel->address_hash % host->num_channel_lookup_bins];
struct host_channel *prev = channel->prev_address_hash;
struct host_channel *next = channel->next_address_hash;
if (prev) {
prev->next_address_hash = next;
} else {
bucket->first = next;
bin->first = next;
}
if (next) {
next->prev_address_hash = prev;
} else {
bucket->last = prev;
bin->last = prev;
}
}
@ -379,8 +379,8 @@ INTERNAL u64 hash_from_channel_msg(struct host_channel_id channel_id, u64 msg_id
INTERNAL struct host_msg_assembler *host_get_msg_assembler(struct host *host, struct host_channel_id channel_id, u64 msg_id)
{
u64 hash = hash_from_channel_msg(channel_id, msg_id);
struct host_msg_assembler_lookup_bucket *bucket = &host->msg_assembler_lookup_buckets[hash % host->num_msg_assembler_lookup_buckets];
for (struct host_msg_assembler *ma = bucket->first; ma; ma = ma->next_hash) {
struct host_msg_assembler_lookup_bin *bin = &host->msg_assembler_lookup_bins[hash % host->num_msg_assembler_lookup_bins];
for (struct host_msg_assembler *ma = bin->first; ma; ma = ma->next_hash) {
if (ma->hash == hash && host_channel_id_eq(ma->channel->id, channel_id) && ma->msg_id == msg_id) {
return ma;
}
@ -435,14 +435,14 @@ INTERNAL struct host_msg_assembler *host_msg_assembler_alloc(struct host_channel
/* Insert into lookup table */
u64 hash = hash_from_channel_msg(channel->id, msg_id);
ma->hash = hash;
struct host_msg_assembler_lookup_bucket *bucket = &host->msg_assembler_lookup_buckets[hash % host->num_msg_assembler_lookup_buckets];
if (bucket->last) {
bucket->last->next_hash = ma;
ma->prev_hash = bucket->last;
struct host_msg_assembler_lookup_bin *bin = &host->msg_assembler_lookup_bins[hash % host->num_msg_assembler_lookup_bins];
if (bin->last) {
bin->last->next_hash = ma;
ma->prev_hash = bin->last;
} else {
bucket->first = ma;
bin->first = ma;
}
bucket->last = ma;
bin->last = ma;
return ma;
}
@ -470,19 +470,19 @@ INTERNAL void host_msg_assembler_release(struct host_msg_assembler *ma)
}
/* Release from lookup table */
struct host_msg_assembler_lookup_bucket *bucket = &host->msg_assembler_lookup_buckets[ma->hash % host->num_msg_assembler_lookup_buckets];
struct host_msg_assembler_lookup_bin *bin = &host->msg_assembler_lookup_bins[ma->hash % host->num_msg_assembler_lookup_bins];
{
struct host_msg_assembler *prev = ma->prev_hash;
struct host_msg_assembler *next = ma->next_hash;
if (prev) {
prev->next_hash = next;
} else {
bucket->first = next;
bin->first = next;
}
if (next) {
next->prev_hash = prev;
} else {
bucket->last = prev;
bin->last = prev;
}
}

View File

@ -9,7 +9,7 @@
struct buddy_ctx;
struct host_snd_packet;
struct host_channel_lookup_bucket;
struct host_channel_lookup_bin;
struct host_rcv_buffer;
enum host_cmd_kind {
@ -81,11 +81,11 @@ struct host {
struct host_snd_packet *first_free_packet; /* Allocated in `arena` */
struct host_msg_assembler *first_free_msg_assembler; /* Allocated in `arena` */
struct host_channel_lookup_bucket *channel_lookup_buckets; /* Allocated in `arena` */
u64 num_channel_lookup_buckets;
struct host_channel_lookup_bin *channel_lookup_bins; /* Allocated in `arena` */
u64 num_channel_lookup_bins;
struct host_msg_assembler_lookup_bucket *msg_assembler_lookup_buckets; /* Allocated in `arena` */
u64 num_msg_assembler_lookup_buckets;
struct host_msg_assembler_lookup_bin *msg_assembler_lookup_bins; /* Allocated in `arena` */
u64 num_msg_assembler_lookup_bins;
/* Double buffer for incoming data */
struct sys_mutex rcv_buffer_write_mutex;

156
src/sim.c
View File

@ -23,9 +23,9 @@
* An ent is the smallest unit of simulation state.
*/
#define CLIENT_LOOKUP_BUCKETS 127
#define TICK_LOOKUP_BUCKETS 127
#define ID_LOOKUP_BUCKETS 4096
#define CLIENT_LOOKUP_BINS 127
#define TICK_LOOKUP_BINS 127
#define ID_LOOKUP_BINS 4096
/* ========================== *
* Startup
@ -102,8 +102,8 @@ struct sim_client_store *sim_client_store_alloc(void)
store->arena = arena;
}
store->valid = true;
store->num_client_lookup_buckets = CLIENT_LOOKUP_BUCKETS;
store->client_lookup_buckets = arena_push_array_zero(&store->arena, struct sim_client_lookup_bucket, store->num_client_lookup_buckets);
store->num_client_lookup_bins = CLIENT_LOOKUP_BINS;
store->client_lookup_bins = arena_push_array_zero(&store->arena, struct sim_client_lookup_bin, store->num_client_lookup_bins);
store->clients_arena = arena_alloc(GIGABYTE(64));
store->clients = arena_dry_push(&store->clients_arena, struct sim_client);
return store;
@ -148,8 +148,8 @@ struct sim_client *sim_client_alloc(struct sim_client_store *store)
client->handle = handle;
client->snapshots_arena = arena_alloc(GIGABYTE(8));
client->num_snapshot_lookup_buckets = TICK_LOOKUP_BUCKETS;
client->snapshot_lookup_buckets = arena_push_array_zero(&client->snapshots_arena, struct sim_snapshot_lookup_bucket, client->num_snapshot_lookup_buckets);
client->num_snapshot_lookup_bins = TICK_LOOKUP_BINS;
client->snapshot_lookup_bins = arena_push_array_zero(&client->snapshots_arena, struct sim_snapshot_lookup_bin, client->num_snapshot_lookup_bins);
return client;
}
@ -157,11 +157,11 @@ struct sim_client *sim_client_alloc(struct sim_client_store *store)
void sim_client_release(struct sim_client *client)
{
/* Release internal snapshot memory */
for (u64 i = 0; i < client->num_snapshot_lookup_buckets; ++i) {
struct sim_snapshot_lookup_bucket *bucket = &client->snapshot_lookup_buckets[i];
struct sim_snapshot *ss = bucket->first;
for (u64 i = 0; i < client->num_snapshot_lookup_bins; ++i) {
struct sim_snapshot_lookup_bin *bin = &client->snapshot_lookup_bins[i];
struct sim_snapshot *ss = bin->first;
while (ss) {
struct sim_snapshot *next = ss->next_in_bucket;
struct sim_snapshot *next = ss->next_in_bin;
arena_release(&ss->ents_arena);
arena_release(&ss->arena);
ss = next;
@ -197,19 +197,19 @@ void sim_client_set_channel_id(struct sim_client *client, struct host_channel_id
/* Remove old channel id from channel lookup */
if (!host_channel_id_is_nil(old_channel_id)) {
u64 bucket_index = client->channel_hash % store->num_client_lookup_buckets;
struct sim_client_lookup_bucket *bucket = &store->client_lookup_buckets[bucket_index];
struct sim_client *prev = sim_client_from_handle(store, client->prev_in_bucket);
struct sim_client *next = sim_client_from_handle(store, client->next_in_bucket);
u64 bin_index = client->channel_hash % store->num_client_lookup_bins;
struct sim_client_lookup_bin *bin = &store->client_lookup_bins[bin_index];
struct sim_client *prev = sim_client_from_handle(store, client->prev_in_bin);
struct sim_client *next = sim_client_from_handle(store, client->next_in_bin);
if (prev->valid) {
prev->next_in_bucket = next->handle;
prev->next_in_bin = next->handle;
} else {
bucket->first = next->handle;
bin->first = next->handle;
}
if (next->valid) {
next->prev_in_bucket = prev->handle;
next->prev_in_bin = prev->handle;
} else {
bucket->last = prev->handle;
bin->last = prev->handle;
}
}
@ -219,17 +219,17 @@ void sim_client_set_channel_id(struct sim_client *client, struct host_channel_id
client->channel_id = channel_id;
client->channel_hash = channel_hash;
if (!host_channel_id_is_nil(channel_id)) {
u64 bucket_index = channel_hash % store->num_client_lookup_buckets;
struct sim_client_lookup_bucket *bucket = &store->client_lookup_buckets[bucket_index];
u64 bin_index = channel_hash % store->num_client_lookup_bins;
struct sim_client_lookup_bin *bin = &store->client_lookup_bins[bin_index];
{
struct sim_client *prev_in_bucket = sim_client_from_handle(store, bucket->last);
if (prev_in_bucket->valid) {
prev_in_bucket->next_in_bucket = client->handle;
client->prev_in_bucket = prev_in_bucket->handle;
struct sim_client *prev_in_bin = sim_client_from_handle(store, bin->last);
if (prev_in_bin->valid) {
prev_in_bin->next_in_bin = client->handle;
client->prev_in_bin = prev_in_bin->handle;
} else {
bucket->first = client->handle;
bin->first = client->handle;
}
bucket->last = client->handle;
bin->last = client->handle;
}
}
}
@ -238,9 +238,9 @@ struct sim_client *sim_client_from_channel_id(struct sim_client_store *store, st
{
struct sim_client *res = sim_client_nil();
u64 channel_hash = hash_from_channel_id(channel_id);
u64 bucket_index = channel_hash % store->num_client_lookup_buckets;
struct sim_client_lookup_bucket *bucket = &store->client_lookup_buckets[bucket_index];
for (struct sim_client *client = sim_client_from_handle(store, bucket->first); client->valid; client = sim_client_from_handle(store, client->next_in_bucket)) {
u64 bin_index = channel_hash % store->num_client_lookup_bins;
struct sim_client_lookup_bin *bin = &store->client_lookup_bins[bin_index];
for (struct sim_client *client = sim_client_from_handle(store, bin->first); client->valid; client = sim_client_from_handle(store, client->next_in_bin)) {
if (client->channel_hash == channel_hash) {
res = client;
break;
@ -308,15 +308,15 @@ struct sim_snapshot *sim_snapshot_alloc(struct sim_client *client, struct sim_sn
ss->local_client_ent = src->local_client_ent;
ss->phys_iteration = src->phys_iteration;
/* Copy id lookup buckets */
ss->num_id_buckets = src->num_id_buckets > 0 ? src->num_id_buckets : ID_LOOKUP_BUCKETS;
ss->id_buckets = arena_push_array(&ss->arena, struct sim_ent_bucket, ss->num_id_buckets);
if (src->num_id_buckets > 0) {
for (u64 i = 0; i < src->num_id_buckets; ++i) {
ss->id_buckets[i] = src->id_buckets[i];
/* Copy id lookup bins */
ss->num_id_bins = src->num_id_bins > 0 ? src->num_id_bins : ID_LOOKUP_BINS;
ss->id_bins = arena_push_array(&ss->arena, struct sim_ent_bin, ss->num_id_bins);
if (src->num_id_bins > 0) {
for (u64 i = 0; i < src->num_id_bins; ++i) {
ss->id_bins[i] = src->id_bins[i];
}
} else {
MEMZERO(ss->id_buckets, sizeof(*ss->id_buckets) * ss->num_id_buckets);
MEMZERO(ss->id_bins, sizeof(*ss->id_bins) * ss->num_id_bins);
}
/* Copy entities */
@ -398,15 +398,15 @@ struct sim_snapshot *sim_snapshot_alloc(struct sim_client *client, struct sim_sn
/* Insert into lookup */
{
u64 bucket_index = tick % client->num_snapshot_lookup_buckets;
struct sim_snapshot_lookup_bucket *bucket = &client->snapshot_lookup_buckets[bucket_index];
if (bucket->last) {
bucket->last->next_in_bucket = ss;
ss->prev_in_bucket = bucket->last;
u64 bin_index = tick % client->num_snapshot_lookup_bins;
struct sim_snapshot_lookup_bin *bin = &client->snapshot_lookup_bins[bin_index];
if (bin->last) {
bin->last->next_in_bin = ss;
ss->prev_in_bin = bin->last;
} else {
bucket->first = ss;
bin->first = ss;
}
bucket->last = ss;
bin->last = ss;
}
return ss;
@ -418,19 +418,19 @@ void sim_snapshot_release(struct sim_snapshot *ss)
/* Remove from lookup */
{
u64 bucket_index = ss->tick % client->num_snapshot_lookup_buckets;
struct sim_snapshot_lookup_bucket *bucket = &client->snapshot_lookup_buckets[bucket_index];
struct sim_snapshot *prev = ss->prev_in_bucket;
struct sim_snapshot *next = ss->next_in_bucket;
u64 bin_index = ss->tick % client->num_snapshot_lookup_bins;
struct sim_snapshot_lookup_bin *bin = &client->snapshot_lookup_bins[bin_index];
struct sim_snapshot *prev = ss->prev_in_bin;
struct sim_snapshot *next = ss->next_in_bin;
if (prev) {
prev->next_in_bucket = next;
prev->next_in_bin = next;
} else {
bucket->first = next;
bin->first = next;
}
if (next) {
next->prev_in_bucket = prev;
next->prev_in_bin = prev;
} else {
bucket->last = prev;
bin->last = prev;
}
}
@ -488,9 +488,9 @@ struct sim_snapshot *sim_snapshot_from_tick(struct sim_client *client, u64 tick)
{
struct sim_snapshot *ss = sim_snapshot_nil();
if (tick > 0) {
u64 bucket_index = tick % client->num_snapshot_lookup_buckets;
struct sim_snapshot_lookup_bucket *bucket = &client->snapshot_lookup_buckets[bucket_index];
for (struct sim_snapshot *search = bucket->first; search; search = search->next_in_bucket) {
u64 bin_index = tick % client->num_snapshot_lookup_bins;
struct sim_snapshot_lookup_bin *bin = &client->snapshot_lookup_bins[bin_index];
for (struct sim_snapshot *search = bin->first; search; search = search->next_in_bin) {
if (search->tick == tick) {
ss = search;
break;
@ -652,33 +652,33 @@ void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver,
bw_write_uid(bw, receiver->ent_id.uid);
/* Id buckets */
/* Id bins */
/* TODO: Don't encode these */
for (u64 i = 0; i < ss1->num_id_buckets; ++i) {
for (u64 i = 0; i < ss1->num_id_bins; ++i) {
u32 old_first = 0;
u32 old_last = 0;
if (i < ss0->num_id_buckets) {
struct sim_ent_bucket *old_bucket = &ss0->id_buckets[i];
old_first = old_bucket->first;
old_last = old_bucket->last;
if (i < ss0->num_id_bins) {
struct sim_ent_bin *old_bin = &ss0->id_bins[i];
old_first = old_bin->first;
old_last = old_bin->last;
}
struct sim_ent_bucket *bucket = &ss1->id_buckets[i];
u32 new_first = bucket->first;
u32 new_last = bucket->last;
struct sim_ent_bin *bin = &ss1->id_bins[i];
u32 new_first = bin->first;
u32 new_last = bin->last;
if (new_first != old_first || new_last != old_last) {
bw_write_bit(bw, 1);
bw_write_uv(bw, i);
if (old_first == bucket->first) {
if (old_first == bin->first) {
bw_write_bit(bw, 0);
} else {
bw_write_bit(bw, 1);
bw_write_uv(bw, bucket->first);
bw_write_uv(bw, bin->first);
}
if (old_last == bucket->last) {
if (old_last == bin->last) {
bw_write_bit(bw, 0);
} else {
bw_write_bit(bw, 1);
bw_write_uv(bw, bucket->last);
bw_write_uv(bw, bin->last);
}
}
}
@ -723,26 +723,26 @@ void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss)
ss->local_client_ent = (struct sim_ent_id) { .uid = br_read_uid(br) };
/* Id buckets */
/* Id bins */
/* TODO: Don't decode these, determine them implicitly from decoded ents */
{
b32 bucket_changed = br_read_bit(br);
while (bucket_changed) {
u32 bucket_index = br_read_uv(br);
if (bucket_index < ss->num_id_buckets) {
struct sim_ent_bucket *bucket = &ss->id_buckets[bucket_index];
b32 bin_changed = br_read_bit(br);
while (bin_changed) {
u32 bin_index = br_read_uv(br);
if (bin_index < ss->num_id_bins) {
struct sim_ent_bin *bin = &ss->id_bins[bin_index];
if (br_read_bit(br)) {
bucket->first = br_read_uv(br);
bin->first = br_read_uv(br);
}
if (br_read_bit(br)) {
bucket->last = br_read_uv(br);
bin->last = br_read_uv(br);
}
} else {
/* Invalid bucket index */
/* Invalid bin index */
ASSERT(false);
}
bucket_changed = br_read_bit(br);
bin_changed = br_read_bit(br);
}
}

View File

@ -24,7 +24,7 @@ struct sim_startup_receipt sim_startup(void);
* Client store
* ========================== */
struct sim_client_lookup_bucket {
struct sim_client_lookup_bin {
struct sim_client_handle first;
struct sim_client_handle last;
};
@ -34,8 +34,8 @@ struct sim_client_store {
struct arena arena;
/* Client lookup */
struct sim_client_lookup_bucket *client_lookup_buckets;
u64 num_client_lookup_buckets;
struct sim_client_lookup_bin *client_lookup_bins;
u64 num_client_lookup_bins;
/* Clients */
struct arena clients_arena;
@ -60,7 +60,7 @@ void sim_client_store_release(struct sim_client_store *store);
struct sim_snapshot;
struct sim_snapshot_lookup_bucket {
struct sim_snapshot_lookup_bin {
struct sim_snapshot *first;
struct sim_snapshot *last;
};
@ -76,8 +76,8 @@ struct sim_client {
u64 channel_hash;
struct sim_client_handle next_free;
struct sim_client_handle next_in_bucket;
struct sim_client_handle prev_in_bucket;
struct sim_client_handle next_in_bin;
struct sim_client_handle prev_in_bin;
/* The client entity's id in the master sim (if relevant) */
struct sim_ent_id ent_id;
@ -100,8 +100,8 @@ struct sim_client {
struct sim_snapshot *first_free_snapshot;
/* Tick -> snapshot lookup */
u64 num_snapshot_lookup_buckets;
struct sim_snapshot_lookup_bucket *snapshot_lookup_buckets;
u64 num_snapshot_lookup_bins;
struct sim_snapshot_lookup_bin *snapshot_lookup_bins;
};
INLINE struct sim_client *sim_client_nil(void)
@ -143,15 +143,15 @@ struct sim_control {
u32 flags;
};
struct sim_ent_bucket;
struct sim_ent_bin;
struct sim_snapshot {
b32 valid;
u64 tick;
struct sim_client *client;
struct sim_snapshot *next_free;
struct sim_snapshot *next_in_bucket;
struct sim_snapshot *prev_in_bucket;
struct sim_snapshot *next_in_bin;
struct sim_snapshot *prev_in_bin;
u64 prev_tick;
u64 next_tick;
@ -174,8 +174,8 @@ struct sim_snapshot {
struct sim_ent_id local_client_ent; /* The id of the receiver's client ent */
/* Id lookup */
struct sim_ent_bucket *id_buckets;
u64 num_id_buckets;
struct sim_ent_bin *id_bins;
u64 num_id_bins;
/* Entities */
struct arena ents_arena;

View File

@ -174,9 +174,9 @@ void sim_ent_activate(struct sim_ent *ent, u64 current_tick)
* Ent id
* ========================== */
INTERNAL struct sim_ent_bucket *bucket_from_id(struct sim_snapshot *ss, struct sim_ent_id id)
INTERNAL struct sim_ent_bin *bin_from_id(struct sim_snapshot *ss, struct sim_ent_id id)
{
return &ss->id_buckets[id.uid.lo % ss->num_id_buckets];
return &ss->id_bins[id.uid.lo % ss->num_id_bins];
}
/* NOTE: This should only really happen during ent allocation (it doesn't make sense for an allocated ent's id to change) */
@ -187,15 +187,15 @@ void sim_ent_set_id(struct sim_ent *ent, struct sim_ent_id id)
if (!sim_ent_id_eq(old_id, id)) {
/* Release old from lookup */
if (!sim_ent_id_eq(old_id, SIM_ENT_NIL_ID)) {
struct sim_ent_bucket *bucket = bucket_from_id(ss, old_id);
struct sim_ent_bin *bin = bin_from_id(ss, old_id);
u32 prev_index = 0;
u32 next_index = 0;
u32 search_index = bucket->first;
u32 search_index = bin->first;
struct sim_ent *prev = sim_ent_nil();
struct sim_ent *next = sim_ent_nil();
struct sim_ent *search = ent_from_index(ss, search_index);
while (search->valid) {
next_index = search->next_in_id_bucket;
next_index = search->next_in_id_bin;
next = ent_from_index(ss, next_index);
if (sim_ent_id_eq(search->id, old_id)) {
break;
@ -206,35 +206,35 @@ void sim_ent_set_id(struct sim_ent *ent, struct sim_ent_id id)
search = next;
}
/* Old id not in bucket, this should be impossible. */
/* Old id not in bin, this should be impossible. */
ASSERT(search->valid);
if (prev->valid) {
prev->next_in_id_bucket = next_index;
prev->next_in_id_bin = next_index;
} else {
bucket->first = next_index;
bin->first = next_index;
}
if (next->valid) {
next->prev_in_id_bucket = prev_index;
next->prev_in_id_bin = prev_index;
} else {
bucket->last = prev_index;
bin->last = prev_index;
}
}
/* Insert new id into lookup */
if (!sim_ent_id_eq(id, SIM_ENT_NIL_ID)) {
struct sim_ent_bucket *bucket = bucket_from_id(ss, id);
struct sim_ent_bin *bin = bin_from_id(ss, id);
u32 ent_index = index_from_ent(ss, ent);
struct sim_ent *last = ent_from_index(ss, bucket->last);
struct sim_ent *last = ent_from_index(ss, bin->last);
if (last->valid) {
last->next_in_id_bucket = ent_index;
ent->prev_in_id_bucket = bucket->last;
last->next_in_id_bin = ent_index;
ent->prev_in_id_bin = bin->last;
} else {
bucket->first = ent_index;
ent->prev_in_id_bucket = 0;
bin->first = ent_index;
ent->prev_in_id_bin = 0;
}
bucket->last = ent_index;
bin->last = ent_index;
}
ent->id = id;
@ -246,8 +246,8 @@ struct sim_ent *sim_ent_from_id(struct sim_snapshot *ss, struct sim_ent_id id)
{
struct sim_ent *res = sim_ent_nil();
if (!sim_ent_id_eq(id, SIM_ENT_NIL_ID) && ss->valid) {
struct sim_ent_bucket *bucket = bucket_from_id(ss, id);
for (struct sim_ent *e = ent_from_index(ss, bucket->first); e->valid; e = ent_from_index(ss, e->next_in_id_bucket)) {
struct sim_ent_bin *bin = bin_from_id(ss, id);
for (struct sim_ent *e = ent_from_index(ss, bin->first); e->valid; e = ent_from_index(ss, e->next_in_id_bin)) {
if (sim_ent_id_eq(e->id, id)) {
res = e;
break;
@ -591,8 +591,8 @@ void sim_ent_sync(struct sim_ent *local, struct sim_ent *remote)
local->top = old.top;
/* Keep indices */
local->next_in_id_bucket = old.next_in_id_bucket;
local->prev_in_id_bucket = old.prev_in_id_bucket;
local->next_in_id_bin = old.next_in_id_bin;
local->prev_in_id_bin = old.prev_in_id_bin;
local->next_free = old.next_free;
sim_ent_disable_prop(local, SIM_ENT_PROP_SYNC_SRC);

View File

@ -87,8 +87,8 @@ struct sim_ent {
struct sim_ent_id last;
/* Lists keyed by index in snapshot ent array */
u32 next_in_id_bucket;
u32 prev_in_id_bucket;
u32 next_in_id_bin;
u32 prev_in_id_bin;
u32 next_free;
/* ====================================================================== */
@ -331,7 +331,7 @@ struct sim_ent_prop_array {
u64 count;
};
struct sim_ent_bucket {
struct sim_ent_bin {
u32 first;
u32 last;
};

View File

@ -18,9 +18,9 @@ READONLY struct space _g_space_nil = { .valid = false };
* ========================== */
/* NOTE:
* The number of buckets determines how often tiles will collide in the spatial hash.
* For example, at `num_buckets_sqrt` = 256 (65536 buckets), tiles <1, 1>, <1, 257>, and <257, 257> will collide. */
struct space *space_alloc(f32 cell_size, u32 num_buckets_sqrt)
* The number of bins determines how often tiles will collide in the spatial hash.
* For example, at `num_bins_sqrt` = 256 (65536 bins), tiles <1, 1>, <1, 257>, and <257, 257> will collide. */
struct space *space_alloc(f32 cell_size, u32 num_bins_sqrt)
{
struct space *space;
{
@ -34,9 +34,9 @@ struct space *space_alloc(f32 cell_size, u32 num_buckets_sqrt)
space->cell_arena = arena_alloc(GIGABYTE(64));
space->cell_size = cell_size;
space->num_buckets = num_buckets_sqrt * num_buckets_sqrt;
space->num_buckets_sqrt = num_buckets_sqrt;
space->buckets = arena_push_array_zero(&space->cell_arena, struct space_cell_bucket, space->num_buckets);
space->num_bins = num_bins_sqrt * num_bins_sqrt;
space->num_bins_sqrt = num_bins_sqrt;
space->bins = arena_push_array_zero(&space->cell_arena, struct space_cell_bin, space->num_bins);
return space;
}
@ -51,7 +51,7 @@ void space_reset(struct space *space)
{
arena_pop_to(&space->entry_arena, (u64)space->entries - (u64)space->entry_arena.base);
arena_reset(&space->cell_arena);
space->buckets = arena_push_array_zero(&space->cell_arena, struct space_cell_bucket, space->num_buckets);;
space->bins = arena_push_array_zero(&space->cell_arena, struct space_cell_bin, space->num_bins);;
space->num_entries_reserved = 0;
space->first_free_cell = NULL;
space->first_free_cell_node = NULL;
@ -83,9 +83,9 @@ INTERNAL struct v2i32 world_to_cell_coords(f32 cell_size, struct v2 world_pos)
return V2I32((i32)x, (i32)y);
}
INTERNAL i32 cell_coords_to_bucket_index(struct space *space, struct v2i32 cell_pos)
INTERNAL i32 cell_coords_to_bin_index(struct space *space, struct v2i32 cell_pos)
{
i32 num_buckets_sqrt = space->num_buckets_sqrt;
i32 num_bins_sqrt = space->num_bins_sqrt;
/* Cell pos of 0 is not valid and will be converted to -1 */
ASSERT(cell_pos.x != 0 && cell_pos.y != 0);
@ -96,21 +96,21 @@ INTERNAL i32 cell_coords_to_bucket_index(struct space *space, struct v2i32 cell_
index_x -= (index_x >= 0);
index_y -= (index_y >= 0);
/* Un-mirror coords to prevent collisions between cells near the axes. (e.g. <3, 1> & <3, -1> should not collide) */
index_x += (index_x < 0) * (num_buckets_sqrt * ((index_x / -num_buckets_sqrt) + 1));
index_y += (index_y < 0) * (num_buckets_sqrt * ((index_y / -num_buckets_sqrt) + 1));
index_x += (index_x < 0) * (num_bins_sqrt * ((index_x / -num_bins_sqrt) + 1));
index_y += (index_y < 0) * (num_bins_sqrt * ((index_y / -num_bins_sqrt) + 1));
i32 bucket_index = (index_x % num_buckets_sqrt) + (index_y % num_buckets_sqrt) * num_buckets_sqrt;
ASSERT(bucket_index >= 0 && bucket_index < (i32)space->num_buckets);
i32 bin_index = (index_x % num_bins_sqrt) + (index_y % num_bins_sqrt) * num_bins_sqrt;
ASSERT(bin_index >= 0 && bin_index < (i32)space->num_bins);
return bucket_index;
return bin_index;
}
struct space_cell *space_get_cell(struct space *space, struct v2i32 cell_pos)
{
i32 bucket_index = cell_coords_to_bucket_index(space, cell_pos);
struct space_cell_bucket *bucket = &space->buckets[bucket_index];
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
struct space_cell_bin *bin = &space->bins[bin_index];
struct space_cell *res = space_cell_nil();
for (struct space_cell *n = bucket->first_cell; n; n = n->next_in_bucket) {
for (struct space_cell *n = bin->first_cell; n; n = n->next_in_bin) {
if (v2i32_eq(n->pos, cell_pos)) {
res = n;
break;
@ -122,12 +122,12 @@ struct space_cell *space_get_cell(struct space *space, struct v2i32 cell_pos)
INTERNAL void space_cell_node_alloc(struct v2i32 cell_pos, struct space_entry *entry)
{
struct space *space = space_from_entry(entry);
i32 bucket_index = cell_coords_to_bucket_index(space, cell_pos);
struct space_cell_bucket *bucket = &space->buckets[bucket_index];
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
struct space_cell_bin *bin = &space->bins[bin_index];
/* Find existing cell */
struct space_cell *cell = NULL;
for (struct space_cell *n = bucket->first_cell; n; n = n->next_in_bucket) {
for (struct space_cell *n = bin->first_cell; n; n = n->next_in_bin) {
if (v2i32_eq(n->pos, cell_pos)) {
cell = n;
break;
@ -143,15 +143,15 @@ INTERNAL void space_cell_node_alloc(struct v2i32 cell_pos, struct space_entry *e
cell = arena_push(&space->cell_arena, struct space_cell);
}
MEMZERO_STRUCT(cell);
if (bucket->last_cell) {
bucket->last_cell->next_in_bucket = cell;
cell->prev_in_bucket = bucket->last_cell;
if (bin->last_cell) {
bin->last_cell->next_in_bin = cell;
cell->prev_in_bin = bin->last_cell;
} else {
bucket->first_cell = cell;
bin->first_cell = cell;
}
bucket->last_cell = cell;
bin->last_cell = cell;
cell->pos = cell_pos;
cell->bucket = bucket;
cell->bin = bin;
cell->valid = true;
}
@ -193,7 +193,7 @@ INTERNAL void space_cell_node_release(struct space_cell_node *n)
struct space_cell *cell = n->cell;
struct space_entry *entry = n->entry;
struct space *space = space_from_entry(entry);
struct space_cell_bucket *bucket = cell->bucket;
struct space_cell_bin *bin = cell->bin;
/* Remove from entry list */
{
@ -229,18 +229,18 @@ INTERNAL void space_cell_node_release(struct space_cell_node *n)
/* If cell is now empty, release it */
if (!cell->first_node && !cell->last_node) {
/* Remove from bucket */
struct space_cell *prev = cell->prev_in_bucket;
struct space_cell *next = cell->next_in_bucket;
/* Remove from bin */
struct space_cell *prev = cell->prev_in_bin;
struct space_cell *next = cell->next_in_bin;
if (prev) {
prev->next_in_bucket = next;
prev->next_in_bin = next;
} else {
bucket->first_cell = next;
bin->first_cell = next;
}
if (next) {
next->prev_in_bucket = prev;
next->prev_in_bin = prev;
} else {
bucket->last_cell = prev;
bin->last_cell = prev;
}
cell->valid = false;

View File

@ -1,7 +1,7 @@
#ifndef SPACE_H
#define SPACE_H
struct space_cell_bucket;
struct space_cell_bin;
struct space_entry {
b32 valid;
@ -40,14 +40,14 @@ struct space_cell {
struct space_cell_node *first_node;
struct space_cell_node *last_node;
struct space_cell_bucket *bucket;
struct space_cell *prev_in_bucket;
struct space_cell *next_in_bucket;
struct space_cell_bin *bin;
struct space_cell *prev_in_bin;
struct space_cell *next_in_bin;
struct space_cell *next_free;
};
struct space_cell_bucket {
struct space_cell_bin {
struct space_cell *first_cell;
struct space_cell *last_cell;
};
@ -57,9 +57,9 @@ struct space {
f32 cell_size;
struct arena cell_arena;
struct space_cell_bucket *buckets;
i32 num_buckets;
i32 num_buckets_sqrt;
struct space_cell_bin *bins;
i32 num_bins;
i32 num_bins_sqrt;
struct space_cell *first_free_cell;
struct space_cell_node *first_free_cell_node;
@ -104,7 +104,7 @@ INLINE struct space *space_nil(void)
* Space
* ========================== */
struct space *space_alloc(f32 cell_size, u32 num_buckets_sqrt);
struct space *space_alloc(f32 cell_size, u32 num_bins_sqrt);
void space_release(struct space *space);
void space_reset(struct space *space);

View File

@ -14,7 +14,7 @@
#include "math.h"
#define CACHE_MEMORY_BUDGET (MEGABYTE(256))
#define CACHE_BUCKETS_COUNT 1024
#define CACHE_BINS_COUNT 1024
#define MAX_LOADER_THREADS 4
@ -30,8 +30,8 @@
#define TEXTURE_ARENA_RESERVE MEGABYTE(1)
#define SHEET_ARENA_RESERVE MEGABYTE(64)
#define SHEET_SPAN_LOOKUP_TABLE_BUCKET_RATIO 2.0
#define SHEET_SLICE_LOOKUP_TABLE_BUCKET_RATIO 2.0
#define SHEET_SPAN_LOOKUP_TABLE_BIN_RATIO 2.0
#define SHEET_SLICE_LOOKUP_TABLE_BIN_RATIO 2.0
/* ========================== *
* Loader cmd structs
@ -96,7 +96,7 @@ struct cache_node {
#endif
};
struct cache_bucket {
struct cache_bin {
struct sys_mutex mutex;
struct cache_node *first;
};
@ -104,7 +104,7 @@ struct cache_bucket {
struct cache {
struct atomic_u64 memory_usage;
struct arena arena;
struct cache_bucket *buckets;
struct cache_bin *bins;
struct sys_mutex node_pool_mutex;
struct cache_node *node_pool_first_free;
};
@ -248,9 +248,9 @@ struct sprite_startup_receipt sprite_startup(struct renderer_startup_receipt *re
G.cache.node_pool_mutex = sys_mutex_alloc();
G.cache.arena = arena_alloc(GIGABYTE(64));
G.cache.buckets = arena_push_array_zero(&G.cache.arena, struct cache_bucket, CACHE_BUCKETS_COUNT);
for (u64 i = 0; i < CACHE_BUCKETS_COUNT; ++i) {
G.cache.buckets[i].mutex = sys_mutex_alloc();
G.cache.bins = arena_push_array_zero(&G.cache.arena, struct cache_bin, CACHE_BINS_COUNT);
for (u64 i = 0; i < CACHE_BINS_COUNT; ++i) {
G.cache.bins[i].mutex = sys_mutex_alloc();
}
G.load_cmds_arena = arena_alloc(GIGABYTE(64));
@ -430,7 +430,7 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
if (ase.num_spans > 0) {
__profscope(init_spans);
sheet.spans = arena_push_array_zero(arena, struct sprite_sheet_span, sheet.spans_count);
sheet.spans_dict = fixed_dict_init(arena, (u64)(ase.num_spans * SHEET_SPAN_LOOKUP_TABLE_BUCKET_RATIO));
sheet.spans_dict = fixed_dict_init(arena, (u64)(ase.num_spans * SHEET_SPAN_LOOKUP_TABLE_BIN_RATIO));
u64 index = 0;
for (struct ase_span *ase_span = ase.span_head; ase_span; ase_span = ase_span->next) {
struct string name = string_copy(arena, ase_span->name);
@ -498,7 +498,7 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
/* Allocate slice groups & fill originals in 2d array */
sheet.slice_groups_count = num_temp_slice_group_nodes;
sheet.slice_groups = arena_push_array_zero(arena, struct sprite_sheet_slice_group, sheet.slice_groups_count);
sheet.slice_groups_dict = fixed_dict_init(arena, (u64)(num_temp_slice_group_nodes * SHEET_SLICE_LOOKUP_TABLE_BUCKET_RATIO));
sheet.slice_groups_dict = fixed_dict_init(arena, (u64)(num_temp_slice_group_nodes * SHEET_SLICE_LOOKUP_TABLE_BIN_RATIO));
u64 index = 0;
for (struct temp_slice_group_node *temp_slice_group_node = temp_slice_group_head; temp_slice_group_node; temp_slice_group_node = temp_slice_group_node->next) {
@ -700,10 +700,10 @@ INTERNAL void cache_node_load_sheet(struct cache_node *n, struct sprite_tag tag)
* Scope
* ========================== */
INTERNAL void scope_ensure_reference(struct sprite_scope *scope, struct cache_node *cache_node, u64 cache_bucket_index)
INTERNAL void scope_ensure_reference(struct sprite_scope *scope, struct cache_node *cache_node, u64 cache_bin_index)
{
__prof;
struct sprite_scope_reference **ref_next = &scope->reference_buckets[cache_bucket_index];
struct sprite_scope_reference **ref_next = &scope->reference_bins[cache_bin_index];
struct sprite_scope_reference *ref = *ref_next;
while (ref) {
if (ref->cache_node == cache_node) {
@ -740,13 +740,13 @@ struct sprite_scope *sprite_scope_begin(void)
if (tctx->first_free_scope) {
res = tctx->first_free_scope;
tctx->first_free_scope = res->next_free;
MEMZERO(res->reference_buckets, sizeof(*res->reference_buckets) * CACHE_BUCKETS_COUNT);
MEMZERO(res->reference_bins, sizeof(*res->reference_bins) * CACHE_BINS_COUNT);
*res = (struct sprite_scope) {
.reference_buckets = res->reference_buckets
.reference_bins = res->reference_bins
};
} else {
res = arena_push_zero(&tctx->arena, struct sprite_scope);
res->reference_buckets = arena_push_array_zero(&tctx->arena, struct sprite_scope_reference *, CACHE_BUCKETS_COUNT);
res->reference_bins = arena_push_array_zero(&tctx->arena, struct sprite_scope_reference *, CACHE_BINS_COUNT);
}
return res;
@ -755,8 +755,8 @@ struct sprite_scope *sprite_scope_begin(void)
void sprite_scope_end(struct sprite_scope *scope)
{
struct sprite_tctx *tctx = thread_local_var_eval(&tl_sprite_tctx);
for (u64 i = 0; i < CACHE_BUCKETS_COUNT; ++i) {
struct sprite_scope_reference *ref = scope->reference_buckets[i];
for (u64 i = 0; i < CACHE_BINS_COUNT; ++i) {
struct sprite_scope_reference *ref = scope->reference_bins[i];
while (ref) {
/* Decrement refcount */
node_refcount_add(ref->cache_node, -1);
@ -783,18 +783,18 @@ INTERNAL struct cache_node *node_lookup_touch(struct sprite_scope *scope, struct
struct cache_node **nonmatching_next = NULL;
struct cache_node_hash hash = cache_node_hash_from_tag_hash(tag.hash, kind);
u64 cache_bucket_index = hash.v % CACHE_BUCKETS_COUNT;
struct cache_bucket *bucket = &G.cache.buckets[cache_bucket_index];
u64 cache_bin_index = hash.v % CACHE_BINS_COUNT;
struct cache_bin *bin = &G.cache.bins[cache_bin_index];
/* Lookup */
/* TODO: Spinlock */
{
struct sys_lock lock = sys_mutex_lock_s(&bucket->mutex);
nonmatching_next = &bucket->first;
struct sys_lock lock = sys_mutex_lock_s(&bin->mutex);
nonmatching_next = &bin->first;
n = *nonmatching_next;
while (n) {
if (n->hash.v == hash.v) {
scope_ensure_reference(scope, n, cache_bucket_index);
scope_ensure_reference(scope, n, cache_bin_index);
break;
} else {
nonmatching = n;
@ -808,7 +808,7 @@ INTERNAL struct cache_node *node_lookup_touch(struct sprite_scope *scope, struct
/* Allocate new node if necessary */
if (!n) {
__profscope(node_lookup_allocate);
struct sys_lock bucket_lock = sys_mutex_lock_e(&bucket->mutex);
struct sys_lock bin_lock = sys_mutex_lock_e(&bin->mutex);
{
/* Alloc node */
{
@ -822,8 +822,8 @@ INTERNAL struct cache_node *node_lookup_touch(struct sprite_scope *scope, struct
}
sys_mutex_unlock(&pool_lock);
}
/* Init node and add to bucket */
scope_ensure_reference(scope, n, cache_bucket_index);
/* Init node and add to bin */
scope_ensure_reference(scope, n, cache_bin_index);
*nonmatching_next = n;
if (nonmatching) {
nonmatching->next_hash = n;
@ -834,7 +834,7 @@ INTERNAL struct cache_node *node_lookup_touch(struct sprite_scope *scope, struct
n->texture = G.nil_texture;
n->sheet = G.nil_sheet;
}
sys_mutex_unlock(&bucket_lock);
sys_mutex_unlock(&bin_lock);
}
return n;
@ -1039,7 +1039,7 @@ struct evict_node {
b32 force_evict;
struct cache_node_refcount refcount;
struct cache_node *cache_node;
struct cache_bucket *cache_bucket;
struct cache_bin *cache_bin;
struct evict_node *next_consider;
struct evict_node *next_consider_lru;
struct evict_node *next_evicted;
@ -1063,11 +1063,11 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg)
b32 cache_over_budget = atomic_u64_eval(&G.cache.memory_usage) > CACHE_MEMORY_BUDGET;
if (cache_over_budget || RESOURCE_RELOADING) {
__profscope(eviction_scan);
for (u64 i = 0; i < CACHE_BUCKETS_COUNT; ++i) {
struct cache_bucket *bucket = &G.cache.buckets[i];
struct sys_lock bucket_lock = sys_mutex_lock_s(&bucket->mutex);
for (u64 i = 0; i < CACHE_BINS_COUNT; ++i) {
struct cache_bin *bin = &G.cache.bins[i];
struct sys_lock bin_lock = sys_mutex_lock_s(&bin->mutex);
{
struct cache_node *n = bucket->first;
struct cache_node *n = bin->first;
while (n) {
b32 consider_for_eviction = false;
b32 force_evict = false;
@ -1122,7 +1122,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg)
if (consider_for_eviction) {
struct evict_node *evict_node = arena_push_zero(scratch.arena, struct evict_node);
evict_node->cache_node = n;
evict_node->cache_bucket = bucket;
evict_node->cache_bin = bin;
evict_node->refcount = refcount;
evict_node->force_evict = force_evict;
evict_node->next_consider = head_consider;
@ -1132,7 +1132,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg)
n = n->next_hash;
}
}
sys_mutex_unlock(&bucket_lock);
sys_mutex_unlock(&bin_lock);
}
}
@ -1162,19 +1162,19 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg)
__profscope(eviction_cache_removal);
b32 stop_evicting = false;
for (struct evict_node *en = head_consider_lru; en && !stop_evicting; en = en->next_consider_lru) {
struct cache_bucket *bucket = en->cache_bucket;
struct cache_bin *bin = en->cache_bin;
struct cache_node *n = en->cache_node;
struct sys_lock bucket_lock = sys_mutex_lock_e(&bucket->mutex);
struct sys_lock bin_lock = sys_mutex_lock_e(&bin->mutex);
{
struct cache_node_refcount refcount = *(struct cache_node_refcount *)atomic_u64_raw(&n->refcount_struct);
if (refcount.count > 0 || ((refcount.last_modified_cycle != en->refcount.last_modified_cycle) && !en->force_evict)) {
/* Cache node has been referenced since scan, skip eviction. */
} else if (en->force_evict || atomic_u64_eval(&G.cache.memory_usage) > CACHE_MEMORY_BUDGET) {
/* Remove from cache bucket */
/* Remove from cache bin */
if (n->prev_hash) {
n->prev_hash->next_hash = n->next_hash;
} else {
bucket->first = n->next_hash;
bin->first = n->next_hash;
}
if (n->next_hash) {
n->next_hash->prev_hash = n->prev_hash;
@ -1188,7 +1188,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg)
stop_evicting = true;
}
}
sys_mutex_unlock(&bucket_lock);
sys_mutex_unlock(&bin_lock);
}
}

View File

@ -32,7 +32,7 @@ b32 sprite_tag_eq(struct sprite_tag t1, struct sprite_tag t2);
* ========================== */
struct sprite_scope {
struct sprite_scope_reference **reference_buckets;
struct sprite_scope_reference **reference_bins;
struct sprite_scope *next_free;
};

View File

@ -119,7 +119,7 @@ INLINE void merge_sort(void *items, u64 item_count, u64 item_size, sort_compare_
/* ========================== *
* Fixed Dict
*
* Simple fixed bucket-count string->value chaining dict for generic use
* Simple fixed bin-count string->value chaining dict for generic use
* ========================== */
struct fixed_dict_entry {
@ -129,22 +129,22 @@ struct fixed_dict_entry {
struct fixed_dict_entry *next;
};
struct fixed_dict_bucket {
struct fixed_dict_bin {
struct fixed_dict_entry *entry_head;
};
struct fixed_dict {
u64 buckets_count;
struct fixed_dict_bucket *buckets;
u64 bins_count;
struct fixed_dict_bin *bins;
};
INLINE struct fixed_dict fixed_dict_init(struct arena *arena, u64 buckets_count)
INLINE struct fixed_dict fixed_dict_init(struct arena *arena, u64 bins_count)
{
__prof;
struct fixed_dict dict = ZI;
buckets_count = max_u64(buckets_count, 1); /* Ensure at least 1 bucket */
dict.buckets_count = buckets_count;
dict.buckets = arena_push_array_zero(arena, struct fixed_dict_bucket, buckets_count);
bins_count = max_u64(bins_count, 1); /* Ensure at least 1 bin */
dict.bins_count = bins_count;
dict.bins = arena_push_array_zero(arena, struct fixed_dict_bin, bins_count);
return dict;
}
@ -154,10 +154,10 @@ INLINE void fixed_dict_set(struct arena *arena, struct fixed_dict *dict, struct
__prof;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, key);
u64 index = hash % dict->buckets_count;
struct fixed_dict_bucket *bucket = &dict->buckets[index];
u64 index = hash % dict->bins_count;
struct fixed_dict_bin *bin = &dict->bins[index];
struct fixed_dict_entry *entry = bucket->entry_head;
struct fixed_dict_entry *entry = bin->entry_head;
while (entry) {
if (hash == entry->hash) {
/* Existing match found, replace its contents */
@ -173,9 +173,9 @@ INLINE void fixed_dict_set(struct arena *arena, struct fixed_dict *dict, struct
entry->key = key;
entry->value = value;
entry->hash = hash;
entry->next = bucket->entry_head;
entry->next = bin->entry_head;
bucket->entry_head = entry;
bin->entry_head = entry;
}
INLINE void *fixed_dict_get(const struct fixed_dict *dict, struct string key)
@ -183,10 +183,10 @@ INLINE void *fixed_dict_get(const struct fixed_dict *dict, struct string key)
__prof;
u64 hash = hash_fnv64(HASH_FNV64_BASIS, key);
u64 index = hash % dict->buckets_count;
struct fixed_dict_bucket *bucket = &dict->buckets[index];
u64 index = hash % dict->bins_count;
struct fixed_dict_bin *bin = &dict->bins[index];
for (struct fixed_dict_entry *entry = bucket->entry_head; entry; entry = entry->next) {
for (struct fixed_dict_entry *entry = bin->entry_head; entry; entry = entry->next) {
if (hash == entry->hash) {
/* Match found */
return entry->value;