Compare commits
5 Commits
5476ba3ad9
...
5eb99e742d
Author | SHA1 | Date | |
---|---|---|---|
|
5eb99e742d | ||
|
bd781f335c | ||
|
35de7aa57d | ||
|
eb40561074 | ||
|
4b272786a5 |
4
amap.h
4
amap.h
@ -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 NULL if there is no ptr for the key.
|
* AMAP_GET Gets the symbol at key (the ptr parameter is unused). Returns "ptr" if there is no data 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.
|
* @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.
|
||||||
* @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);
|
||||||
|
14
main.cpp
14
main.cpp
@ -1,8 +1,22 @@
|
|||||||
#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
36
simap.h
@ -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*) alloc(&(ret.a), sizeof(uint64_t), sizeof(uint64_t), 1)) /* addr divisible by 8 */
|
ret.base = ((uint64_t*) aralloc(&(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 == (uin32_t) -1) {
|
if(previ == (uint32_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,8 +132,12 @@ 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) {
|
||||||
// return (alignment - (size % alignment)) % alignment;
|
/* Would ensure returned value divisible by 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 */
|
||||||
@ -151,8 +155,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*/,
|
||||||
@ -174,7 +178,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_ptr_64 *)((uint8_t *)(map->base) + usi);
|
simap_ptr64 *data = (simap_ptr64 *)((uint8_t *)(map->base) + usi);
|
||||||
data->ptr = ptr;
|
data->ptr = ptr;
|
||||||
|
|
||||||
/* Save link to previous */
|
/* Save link to previous */
|
||||||
@ -186,21 +190,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 = (uint8_t *)(usprev + 2);
|
simap_c64 *start_str = (simap_c64 *)(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 = (uint8_t *)(map->base) + previ +
|
uint32_t *prevnex = (uint32_t *)((uint8_t *)(map->base) + previ +
|
||||||
sizeof(simap_ptr64) +
|
sizeof(simap_ptr64) +
|
||||||
sizeof(uint32_t);
|
sizeof(uint32_t));
|
||||||
*prevnex = usi;
|
*prevnex = usi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +214,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 NULL;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,13 +223,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 NULL if there is no ptr for the key.
|
* AMAP_GET Gets the symbol at key (the ptr parameter is unused). Returns "ptr" if there is no data 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.
|
* @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...
|
||||||
* @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) {
|
||||||
@ -240,7 +244,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->ptr;
|
return found ? found->ptr : ptr;
|
||||||
} else {
|
} else {
|
||||||
assert(op == AMAP_SET);
|
assert(op == AMAP_SET);
|
||||||
|
|
||||||
@ -254,7 +258,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 NULL;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SIMAP_H */
|
#endif /* SIMAP_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user