use hashmap in constants buffer to speed up translation time with large files

This commit is contained in:
2025-06-30 17:56:32 +01:00
parent 31f38d8ba4
commit 3adecb4eba
18 changed files with 1120882 additions and 83 deletions

View File

@@ -7,47 +7,47 @@
#include <stdlib.h>
#include <string.h>
struct hashmap *createHashmap() {
struct hashmap_GC *createHashmap_GC() {
size_t size = 8;
struct hashmap *t = (struct hashmap *)ar_alloc(sizeof(struct hashmap));
struct hashmap_GC *t = (struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC));
t->size = size;
t->order = 1;
t->list = (struct node **)ar_alloc(sizeof(struct node *) * size);
memset(t->list, 0, sizeof(struct node *) * size);
t->list = (struct node_GC **)ar_alloc(sizeof(struct node_GC *) * size);
memset(t->list, 0, sizeof(struct node_GC *) * size);
return t;
}
void resize_hashmap(struct hashmap *t) {
void resize_hashmap_GC(struct hashmap_GC *t) {
int old_size = t->size;
int new_size = old_size * 2;
struct node **old_list = t->list;
struct node_GC **old_list = t->list;
// Create new list
t->list = (struct node **)ar_alloc(sizeof(struct node *) * new_size);
memset(t->list, 0, sizeof(struct node *) * new_size);
t->list = (struct node_GC **)ar_alloc(sizeof(struct node_GC *) * new_size);
memset(t->list, 0, sizeof(struct node_GC *) * new_size);
t->size = new_size;
t->count = 0;
// Rehash old entries into new list
for (int i = 0; i < old_size; i++) {
struct node *temp = old_list[i];
struct node_GC *temp = old_list[i];
while (temp) {
hashmap_insert(t, temp->hash, temp->key, temp->val,
hashmap_insert_GC(t, temp->hash, temp->key, temp->val,
temp->order); // Will increment count
temp = temp->next;
}
}
}
int hashCode(struct hashmap *t, uint64_t hash) { return hash % t->size; }
int hashCode_GC(struct hashmap_GC *t, uint64_t hash) { return hash % t->size; }
int hashmap_remove(struct hashmap *t, uint64_t hash) {
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
struct node *prev = NULL;
int hashmap_remove_GC(struct hashmap_GC *t, uint64_t hash) {
int pos = hashCode_GC(t, hash);
struct node_GC *list = t->list[pos];
struct node_GC *temp = list;
struct node_GC *prev = NULL;
while (temp) {
if (temp->hash == hash) {
if (prev)
@@ -65,18 +65,18 @@ int hashmap_remove(struct hashmap *t, uint64_t hash) {
return 0;
}
void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
void hashmap_insert_GC(struct hashmap_GC *t, uint64_t hash, void *key,
void *val, size_t order) {
if (!order) {
order = t->order++;
}
if ((t->count + 1) > t->size * 0.75) {
resize_hashmap(t);
resize_hashmap_GC(t);
}
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
int pos = hashCode_GC(t, hash);
struct node_GC *list = t->list[pos];
struct node_GC *temp = list;
// Check if key exists → overwrite
while (temp) {
@@ -88,7 +88,7 @@ void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
}
// Insert new node
struct node *newNode = (struct node *)ar_alloc(sizeof(struct node));
struct node_GC *newNode = (struct node_GC *)ar_alloc(sizeof(struct node_GC));
newNode->hash = hash;
newNode->key = key;
newNode->val = val;
@@ -98,10 +98,10 @@ void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
t->count++;
}
void *hashmap_lookup(struct hashmap *t, uint64_t hash) {
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
void *hashmap_lookup_GC(struct hashmap_GC *t, uint64_t hash) {
int pos = hashCode_GC(t, hash);
struct node_GC *list = t->list[pos];
struct node_GC *temp = list;
while (temp) {
if (temp->hash == hash) {
return temp->val;

View File

@@ -1,33 +1,33 @@
#ifndef HASHMAP_H
#define HASHMAP_H
#ifndef HASHMAP_GC_H
#define HASHMAP_GC_H
#include <stdint.h>
#include <stdlib.h>
typedef struct ArgonObject ArgonObject;
struct node {
struct node_GC {
uint64_t hash;
void *key;
void *val;
size_t order;
struct node *next;
struct node_GC *next;
};
struct hashmap {
struct hashmap_GC {
size_t size;
size_t count;
size_t order;
struct node **list;
struct node_GC **list;
};
struct hashmap *createHashmap();
struct hashmap_GC *createHashmap_GC();
int hashCode(struct hashmap *t, uint64_t hash);
int hashCode_GC(struct hashmap_GC *t, uint64_t hash);
int hashmap_remove(struct hashmap *t, uint64_t hash);
int hashmap_remove_GC(struct hashmap_GC *t, uint64_t hash);
void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
void hashmap_insert_GC(struct hashmap_GC *t, uint64_t hash, void *key,
void *val, size_t order);
void *hashmap_lookup(struct hashmap *t, uint64_t hash);
void *hashmap_lookup_GC(struct hashmap_GC *t, uint64_t hash);
#endif // HASHMAP_H
#endif // HASHMAP_GC_H

View File

@@ -1,185 +0,0 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2022 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "siphash.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
/* default: SipHash-2-4 */
#ifndef cROUNDS
#define cROUNDS 2
#endif
#ifndef dROUNDS
#define dROUNDS 4
#endif
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
#define U32TO8_LE(p, v) \
(p)[0] = (uint8_t)((v)); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24);
#define U64TO8_LE(p, v) \
U32TO8_LE((p), (uint32_t)((v))); \
U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
#define U8TO64_LE(p) \
(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \
((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
#define SIPROUND \
do { \
v0 += v1; \
v1 = ROTL(v1, 13); \
v1 ^= v0; \
v0 = ROTL(v0, 32); \
v2 += v3; \
v3 = ROTL(v3, 16); \
v3 ^= v2; \
v0 += v3; \
v3 = ROTL(v3, 21); \
v3 ^= v0; \
v2 += v1; \
v1 = ROTL(v1, 17); \
v1 ^= v2; \
v2 = ROTL(v2, 32); \
} while (0)
#ifdef DEBUG_SIPHASH
#include <stdio.h>
#define TRACE \
do { \
printf("(%3zu) v0 %016" PRIx64 "\n", inlen, v0); \
printf("(%3zu) v1 %016" PRIx64 "\n", inlen, v1); \
printf("(%3zu) v2 %016" PRIx64 "\n", inlen, v2); \
printf("(%3zu) v3 %016" PRIx64 "\n", inlen, v3); \
} while (0)
#else
#define TRACE
#endif
/*
Computes a SipHash value
*in: pointer to input data (read-only)
inlen: input data length in bytes (any size_t value)
*k: pointer to the key data (read-only), must be 16 bytes
*out: pointer to output data (write-only), outlen bytes must be allocated
outlen: length of the output in bytes, must be 8 or 16
*/
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
const size_t outlen) {
const unsigned char *ni = (const unsigned char *)in;
const unsigned char *kk = (const unsigned char *)k;
assert((outlen == 8) || (outlen == 16));
uint64_t v0 = UINT64_C(0x736f6d6570736575);
uint64_t v1 = UINT64_C(0x646f72616e646f6d);
uint64_t v2 = UINT64_C(0x6c7967656e657261);
uint64_t v3 = UINT64_C(0x7465646279746573);
uint64_t k0 = U8TO64_LE(kk);
uint64_t k1 = U8TO64_LE(kk + 8);
uint64_t m;
int i;
const unsigned char *end = ni + inlen - (inlen % sizeof(uint64_t));
const int left = inlen & 7;
uint64_t b = ((uint64_t)inlen) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
if (outlen == 16)
v1 ^= 0xee;
for (; ni != end; ni += 8) {
m = U8TO64_LE(ni);
v3 ^= m;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= m;
}
switch (left) {
case 7:
b |= ((uint64_t)ni[6]) << 48;
/* FALLTHRU */
case 6:
b |= ((uint64_t)ni[5]) << 40;
/* FALLTHRU */
case 5:
b |= ((uint64_t)ni[4]) << 32;
/* FALLTHRU */
case 4:
b |= ((uint64_t)ni[3]) << 24;
/* FALLTHRU */
case 3:
b |= ((uint64_t)ni[2]) << 16;
/* FALLTHRU */
case 2:
b |= ((uint64_t)ni[1]) << 8;
/* FALLTHRU */
case 1:
b |= ((uint64_t)ni[0]);
break;
case 0:
break;
}
v3 ^= b;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= b;
if (outlen == 16)
v2 ^= 0xee;
else
v2 ^= 0xff;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out, b);
if (outlen == 8)
return 0;
v1 ^= 0xdd;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out + 8, b);
return 0;
}

View File

@@ -1,22 +0,0 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2021 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <inttypes.h>
#include <string.h>
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
const size_t outlen);