|
|
#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;
|