From e0d78813d0f49cdc5e04dc63a602f18c18a4eef8 Mon Sep 17 00:00:00 2001 From: attilavs2 Date: Wed, 5 Mar 2025 14:38:36 +0100 Subject: [PATCH] Real hashmap --- .gitignore | 0 Makefile | 3 ++- examples/hello_world.flsp | 0 examples/more_or_less.flsp | 0 spec.md | 0 src/byte_defs.h | 21 +++++++++------- src/bytecode.c | 9 +++++++ src/code_defs.h | 0 src/config.h | 0 src/fixed.h | 0 src/hash.c | 51 ++++++++++++++++++++------------------ src/hash.h | 16 ++++++------ src/main.c | 18 ++++++-------- src/types.h | 4 +++ 14 files changed, 70 insertions(+), 52 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 Makefile mode change 100644 => 100755 examples/hello_world.flsp mode change 100644 => 100755 examples/more_or_less.flsp mode change 100644 => 100755 spec.md mode change 100644 => 100755 src/byte_defs.h create mode 100755 src/bytecode.c mode change 100644 => 100755 src/code_defs.h mode change 100644 => 100755 src/config.h mode change 100644 => 100755 src/fixed.h mode change 100644 => 100755 src/hash.c mode change 100644 => 100755 src/hash.h mode change 100644 => 100755 src/main.c mode change 100644 => 100755 src/types.h diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index 5fb9c72..742de97 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ OUTNAME = flisp -CFLAGS = -O0 -Wall -Wextra -g -pipe +CFLAGS = -O0 -Wall -Wextra -g -pipe CC = gcc @@ -27,6 +27,7 @@ windef: $(eval OUTPUT = "$(OUTNAME).exe") $(eval BUILD_DIR = build-win) $(eval LDFLAGS = $(LDFLAGS_WIN)) + $(eval CFLAGS += -mno-ms-bitfields -D win) builddir: @- mkdir $(BUILD_DIR) diff --git a/examples/hello_world.flsp b/examples/hello_world.flsp old mode 100644 new mode 100755 diff --git a/examples/more_or_less.flsp b/examples/more_or_less.flsp old mode 100644 new mode 100755 diff --git a/spec.md b/spec.md old mode 100644 new mode 100755 diff --git a/src/byte_defs.h b/src/byte_defs.h old mode 100644 new mode 100755 index 9e5965c..756c6b3 --- a/src/byte_defs.h +++ b/src/byte_defs.h @@ -73,41 +73,44 @@ typedef struct { typedef struct { - u8 __padding[2]; u32 value; + u8 __padding[2]; } PACKED Value4B; typedef struct { - u16 len; u32 pos; // Offset from stack allocator + u16 len; } PACKED ValueArray; typedef struct { - u8 len; - union { + PACKED union { char str[5]; - struct { - u8 __padding; + PACKED struct { u32 pos; + u8 __padding; }; }; + u8 len; } PACKED ValueStr; typedef struct { - uint is_array : 1; - uint type : 15; - + PACKED union { Value4B v4B; ValueArray varray; }; + uint is_array : 1; + uint type : 15; + } PACKED Value; +#ifndef win _Static_assert(sizeof(Value) == 8); +#endif diff --git a/src/bytecode.c b/src/bytecode.c new file mode 100755 index 0000000..f560d6f --- /dev/null +++ b/src/bytecode.c @@ -0,0 +1,9 @@ +#include +#include + +#include "types.h" +#include "byte_defs.h" + +void run_bytecode(){ + +} diff --git a/src/code_defs.h b/src/code_defs.h old mode 100644 new mode 100755 diff --git a/src/config.h b/src/config.h old mode 100644 new mode 100755 diff --git a/src/fixed.h b/src/fixed.h old mode 100644 new mode 100755 diff --git a/src/hash.c b/src/hash.c old mode 100644 new mode 100755 index 6e7b5de..80460ec --- a/src/hash.c +++ b/src/hash.c @@ -10,6 +10,7 @@ int heap_hashmap(HashMap *map, i32 size){ if(size < 32) return 1; map->curr_len = size; + map->curr_id = 0; map->buffer = malloc(sizeof(MapItem)*size); map->bit_free = malloc(sizeof(u32)*size/32); @@ -27,7 +28,7 @@ void free_hashmap(HashMap *map){ } // ~djb2 -u32 hash(i32 max, char *str){ +i32 hash(i32 max, char *str){ if(!str) return HASH_NULL; u32 hsh = 5281; @@ -51,44 +52,42 @@ void set_bit(u32 *bitmap, i32 pos){ bitmap[pos/32] |= (1<<(pos%32)); } -u32 hashmap_insert(HashMap *map, char *str){ +i32 hashmap_insert(HashMap *map, char *str){ #if DEBUG > 0 float load_factor = (float)(map->item_n+1)/(float)(map->curr_len); //printf("%f\n", load_factor); #if DEBUG == 1 - assert(load_factor < 0.95); - #else assert(load_factor < 0.8); + #else + assert(load_factor < 0.7); #endif #endif if(map->item_n+1 >= map->curr_len) - return HASH_NULL; - u32 hsh = hash(map->curr_len, str); - char *match = hashmap_get(map, hsh); - if(match){ - if(!strncmp(match, str, 32)) - return hsh; + return HASH_NULL; + i32 hsh = hash(map->curr_len, str); + i32 match = hashmap_get(map, str); + if(match > 0){ + return match; } if(!map->bit_free[hsh/32]){ - printf("[ncan]"); map->buffer[hsh].hash = hsh; + map->buffer[hsh].id = map->curr_id++; strncpy(map->buffer[hsh].str, str, 32); set_bit(map->bit_free, hsh); map->item_n++; - return hsh; + return map->buffer[hsh].id; } - u32 pos = hsh; + i32 pos = hsh; i32 taken; do { taken = get_bit(map->bit_free, pos); if(!taken) break; pos++; - } while(pos < map->curr_len); - printf("(%d %d)", hsh, pos); + } while(pos < map->curr_len && pos-hsh < RELOCATE_TRY_MAX); #if DEBUG == 2 assert(!taken); @@ -96,28 +95,32 @@ u32 hashmap_insert(HashMap *map, char *str){ if(!taken){ map->buffer[pos].hash = hsh; - strncpy(map->buffer[hsh].str, str, 32); + map->buffer[pos].id = map->curr_id++; + strncpy(map->buffer[pos].str, str, 32); set_bit(map->bit_free, hsh); map->item_n++; - return hsh; + return map->buffer[pos].id; } return HASH_NULL; } -char *hashmap_get(HashMap *map, u32 fhash){ - u32 pos = fhash; +i32 hashmap_get(HashMap *map, char *str){ + i32 fhash = hash(map->curr_len, str); + i32 pos = fhash; i32 match; do { - u32 c_hash = map->buffer[pos].hash; + i32 c_hash = map->buffer[pos].hash; match = c_hash == fhash; - printf("[%d %d]", c_hash, fhash); + if(match) + match = !strncmp(str,map->buffer[pos].str,32); pos++; - } while(!match && pos < map->curr_len); + } while(!match && pos < map->curr_len && pos-fhash < RELOCATE_TRY_MAX); pos--; + if(match) - return map->buffer[pos].str; + return map->buffer[pos].id; else - return NULL; + return -1; } diff --git a/src/hash.h b/src/hash.h old mode 100644 new mode 100755 index fc592ac..ab1c302 --- a/src/hash.h +++ b/src/hash.h @@ -7,12 +7,13 @@ #define HASH_NULL 0xFFFFFF -#define LOAD_EXTEND fix(0.7) +#define RELOCATE_TRY_MAX 32 typedef struct { - u32 hash; // Hashs are internally 24bit for bytecode ops + i32 hash; // Hashs are internally 24bit for bytecode ops char str[32]; + i32 id; } MapItem; @@ -20,8 +21,9 @@ typedef struct { MapItem *buffer; u32 *bit_free; // Bit map to track usage - u32 curr_len; - u32 item_n; + i32 curr_len; + i32 item_n; + i32 curr_id; } HashMap; @@ -30,9 +32,9 @@ int heap_hashmap(HashMap *map, i32 size); void free_hashmap(HashMap *map); // Max is max value of hash -u32 hash(i32 max, char *str); +i32 hash(i32 max, char *str); // Returns hash - if error returns HASH_NULL -u32 hashmap_insert(HashMap *map, char *str); +i32 hashmap_insert(HashMap *map, char *str); -char *hashmap_get(HashMap *map, u32 hash); +i32 hashmap_get(HashMap *map, char *str); diff --git a/src/main.c b/src/main.c old mode 100644 new mode 100755 index e0102e9..28d366f --- a/src/main.c +++ b/src/main.c @@ -11,9 +11,10 @@ #define STR_N 20 int main(){ + HashMap map; - if(heap_hashmap(&map, 256)){ - printf("Failed to alloc hashmap"); + if(heap_hashmap(&map, 256) ){ + printf("Failed to alloc hashmap\n"); return 1; } @@ -40,19 +41,14 @@ int main(){ "b" }; - char *strings2[STR_N]; - - int hashs[STR_N]; + int ids[STR_N]; for(int i = 0; i < STR_N; i++) - hashs[i] = hashmap_insert(&map, strings[i]); - for(int i = 0; i < STR_N; i++){ - strings2[i] = hashmap_get(&map, hashs[i]); - printf("%d : %s\n", hashs[i], strings2[i]); - } + ids[i] = hashmap_insert(&map, strings[i]); i32 res = 0; for(int i = 0; i < STR_N; i++){ - res += strncmp(strings[i], strings2[i], 32); + res = ids[i] - hashmap_get(&map, strings[i]); + printf("%s : %d:%d\n", strings[i], hashmap_get(&map, strings[i]),ids[i]); } assert(!res); diff --git a/src/types.h b/src/types.h old mode 100644 new mode 100755 index d2f2c2d..c6ebdd9 --- a/src/types.h +++ b/src/types.h @@ -13,5 +13,9 @@ typedef uint64_t u64; typedef unsigned int uint; +#ifdef win +#define PACKED __attribute__((gcc_struct)) __attribute__((__packed__)) +#else #define PACKED __attribute__((__packed__)) +#endif