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

2 years ago
2 years ago
2 years ago
  1. #define TABLE_KEY_SIZE 64
  2. #define TABLE_NUM_LANES 32
  3. static inline unsigned int APHash(const char* str, unsigned int length) {
  4. unsigned int hash = 0xAAAAAAAA;
  5. unsigned int i = 0;
  6. for (i = 0; i < length; ++str, ++i)
  7. {
  8. hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ (*str) * (hash >> 3)) :
  9. (~((hash << 11) + ((*str) ^ (hash >> 5))));
  10. }
  11. return hash;
  12. }
  13. static inline uint32_t fastModuloReductionDanielLemire(uint32_t v, uint32_t c) {
  14. return (((uint64_t)v) * ((uint64_t)c)) >> 32;
  15. }
  16. static inline uint32_t hash(const char* key, uint32_t keyLength, uint32_t capacity) {
  17. uint32_t value = APHash(key, keyLength);
  18. return fastModuloReductionDanielLemire(value, capacity);
  19. }
  20. typedef struct TableEntry {
  21. struct TableEntry* next;
  22. const char key[TABLE_KEY_SIZE];
  23. ssize_t size;
  24. ssize_t align;
  25. } TableEntry;
  26. typedef struct Table {
  27. TableEntry **entries;
  28. } Table;
  29. static inline TableEntry* lookup(Table *table, const char key[TABLE_KEY_SIZE]) {
  30. TableEntry *entry = table->entries[hash(key, TABLE_KEY_SIZE, TABLE_NUM_LANES)];
  31. for (; entry != NULL; entry = entry->next) {
  32. if (memcmp(entry->key, key, TABLE_KEY_SIZE) == 0) {
  33. return entry;
  34. }
  35. }
  36. return NULL;
  37. }
  38. static inline void insert(Table *table, const char key[TABLE_KEY_SIZE], ssize_t size, ssize_t align) {
  39. TableEntry *entry = lookup(table, key);
  40. if (!entry) { // no entry with that key exists
  41. entry = (TableEntry*) calloc(sizeof(TableEntry), 1);
  42. strWrite((char*)entry->key, key, TABLE_KEY_SIZE);
  43. entry->size = size;
  44. entry->align = align;
  45. unsigned int hashValue = hash(key, TABLE_KEY_SIZE, TABLE_NUM_LANES);
  46. entry->next = table->entries[hashValue];
  47. table->entries[hashValue] = entry;
  48. } else { // entry already exists, replace its value
  49. entry->size = size;
  50. entry->align = align;
  51. }
  52. }
  53. static inline void insertPadZeroes(Table* table, const char* keyToPad, ssize_t size, ssize_t align) {
  54. char scratch[64] = { 0 };
  55. for (int i = 0; i < TABLE_KEY_SIZE; i++) {
  56. if (keyToPad[i] == '\0') break;
  57. scratch[i] = keyToPad[i];
  58. }
  59. insert(table, scratch, size, align);
  60. }
  61. static inline void traversePrint(Table *table) {
  62. for (unsigned int i = 0; i < TABLE_NUM_LANES; i++) {
  63. TableEntry *entry = table->entries[i];
  64. while (entry != NULL) {
  65. printf("entry key: %-64s, size: %lu, align: %lu\n", entry->key, entry->size, entry->align);
  66. entry = entry->next;
  67. }
  68. }
  69. }
  70. static inline Table* initTable() {
  71. Table *table = malloc(sizeof(Table));
  72. table->entries = (TableEntry**) calloc(sizeof(TableEntry*), TABLE_NUM_LANES);
  73. // alignof === sizeof for primitive data types, C99 doesn't have 'alignof'
  74. insertPadZeroes(table, "char", sizeof(char), sizeof(char));
  75. insertPadZeroes(table, "signed char", sizeof(signed char), sizeof(signed char));
  76. insertPadZeroes(table, "unsigned char", sizeof(unsigned char), sizeof(unsigned char));
  77. insertPadZeroes(table, "short", sizeof(short), sizeof(short));
  78. insertPadZeroes(table, "short int", sizeof(short int), sizeof(short int));
  79. insertPadZeroes(table, "signed short", sizeof(signed short), sizeof(signed short));
  80. insertPadZeroes(table, "signed short int", sizeof(signed short int), sizeof(signed short int));
  81. insertPadZeroes(table, "unsigned short", sizeof(unsigned short), sizeof(unsigned short));
  82. insertPadZeroes(table, "unsigned short int", sizeof(unsigned short int), sizeof(unsigned short int));
  83. insertPadZeroes(table, "int", sizeof(int), sizeof(int));
  84. insertPadZeroes(table, "signed", sizeof(signed), sizeof(signed));
  85. insertPadZeroes(table, "signed int", sizeof(signed int), sizeof(signed int));
  86. insertPadZeroes(table, "unsigned", sizeof(unsigned), sizeof(unsigned));
  87. insertPadZeroes(table, "unsigned int", sizeof(unsigned int), sizeof(unsigned int));
  88. insertPadZeroes(table, "long", sizeof(long), sizeof(long));
  89. insertPadZeroes(table, "long int", sizeof(long int), sizeof(long int));
  90. insertPadZeroes(table, "signed long", sizeof(signed long), sizeof(signed long));
  91. insertPadZeroes(table, "signed long int", sizeof(signed long int), sizeof(signed long int));
  92. insertPadZeroes(table, "unsigned long", sizeof(unsigned long), sizeof(unsigned long));
  93. insertPadZeroes(table, "unsigned long int", sizeof(unsigned long int), sizeof(unsigned long int));
  94. insertPadZeroes(table, "long long", sizeof(long long), sizeof(long long));
  95. insertPadZeroes(table, "long long int", sizeof(long long int), sizeof(long long int));
  96. insertPadZeroes(table, "signed long long", sizeof(signed long long), sizeof(signed long long));
  97. insertPadZeroes(table, "signed long long int", sizeof(signed long long int), sizeof(signed long long int));
  98. insertPadZeroes(table, "unsigned long long", sizeof(unsigned long long), sizeof(unsigned long long));
  99. insertPadZeroes(table, "unsigned long long int", sizeof(unsigned long long int), sizeof(unsigned long long int));
  100. insertPadZeroes(table, "float", sizeof(float), sizeof(float));
  101. insertPadZeroes(table, "double", sizeof(double), sizeof(double));
  102. insertPadZeroes(table, "long double", sizeof(long double), sizeof(long double));
  103. insertPadZeroes(table, "size_t", sizeof(size_t), sizeof(size_t));
  104. insertPadZeroes(table, "ssize_t", sizeof(ssize_t), sizeof(ssize_t));
  105. insertPadZeroes(table, "bool", sizeof(bool), sizeof(bool));
  106. insertPadZeroes(table, "_Bool", sizeof(_Bool), sizeof(_Bool));
  107. return table;
  108. }
  109. static Table *typeTable;