diff --git a/.gitignore b/.gitignore index 77f2048..ab9ba69 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ tags *.un~ +/foobar diff --git a/cig.h b/cig.h index 4535a15..5e7af07 100644 --- a/cig.h +++ b/cig.h @@ -170,7 +170,7 @@ void *dyn_array_create_func(dyn_array_create_func_args_t args); .line = __LINE__, \ .allocator = __VA_ARGS__, \ }); \ -} while(0); +} while(0) // Always reassign the array. if multiple variables reference the same growing // array, then you should be using pointer pointers. @@ -278,10 +278,10 @@ void *map_create_func(map_create_func_args_t args); .line=__LINE__, \ .allocator=__VA_ARGS__ \ }); \ -} while(0); +} while(0) #define init_set(PTR, ...) do { \ - (*(PTR)) = map_create_func(map_create_func_args_t) { \ + (*(PTR)) = map_create_func((map_create_func_args_t) { \ .item_size=sizeof(*(*(PTR))), \ .key_size=sizeof(*(*(PTR))), \ .key_offset=0, \ @@ -289,7 +289,7 @@ void *map_create_func(map_create_func_args_t args); .line=__LINE__, \ .allocator=__VA_ARGS__ \ }); \ -} while(0); +} while(0) int map_len(void *this); int map_cap(void *this); @@ -297,6 +297,28 @@ uint32_t fnv_1a(const uint8_t *bytes, const unsigned int size); // Used for debugging the mapping array. Prints out nerdfonts icons to indicate // the state of each mapping slot. void map_print_mapping_state(void *this, FILE *file); +// Checks that the map can handle one more item. The maps capacity grows if not, +// usually by doubling the capacity. +void map_assure_growable_by_1(void **this, const char *file, int line); + +typedef struct index_pair { + unsigned int new_index; + unsigned int old_index; + bool has_old_index; +} index_pair_t; +/* + * Hashes modulo the header->mapping_capacity. Will linearly probe until a free + * slot is found. If the key already exists in the mapping array, that will be + * indicated in the return value, and the user is expected to overwrite the old + * index with a tombstone if they are going to write a new value for that key. + */ +index_pair_t map_pair_hash(void *this, void *pair); + +// TODO: NOT DONE +#define map_add(THIS, PAIR) do { \ + map_assure_growable_by_1(THIS, __FILE__, __LINE__); \ + index_pair_t idx_pair = map_pair_hash((*(THIS)), pair); \ +} while (0) // CLI ///////////////////////////////////////////////////////////////////////// diff --git a/foobar.c b/foobar.c new file mode 100644 index 0000000..218c802 --- /dev/null +++ b/foobar.c @@ -0,0 +1,12 @@ +#define CIG_IMPL +#include "cig.h" + +int main() { + with_borrow(allocator) { + int *ints; + init_set(&ints, allocator, .initial_capacity=20); + map_print_mapping_state(ints, stdout); + set_add(ints, 10); + map_print_mapping_state(ints, stdout); + } +} diff --git a/justfile b/justfile index ab443b5..213bc7e 100644 --- a/justfile +++ b/justfile @@ -5,6 +5,17 @@ TESTBIN := "/tmp/all_tests" set shell := ["bash", "-cu"] +FOOBAR := "foobar" + +run_foobar: build_foobar + ./{{FOOBAR}} + +build_foobar: + {{CC}} ./foobar.c -o {{FOOBAR}} + +clean_foobar: + rm {{FOOBAR}} + test: build {{TESTBIN}} diff --git a/map.c b/map.c index 7e9ef99..de93db7 100644 --- a/map.c +++ b/map.c @@ -16,6 +16,13 @@ #define DEFAULT ESC "0m" #define COLORED(COLOR, TEXT) COLOR TEXT DEFAULT +static int internal_map_mod(int a, int b) { + int r = a % b; + if (r < 0) r += (b > 0 ? b : -b); + return r; +} +#define mod(a, b) internal_map_mod(a, b) + void map_print_mapping_state(void *this, FILE *file) { map_header_t *header = PTR_FROM_FIELD_PTR(map_header_t, bytes, this); for ( int i = 0; i < header->mapping_capacity; i++ ) { @@ -89,12 +96,6 @@ void *map_create_func( return header->bytes; } -typedef struct index_pair { - unsigned int new_index; - unsigned int old_index; - bool has_old_index; -} index_pair_t; - static const void *internal_cig_key_ptr_from_pair_ptr(const void *this, const void *pair) { map_header_t *header = PTR_FROM_FIELD_PTR(map_header_t, bytes, this); return (const void *) &((const char *)pair)[header->key_offset]; @@ -116,12 +117,24 @@ bool map_key_equals(void *this, const void *key1, const void *key2) { return true; } -/* - * Hashes modulo the header->mapping_capacity. Will linearly probe until a free - * slot is found. If the key already exists in the mapping array, that will be - * indicated in the return value, and the user is expected to overwrite the old - * index with a tombstone if they are going to write a new value for that key. - */ +int map_place(void *this, index_pair_t idx_pair) { + map_header_t *header = PTR_FROM_FIELD_PTR(map_header_t, bytes, this); + if (idx_pair.has_old_index) { + header->mapping_arr[idx_pair.new_index] = header->mapping_arr[idx_pair.old_index]; + header->mapping_arr[idx_pair.old_index] = FLAG_TOMBSTONE; + for ( long i = idx_pair.old_index; i != idx_pair.new_index; mod(i-1, header->mapping_capacity) ) { + if (header->mapping_arr[i] == FLAG_TOMBSTONE) { + header->mapping_arr[i] = FLAG_FREE; + } else { + break; + } + } + } + // TODO WRONG!!! + + return idx_pair.new_index; +} + index_pair_t map_pair_hash(void *this, void *pair) { map_header_t *header = PTR_FROM_FIELD_PTR(map_header_t, bytes, this); const void *key = internal_cig_key_ptr_from_pair_ptr(this, pair); @@ -184,8 +197,6 @@ index_pair_t map_pair_hash(void *this, void *pair) { } } -// Checks that the map can handle one more item. The maps capacity grows if not, -// usually by doubling the capacity. void map_assure_growable_by_1(void **this, const char *file, int line) { map_header_t *header = PTR_FROM_FIELD_PTR(map_header_t, bytes, *this); unsigned int new_n_items = header->n_items + 1;