Compare commits

..

No commits in common. "5eb99e742d98774d8bee0bc940b323d38074b5a9" and "5476ba3ad940ec4923243158cc3024bfa0dbeec8" have entirely different histories.

3 changed files with 18 additions and 36 deletions

4
amap.h
View File

@ -11,13 +11,13 @@ typedef enum AMAP_OP AMAP_OP;
* Operations: * Operations:
* *
* AMAP_SET Saves a mapping from key->ptr in map. ptr==NULL "tombstones" the mapping to return NULL. Returns null on error! * AMAP_SET Saves a mapping from key->ptr in map. ptr==NULL "tombstones" the mapping to return NULL. Returns null on error!
* AMAP_GET Gets the symbol at key (the ptr parameter is unused). Returns "ptr" if there is no data for the key. * AMAP_GET Gets the symbol at key (the ptr parameter is unused). Returns NULL if there is no ptr for the key.
* AMAP_ERASE Erases the symbol table so it becomes empty again. Can never fail, returns NULL. * AMAP_ERASE Erases the symbol table so it becomes empty again. Can never fail, returns NULL.
* *
* @param amap_instance The instance we operate upon. * @param amap_instance The instance we operate upon.
* @param op Defines which operation the caller wants. * @param op Defines which operation the caller wants.
* @param key The key (both for SET and GET). This pointer can get easily invalidated so you might need a copy or you do Trie, etc. * @param key The key (both for SET and GET). This pointer can get easily invalidated so you might need a copy or you do Trie, etc.
* @param ptr When adding a ptr (data) to the map / table, the key will point to this ptr. Also the nt-found ptr to return in case of GET. * @param ptr When adding a ptr (data) to the map / table, the key will point to this ptr.
* @returns The ptr / data stored for the key, or NULL on tombstone or when not stored yet or op is SET and there was an error. * @returns The ptr / data stored for the key, or NULL on tombstone or when not stored yet or op is SET and there was an error.
*/ */
typedef void* (*amap)(void *amap_instance, AMAP_OP op, const char *key, void *ptr); typedef void* (*amap)(void *amap_instance, AMAP_OP op, const char *key, void *ptr);

View File

@ -1,22 +1,8 @@
#include <cstdio> #include <cstdio>
#include <cassert>
#include "amap.h" #include "amap.h"
#include "simap.h" #include "simap.h"
void test_basics(amap mapdo, void *map) {
assert(NULL == mapdo(map, AMAP_GET, "asdf", NULL));
int i = 42;
int *iptr;
assert(NULL != mapdo(map, AMAP_SET, "meaning", &i));
assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaning", NULL)));
assert(*iptr == 42);
assert(iptr == &i);
}
int main() { int main() {
/* test simap */
simap_instance si = simap_create();
test_basics(simap, &si);
return 0; return 0;
} }

36
simap.h
View File

@ -63,7 +63,7 @@ static inline simap_instance simap_create() {
ret.prev_usage_end = (uint32_t) -1; ret.prev_usage_end = (uint32_t) -1;
ret.usage_end = 0; ret.usage_end = 0;
ret.next_previndex = 0; ret.next_previndex = 0;
ret.base = ((uint64_t*) aralloc(&(ret.a), sizeof(uint64_t), sizeof(uint64_t), 1)) /* addr divisible by 8 */ ret.base = ((uint64_t*) alloc(&(ret.a), sizeof(uint64_t), sizeof(uint64_t), 1)) /* addr divisible by 8 */
+ 1; /* First really addressible thing */ + 1; /* First really addressible thing */
return ret; return ret;
} }
@ -105,7 +105,7 @@ static inline simap_ptr64 *simap_search_internal(simap_instance *map, const char
/* Check back & forth (jump validation) */ /* Check back & forth (jump validation) */
uint32_t previ = *((uint32_t *)(tipp - 1)); uint32_t previ = *((uint32_t *)(tipp - 1));
if(previ == (uint32_t) -1) { if(previ == (uin32_t) -1) {
/* Expect it be good if it was first insert ever? Statistically rare to be not like it */ /* Expect it be good if it was first insert ever? Statistically rare to be not like it */
return ptr; return ptr;
} }
@ -132,12 +132,8 @@ static inline simap_ptr64 *simap_search_internal(simap_instance *map, const char
/** Gets padding bytes for a size to be padded to divisible alignment */ /** Gets padding bytes for a size to be padded to divisible alignment */
static inline unsigned int get_size_padding(unsigned int size, unsigned int alignment) { static inline unsigned int get_size_padding(unsigned int size, unsigned int alignment) {
/* Would ensure returned value divisible by alignment */ // return (alignment - (size % alignment)) % alignment;
/* return (size + alignment - 1) / alignment * alignment; */ return (size + alignment - 1) / alignment * alignment;
/* same: return (alignment - (size % alignment)) % alignment; */
/* Substracting size leads to padding */
return ((size + alignment - 1) / alignment) * alignment - size;
} }
/** Returns the size of the storage needed for the given key */ /** Returns the size of the storage needed for the given key */
@ -155,8 +151,8 @@ static inline uint32_t simap_elem_storage_size(const char *key) {
/** Force-add the (key,value) to the end of the map */ /** Force-add the (key,value) to the end of the map */
static inline void *simap_force_add_internal(simap_instance *map, const char *key, void *ptr) { static inline void *simap_force_add_internal(simap_instance *map, const char *key, void *ptr) {
uint32_t storage_needed = simap_elem_storage_size(key); uint32_t storage_needed = simap_elem_storage_size(key);
assert((storage_needed % 8) == 0); assert((storage_needed & 8) == 0);
if(map->end - map->usage_end < storage_needed) { if(map->end - map->usage_end > storage_needed) {
/* Need storage */ /* Need storage */
aralloc(&(map->a), aralloc(&(map->a),
sizeof(uint8_t)/*esize*/, sizeof(uint8_t)/*esize*/,
@ -178,7 +174,7 @@ static inline void *simap_force_add_internal(simap_instance *map, const char *ke
uint32_t previ = map->prev_usage_end; uint32_t previ = map->prev_usage_end;
/* Save data ptr */ /* Save data ptr */
simap_ptr64 *data = (simap_ptr64 *)((uint8_t *)(map->base) + usi); simap_ptr64 *data = (simap_ptr_64 *)((uint8_t *)(map->base) + usi);
data->ptr = ptr; data->ptr = ptr;
/* Save link to previous */ /* Save link to previous */
@ -190,21 +186,21 @@ static inline void *simap_force_add_internal(simap_instance *map, const char *ke
*(usprev + 1) = (uint32_t) -1; *(usprev + 1) = (uint32_t) -1;
/* First 8 bytes */ /* First 8 bytes */
simap_c64 *start_str = (simap_c64 *)(usprev + 2); simap_c64 *start_str = (uint8_t *)(usprev + 2);
*start_str = first8; *start_str = first8;
/* Remainin bytes */ /* Remainin bytes */
if(keylen > 8) { if(keylen > 8) {
/* uint32_t key_remains = keylen - 8; */ uint32_t key_remains = keylen - 8;
char *rem_str = (char *)(start_str + 1); char *rem_str = (char *)(start_str + 1);
strcpy(rem_str, key + 8); strcpy(rem_str, key + 8);
} }
/* Update previous with linkage */ /* Update previous with linkage */
if(previ != (uint32_t)-1) { if(previ != (uint32_t)-1) {
uint32_t *prevnex = (uint32_t *)((uint8_t *)(map->base) + previ + uint32_t *prevnex = (uint8_t *)(map->base) + previ +
sizeof(simap_ptr64) + sizeof(simap_ptr64) +
sizeof(uint32_t)); sizeof(uint32_t);
*prevnex = usi; *prevnex = usi;
} }
@ -214,7 +210,7 @@ static inline void *simap_force_add_internal(simap_instance *map, const char *ke
/* Administer usage_end offset */ /* Administer usage_end offset */
map->usage_end += storage_needed; map->usage_end += storage_needed;
return data; return NULL;
} }
/** /**
@ -223,13 +219,13 @@ static inline void *simap_force_add_internal(simap_instance *map, const char *ke
* Operations: * Operations:
* *
* AMAP_SET Saves a mapping from key->ptr in map. ptr==NULL "tombstones" the mapping to return NULL. * AMAP_SET Saves a mapping from key->ptr in map. ptr==NULL "tombstones" the mapping to return NULL.
* AMAP_GET Gets the symbol at key (the ptr parameter is unused). Returns "ptr" if there is no data for the key. * AMAP_GET Gets the symbol at key (the ptr parameter is unused). Returns NULL if there is no ptr for the key.
* AMAP_ERASE Erases the symbol table so it becomes empty again. Can never fail, returns NULL. * AMAP_ERASE Erases the symbol table so it becomes empty again. Can never fail, returns NULL.
* *
* @param amap_instance The instance we operate upon. * @param amap_instance The instance we operate upon.
* @param op Defines which operation the caller wants. * @param op Defines which operation the caller wants.
* @param key The key (both for SET and GET). This pointer can get easily invalidated so you might need a copy or you do Trie, etc. * @param key The key (both for SET and GET). This pointer can get easily invalidated so you might need a copy or you do Trie, etc.
* @param ptr When adding a ptr (data) to the map / table, the key will point to this ptr and the "nt found" ptr to return in get... * @param ptr When adding a ptr (data) to the map / table, the key will point to this ptr.
* @returns The ptr / data stored for the key, or NULL on tombstone or when not stored yet or op is SET and there was an error. * @returns The ptr / data stored for the key, or NULL on tombstone or when not stored yet or op is SET and there was an error.
*/ */
static inline void* simap(void *amap_instance, AMAP_OP op, const char *key, void *ptr) { static inline void* simap(void *amap_instance, AMAP_OP op, const char *key, void *ptr) {
@ -244,7 +240,7 @@ static inline void* simap(void *amap_instance, AMAP_OP op, const char *key, void
simap_ptr64 *found = simap_search_internal(map, key); simap_ptr64 *found = simap_search_internal(map, key);
if(op == AMAP_GET) { if(op == AMAP_GET) {
return found ? found->ptr : ptr; return found->ptr;
} else { } else {
assert(op == AMAP_SET); assert(op == AMAP_SET);
@ -258,7 +254,7 @@ static inline void* simap(void *amap_instance, AMAP_OP op, const char *key, void
} }
assert(false); /* should be unreachable */ assert(false); /* should be unreachable */
return ptr; return NULL;
} }
#endif /* SIMAP_H */ #endif /* SIMAP_H */