From 5476ba3ad940ec4923243158cc3024bfa0dbeec8 Mon Sep 17 00:00:00 2001 From: Richard Thier Date: Tue, 1 Oct 2024 17:49:48 +0200 Subject: [PATCH] finalized implementation, but probably buggy --- simap.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/simap.h b/simap.h index 47aa2fe..d56ed0e 100644 --- a/simap.h +++ b/simap.h @@ -48,6 +48,7 @@ typedef union simap_ptr64 simap_ptr64; struct simap_instance { arena a; uint32_t end; + uint32_t prev_usage_end; /* previous usage_end or -1 if no previous exists... in bytes!!! */ uint32_t usage_end; /* in bytes!!! */ uint32_t next_previndex; /* in bytes!!! */ /** see doc comment for layout and why uint64_t* is the type */ @@ -59,6 +60,7 @@ static inline simap_instance simap_create() { simap_instance ret; ret.a = newarena((ptrdiff_t)1 << 33); ret.end = 0; + ret.prev_usage_end = (uint32_t) -1; ret.usage_end = 0; ret.next_previndex = 0; ret.base = ((uint64_t*) alloc(&(ret.a), sizeof(uint64_t), sizeof(uint64_t), 1)) /* addr divisible by 8 */ @@ -99,13 +101,18 @@ static inline simap_ptr64 *simap_search_internal(simap_instance *map, const char } } + simap_ptr64 *ptr = (simap_ptr64 *)((uint8_t *) (tipp - 2)); + /* Check back & forth (jump validation) */ uint32_t previ = *((uint32_t *)(tipp - 1)); + if(previ == (uin32_t) -1) { + /* Expect it be good if it was first insert ever? Statistically rare to be not like it */ + return ptr; + } uint32_t prevnexi = *(uint32_t *)(((uint8_t *)base) + previ + sizeof(simap_ptr64) + sizeof(uint32_t)); - simap_ptr64 *ptr = (simap_ptr64 *)((uint8_t *)base + prevnexi); uint64_t *retipp = (uint64_t *)(((uint8_t *)base + prevnexi) + sizeof(simap_ptr64) + sizeof(uint32_t) + + sizeof(uint32_t)); @@ -157,7 +164,52 @@ static inline void *simap_force_add_internal(simap_instance *map, const char *ke } /* Already have the storage */ - /* TODO: Implement - beware that I NEED to store the first 8 characters as a simap_c64! */ + + /* Create first 8 char encoding (this ensures endianness and all such stuff) */ + simap_c64 first8 {0}; + uint32_t keylen = strlen(key); + strncpy(first8.str8, key, (keylen < 8) ? keylen : 8); + + uint32_t usi = map->usage_end; + uint32_t previ = map->prev_usage_end; + + /* Save data ptr */ + simap_ptr64 *data = (simap_ptr_64 *)((uint8_t *)(map->base) + usi); + data->ptr = ptr; + + /* Save link to previous */ + uint32_t *usprev = (uint32_t *)((uint8_t *)(map->base) + + sizeof(simap_ptr64) + + sizeof(uint32_t)); + *usprev = previ; + /* and nex */ + *(usprev + 1) = (uint32_t) -1; + + /* First 8 bytes */ + simap_c64 *start_str = (uint8_t *)(usprev + 2); + *start_str = first8; + + /* Remainin bytes */ + if(keylen > 8) { + uint32_t key_remains = keylen - 8; + char *rem_str = (char *)(start_str + 1); + strcpy(rem_str, key + 8); + } + + /* Update previous with linkage */ + if(previ != (uint32_t)-1) { + uint32_t *prevnex = (uint8_t *)(map->base) + previ + + sizeof(simap_ptr64) + + sizeof(uint32_t); + *prevnex = usi; + } + + /* Update prev usage end */ + map->prev_usage_end = usi; + + /* Administer usage_end offset */ + map->usage_end += storage_needed; + return NULL; }