Real hashmap
This commit is contained in:
parent
238bc31425
commit
e0d78813d0
14 changed files with 70 additions and 52 deletions
0
.gitignore
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
3
Makefile
Normal file → Executable file
3
Makefile
Normal file → Executable file
|
@ -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)
|
||||
|
|
0
examples/hello_world.flsp
Normal file → Executable file
0
examples/hello_world.flsp
Normal file → Executable file
0
examples/more_or_less.flsp
Normal file → Executable file
0
examples/more_or_less.flsp
Normal file → Executable file
0
spec.md
Normal file → Executable file
0
spec.md
Normal file → Executable file
21
src/byte_defs.h
Normal file → Executable file
21
src/byte_defs.h
Normal file → Executable file
|
@ -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
|
||||
|
|
9
src/bytecode.c
Executable file
9
src/bytecode.c
Executable file
|
@ -0,0 +1,9 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "byte_defs.h"
|
||||
|
||||
void run_bytecode(){
|
||||
|
||||
}
|
0
src/code_defs.h
Normal file → Executable file
0
src/code_defs.h
Normal file → Executable file
0
src/config.h
Normal file → Executable file
0
src/config.h
Normal file → Executable file
0
src/fixed.h
Normal file → Executable file
0
src/fixed.h
Normal file → Executable file
51
src/hash.c
Normal file → Executable file
51
src/hash.c
Normal file → Executable file
|
@ -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;
|
||||
}
|
||||
|
|
16
src/hash.h
Normal file → Executable file
16
src/hash.h
Normal file → Executable file
|
@ -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);
|
||||
|
|
18
src/main.c
Normal file → Executable file
18
src/main.c
Normal file → Executable file
|
@ -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);
|
||||
|
||||
|
|
4
src/types.h
Normal file → Executable file
4
src/types.h
Normal file → Executable file
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue