start creating base objects for runtime

This commit is contained in:
2025-06-24 01:55:01 +01:00
parent 74c71c3a1b
commit 498cd39c04
16 changed files with 414 additions and 153 deletions

View File

@@ -1,143 +1,112 @@
#include "hashmap.h"
#include <stdint.h>
#include <gc/gc.h>
#include <stdlib.h>
#include "../../../memory.h"
#include <gc/gc.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
struct hashmap *createHashmap(int size)
{
struct hashmap *t = (struct hashmap *)ar_alloc(sizeof(struct hashmap));
t->size = size;
t->list = (struct node **)ar_alloc(sizeof(struct node *) * size);
int i;
for (i = 0; i < size; i++)
t->list[i] = NULL;
return t;
struct hashmap *createHashmap() {
size_t size = 8;
struct hashmap *t = (struct hashmap *)ar_alloc(sizeof(struct hashmap));
t->size = size;
t->order = 1;
t->list = (struct node **)ar_alloc(sizeof(struct node *) * size);
memset(t->list, 0, sizeof(struct node *) * size);
return t;
}
void resize_hashmap(struct hashmap *t)
{
int old_size = t->size;
int new_size = old_size * 2;
void resize_hashmap(struct hashmap *t) {
int old_size = t->size;
int new_size = old_size * 2;
struct node **old_list = t->list;
struct node **old_list = t->list;
// Create new list
t->list = (struct node **)ar_alloc(sizeof(struct node *) * new_size);
for (int i = 0; i < new_size; i++)
t->list[i] = NULL;
// Create new list
t->list = (struct node **)ar_alloc(sizeof(struct node *) * new_size);
memset(t->list, 0, sizeof(struct node *) * new_size);
t->size = new_size;
t->count = 0;
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];
while (temp) {
hashmap_insert(t, temp->hash, temp->key, temp->val); // Will increment count
temp = temp->next;
}
// Rehash old entries into new list
for (int i = 0; i < old_size; i++) {
struct node *temp = old_list[i];
while (temp) {
hashmap_insert(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(struct hashmap *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;
while (temp) {
if (temp->hash == hash) {
if (prev)
prev->next = temp->next;
else
t->list[pos] = temp->next;
return 1;
}
prev = temp;
temp = temp->next;
}
list = NULL;
prev = NULL;
temp = NULL;
return 0;
}
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;
while (temp)
{
if (temp->hash == hash)
{
if (prev)
prev->next = temp->next;
else
t->list[pos] = temp->next;
void hashmap_insert(struct hashmap *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);
}
free(temp);
return 1;
}
prev = temp;
temp = temp->next;
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
// Check if key exists → overwrite
while (temp) {
if (temp->hash == hash) {
temp->val = val;
return;
}
return 0;
temp = temp->next;
}
// Insert new node
struct node *newNode = (struct node *)ar_alloc(sizeof(struct node));
newNode->hash = hash;
newNode->key = key;
newNode->val = val;
newNode->order = order;
newNode->next = list;
t->list[pos] = newNode;
t->count++;
}
void resize(struct hashmap *t)
{
int old_size = t->size;
int new_size = old_size * 2;
struct node **old_list = t->list;
// Create new list
t->list = (struct node **)ar_alloc(sizeof(struct node *) * new_size);
for (int i = 0; i < new_size; i++)
t->list[i] = NULL;
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];
while (temp) {
hashmap_insert(t, temp->hash, temp->key, temp->val); // Will increment count
temp = temp->next;
}
void *hashmap_lookup(struct hashmap *t, uint64_t hash) {
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
while (temp) {
if (temp->hash == hash) {
return temp->val;
}
}
void hashmap_insert(struct hashmap *t, uint64_t hash, ArgonObject* key, ArgonObject* val)
{
if ((t->count + 1) > t->size * 0.75) {
resize(t);
}
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
// Check if key exists → overwrite
while (temp)
{
if (temp->key == key)
{
temp->val = val;
return;
}
temp = temp->next;
}
// Insert new node
struct node *newNode = (struct node *)ar_alloc(sizeof(struct node));
newNode->hash = hash;
newNode->key = key;
newNode->val = val;
newNode->next = list;
t->list[pos] = newNode;
t->count++;
}
void *lookup(struct hashmap *t, uint64_t hash)
{
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
while (temp)
{
if (temp->hash == hash)
{
return temp->val;
}
temp = temp->next;
}
return NULL;
temp = temp->next;
}
return NULL;
}

View File

@@ -5,26 +5,29 @@
typedef struct ArgonObject ArgonObject;
struct node
{
uint64_t hash;
ArgonObject *key;
ArgonObject *val;
struct node *next;
struct node {
uint64_t hash;
void *key;
void *val;
size_t order;
struct node *next;
};
struct hashmap
{
size_t size;
size_t count;
struct node **list;
struct hashmap {
size_t size;
size_t count;
size_t order;
struct node **list;
};
struct hashmap *createHashmap(int size);
struct hashmap *createHashmap();
int hashCode(struct hashmap *t, uint64_t hash);
int hashmap_remove(struct hashmap *t, uint64_t hash);
void hashmap_insert(struct hashmap *t, uint64_t hash, ArgonObject* key, ArgonObject* val);
void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
void *val, size_t order);
void *hashmap_lookup(struct hashmap *t, uint64_t hash);
#endif // HASHMAP_H

View File

@@ -0,0 +1,100 @@
#include "list.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../../memory.h"
LinkedList *create_list(size_t data_size) {
LinkedList *list = checked_malloc(sizeof(LinkedList));
list->head = NULL;
list->data_size = data_size;
list->length = 0;
return list;
}
void append(LinkedList *list, void *element) {
Node *new_node = checked_malloc(sizeof(Node));
new_node->data = checked_malloc(list->data_size);
memcpy(new_node->data, element, list->data_size);
new_node->next = NULL;
if (!list->head) {
list->head = new_node;
} else {
Node *temp = list->head;
while (temp->next)
temp = temp->next;
temp->next = new_node;
}
list->length++;
}
void *get_element_at(LinkedList *list, size_t index) {
if (index >= list->length)
return NULL;
Node *current = list->head;
for (size_t i = 0; i < index; ++i)
current = current->next;
return current->data;
}
int set_element_at(LinkedList *list, size_t index, void *element) {
if (index >= list->length)
return 0;
Node *current = list->head;
for (size_t i = 0; i < index; ++i)
current = current->next;
memcpy(current->data, element, list->data_size);
return 1;
}
int remove_at(LinkedList *list, size_t index) {
if (index >= list->length)
return 0;
Node *temp = list->head;
Node *prev = NULL;
for (size_t i = 0; i < index; ++i) {
prev = temp;
temp = temp->next;
}
if (prev)
prev->next = temp->next;
else
list->head = temp->next;
free(temp->data);
free(temp);
list->length--;
return 1;
}
size_t list_length(LinkedList *list) { return list->length; }
void print_list(LinkedList *list, void (*print_func)(void *)) {
Node *current = list->head;
while (current) {
print_func(current->data);
current = current->next;
}
}
void free_list(LinkedList *list, void (*free_data)(void *)) {
Node *current = list->head;
while (current) {
Node *next = current->next;
if (free_data) // Safe to pass NULL if you don't need it
free_data(current->data);
free(current);
current = next;
}
free(list);
}

View File

@@ -0,0 +1,42 @@
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <stddef.h> // for size_t
// Node structure (opaque to user)
typedef struct Node {
void *data;
struct Node *next;
} Node;
typedef struct LinkedList {
Node *head;
size_t data_size;
size_t length;
} LinkedList;
// Create a new list for the given data type size
LinkedList *create_list(size_t data_size);
// Append an element to the list
void append(LinkedList *list, void *element);
// Get a pointer to the element at the given index
void *get_element_at(LinkedList *list, size_t index);
// Set the element at the given index
int set_element_at(LinkedList *list, size_t index, void *element);
// Remove the element at the given index
int remove_at(LinkedList *list, size_t index);
// Get the number of elements in the list
size_t list_length(LinkedList *list);
// Print the list using a provided print function
void print_list(LinkedList *list, void (*print_func)(void *));
// Free all memory used by the list
void free_list(LinkedList *list, void (*free_data)(void *));
#endif // LINKEDLIST_H

View File

@@ -0,0 +1,185 @@
/*
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

@@ -0,0 +1,22 @@
/*
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);