Skip to content

Instantly share code, notes, and snippets.

@worldOneo
Created May 11, 2022 16:12
Show Gist options
  • Save worldOneo/69f6b2c8330b1b9838750bd92c2f1bb7 to your computer and use it in GitHub Desktop.
Save worldOneo/69f6b2c8330b1b9838750bd92c2f1bb7 to your computer and use it in GitHub Desktop.
Simple (hash) table written in C ~10ns lookups
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
typedef uint64_t u64;
typedef struct Table
{
u64 nullValue;
bool hasNull;
u64 buckets;
u64 *map;
} Table;
static const u64 bucketSize = 8;
Table *alloc_table()
{
Table *table = calloc(1, sizeof(Table));
table->buckets = 8;
table->map = calloc(8, sizeof(u64) * bucketSize);
return table;
}
static inline u64 table_index(u64 bucket, u64 bucketIndex) {
return bucket * bucketSize + bucketIndex;
}
u64 table_get(Table *table, u64 key)
{
if (key == 0)
{
if (table->hasNull)
return table->nullValue;
return 0;
}
u64 bucket = key % table->buckets;
for (u64 i = 0; i < 8; i += 2)
{
u64 idx = table_index(bucket, i);
if (table->map[idx] == key)
{
return table->map[idx + 1];
}
}
return 0;
}
void table_set(Table *table, u64 key, u64 value)
{
if (key == 0)
{
table->hasNull = true;
table->nullValue = value;
return;
}
u64 bucket = key % table->buckets;
for (u64 bucketIndex = 0; bucketIndex < 8; bucketIndex += 2)
{
u64 idx = table_index(bucket, bucketIndex);
u64 mapKey = table->map[idx];
if (mapKey == 0 || mapKey == key)
{
table->map[idx] = key;
table->map[idx + 1] = value;
return;
}
}
// Resize map
u64 newBuckets = table->buckets * 2;
u64 *newMap = calloc(newBuckets, sizeof(u64) * bucketSize);
Table newTable;
newTable.buckets = newBuckets;
newTable.map = newMap;
for (u64 bucket = 0; bucket < table->buckets; bucket++)
{
for (u64 bucketIndex = 0; bucketIndex < bucketSize; bucketIndex += 2)
{
u64 idx = table_index(bucket, bucketIndex);
u64 mapKey = table->map[idx];
if (mapKey != 0)
{
table_set(&newTable, mapKey, table->map[idx + 1]);
}
}
}
free(table->map);
table->map = newMap;
table->buckets = newBuckets;
table_set(table, key, value);
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment