You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
6.3 KiB
135 lines
6.3 KiB
|
|
#define TABLE_KEY_SIZE 64
|
|
#define TABLE_NUM_LANES 32
|
|
static inline unsigned int APHash(const char* str, unsigned int length) {
|
|
unsigned int hash = 0xAAAAAAAA;
|
|
unsigned int i = 0;
|
|
|
|
for (i = 0; i < length; ++str, ++i)
|
|
{
|
|
hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ (*str) * (hash >> 3)) :
|
|
(~((hash << 11) + ((*str) ^ (hash >> 5))));
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
static inline uint32_t fastModuloReductionDanielLemire(uint32_t v, uint32_t c) {
|
|
return (((uint64_t)v) * ((uint64_t)c)) >> 32;
|
|
}
|
|
|
|
static inline uint32_t hash(const char* key, uint32_t keyLength, uint32_t capacity) {
|
|
uint32_t value = APHash(key, keyLength);
|
|
|
|
return fastModuloReductionDanielLemire(value, capacity);
|
|
}
|
|
|
|
typedef struct TableEntry {
|
|
struct TableEntry* next;
|
|
|
|
const char key[TABLE_KEY_SIZE];
|
|
ssize_t size;
|
|
ssize_t align;
|
|
} TableEntry;
|
|
|
|
typedef struct Table {
|
|
TableEntry **entries;
|
|
} Table;
|
|
|
|
static inline TableEntry* lookup(Table *table, const char key[TABLE_KEY_SIZE]) {
|
|
TableEntry *entry = table->entries[hash(key, TABLE_KEY_SIZE, TABLE_NUM_LANES)];
|
|
|
|
for (; entry != NULL; entry = entry->next) {
|
|
if (memcmp(entry->key, key, TABLE_KEY_SIZE) == 0) {
|
|
return entry;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static inline void insert(Table *table, const char key[TABLE_KEY_SIZE], ssize_t size, ssize_t align) {
|
|
TableEntry *entry = lookup(table, key);
|
|
|
|
if (!entry) { // no entry with that key exists
|
|
entry = (TableEntry*) calloc(sizeof(TableEntry), 1);
|
|
strWrite((char*)entry->key, key, TABLE_KEY_SIZE);
|
|
entry->size = size;
|
|
entry->align = align;
|
|
|
|
unsigned int hashValue = hash(key, TABLE_KEY_SIZE, TABLE_NUM_LANES);
|
|
entry->next = table->entries[hashValue];
|
|
table->entries[hashValue] = entry;
|
|
|
|
} else { // entry already exists, replace its value
|
|
entry->size = size;
|
|
entry->align = align;
|
|
}
|
|
}
|
|
|
|
static inline void insertPadZeroes(Table* table, const char* keyToPad, ssize_t size, ssize_t align) {
|
|
char scratch[64] = { 0 };
|
|
for (int i = 0; i < TABLE_KEY_SIZE; i++) {
|
|
if (keyToPad[i] == '\0') break;
|
|
scratch[i] = keyToPad[i];
|
|
}
|
|
|
|
insert(table, scratch, size, align);
|
|
}
|
|
|
|
static inline void traversePrint(Table *table) {
|
|
for (unsigned int i = 0; i < TABLE_NUM_LANES; i++) {
|
|
TableEntry *entry = table->entries[i];
|
|
|
|
while (entry != NULL) {
|
|
printf("entry key: %-64s, size: %lu, align: %lu\n", entry->key, entry->size, entry->align);
|
|
entry = entry->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline Table* initTable() {
|
|
Table *table = malloc(sizeof(Table));
|
|
table->entries = (TableEntry**) calloc(sizeof(TableEntry*), TABLE_NUM_LANES);
|
|
|
|
// alignof === sizeof for primitive data types, C99 doesn't have 'alignof'
|
|
insertPadZeroes(table, "char", sizeof(char), sizeof(char));
|
|
insertPadZeroes(table, "signed char", sizeof(signed char), sizeof(signed char));
|
|
insertPadZeroes(table, "unsigned char", sizeof(unsigned char), sizeof(unsigned char));
|
|
insertPadZeroes(table, "short", sizeof(short), sizeof(short));
|
|
insertPadZeroes(table, "short int", sizeof(short int), sizeof(short int));
|
|
insertPadZeroes(table, "signed short", sizeof(signed short), sizeof(signed short));
|
|
insertPadZeroes(table, "signed short int", sizeof(signed short int), sizeof(signed short int));
|
|
insertPadZeroes(table, "unsigned short", sizeof(unsigned short), sizeof(unsigned short));
|
|
insertPadZeroes(table, "unsigned short int", sizeof(unsigned short int), sizeof(unsigned short int));
|
|
insertPadZeroes(table, "int", sizeof(int), sizeof(int));
|
|
insertPadZeroes(table, "signed", sizeof(signed), sizeof(signed));
|
|
insertPadZeroes(table, "signed int", sizeof(signed int), sizeof(signed int));
|
|
insertPadZeroes(table, "unsigned", sizeof(unsigned), sizeof(unsigned));
|
|
insertPadZeroes(table, "unsigned int", sizeof(unsigned int), sizeof(unsigned int));
|
|
insertPadZeroes(table, "long", sizeof(long), sizeof(long));
|
|
insertPadZeroes(table, "long int", sizeof(long int), sizeof(long int));
|
|
insertPadZeroes(table, "signed long", sizeof(signed long), sizeof(signed long));
|
|
insertPadZeroes(table, "signed long int", sizeof(signed long int), sizeof(signed long int));
|
|
insertPadZeroes(table, "unsigned long", sizeof(unsigned long), sizeof(unsigned long));
|
|
insertPadZeroes(table, "unsigned long int", sizeof(unsigned long int), sizeof(unsigned long int));
|
|
insertPadZeroes(table, "long long", sizeof(long long), sizeof(long long));
|
|
insertPadZeroes(table, "long long int", sizeof(long long int), sizeof(long long int));
|
|
insertPadZeroes(table, "signed long long", sizeof(signed long long), sizeof(signed long long));
|
|
insertPadZeroes(table, "signed long long int", sizeof(signed long long int), sizeof(signed long long int));
|
|
insertPadZeroes(table, "unsigned long long", sizeof(unsigned long long), sizeof(unsigned long long));
|
|
insertPadZeroes(table, "unsigned long long int", sizeof(unsigned long long int), sizeof(unsigned long long int));
|
|
insertPadZeroes(table, "float", sizeof(float), sizeof(float));
|
|
insertPadZeroes(table, "double", sizeof(double), sizeof(double));
|
|
insertPadZeroes(table, "long double", sizeof(long double), sizeof(long double));
|
|
|
|
insertPadZeroes(table, "size_t", sizeof(size_t), sizeof(size_t));
|
|
insertPadZeroes(table, "ssize_t", sizeof(ssize_t), sizeof(ssize_t));
|
|
insertPadZeroes(table, "bool", sizeof(bool), sizeof(bool));
|
|
insertPadZeroes(table, "_Bool", sizeof(_Bool), sizeof(_Bool));
|
|
|
|
return table;
|
|
}
|
|
|
|
static Table *typeTable;
|
|
|