visualize the data structures in a C program
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

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