diff --git a/sdk/core/src/include/electronetsoft/arithmos/adt/map.h b/sdk/core/src/include/electronetsoft/arithmos/adt/map.h index 5a68b65..f4c0ad4 100644 --- a/sdk/core/src/include/electronetsoft/arithmos/adt/map.h +++ b/sdk/core/src/include/electronetsoft/arithmos/adt/map.h @@ -12,7 +12,7 @@ extern "C" { #endif struct map_element { - char *key; + typed_pointer key; list_element *value; }; @@ -20,7 +20,7 @@ struct map_processors { status_code (*on_initialization)(map *); status_code (*on_deinitialization)(map *); status_code (*on_insertion)(map *, map_element *, uint64_t); - status_code (*on_resize_dispatch)(map *, list_element **); + status_code (*on_rehash_dispatch)(map *, list_element **); status_code (*on_removal)(map *, list *, uint64_t); status_code (*on_collision)(list *, uint64_t, @@ -41,12 +41,12 @@ struct map { struct map_function_table { status_code (*insert)(map *, map_element *); status_code (*insert_all)(map *, map_element **); - status_code (*remove)(map *, const char *); - status_code (*remove_all)(map *, const char **); - status_code (*resize)(map *, uint64_t); - status_code (*contains)(map *, const char *); - status_code (*contains_all)(map *, const char **); - status_code (*get)(map *, const char *key, map_element *); + status_code (*remove)(map *, typed_pointer); + status_code (*remove_all)(map *, typed_pointer **); + status_code (*rehash)(map *, uint64_t); + status_code (*contains)(map *, typed_pointer); + status_code (*contains_all)(map *, typed_pointer **); + status_code (*get)(map *, typed_pointer key, map_element *); status_code (*iterator)(map *, status_code (*callback)(map *, map_element *)); }; diff --git a/sdk/core/src/include/electronetsoft/util/number/bitwise.h b/sdk/core/src/include/electronetsoft/util/number/bitwise.h new file mode 100644 index 0000000..07e6d9c --- /dev/null +++ b/sdk/core/src/include/electronetsoft/util/number/bitwise.h @@ -0,0 +1,132 @@ +#ifndef __NUM_BITWISE_H_ +#define __NUM_BITWISE_H_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { // disable C++ name mangling by declaring function prototypes + // a C externally linked space +#endif + +/** + * @brief Extracts a byte of base 2 from a 64-bit input + * structure into an 8-bit output structure. + * + * @param in the input 64-bit structure. + * @param out the output 8-bit structure. + * @param i the index of the byte to extract out of the input structure. + * @return EUNDEFINEDBUFFER if the (out) buffer is not pre-allocated + * PASS if the operation has passed successfully. + */ +static inline status_code bitwise_extract_byte(uint64_t in, + uint8_t *out, + uint8_t i) { + if (NULL == out) { + return EUNDEFINEDBUFFER; + } + + *out = (in >> (8 * i)) ^ 0b00000000; + + return PASS; +} + +/** + * @brief Pushes a byte of base 2 into position of index (i) + * into the (out) structure leaving the rest of bytes unchanged. + * + * @param in the input byte of base 2 to push. + * @param out the output 64-bit structure to push the byte into. + * @param i the destined position or index of the byte. + * @return EUNDEFINEDBUFFER if the (out) is not allocated. + * ENOELEMENT if the index is out of bounds. + * PASS if the operation has passed successfully without errors. + */ +static inline status_code bitwise_push_byte(uint8_t in, + uint64_t *out, + uint8_t i) { + if (NULL == out) { + return EUNDEFINEDBUFFER; + } + + if (i >= 8) { + return ENOELEMENT; + } + + *(((uint8_t *) out) + i) = in; + return PASS; +} + +/** + * @brief Exchanges 2 bytes together inside the (in) 64-bit structure + * without changing the rest of the bytes. + * + * @param in the input 64-bit structure. + * @param out the output structure with changed bytes. + * @param i0 the index of the first byte to exchange. + * @param i1 the index of the second byte to exchange. + * @return EUNDEFINEDBUFFER if the (out) buffer is not pre-allocated + * ENOELEMENT if the indexes are out of bounds or equal. + * PASS otherwise. + */ +static inline status_code bitwise_exchange_bytes(uint64_t in, + uint64_t *out, + uint8_t i0, + uint8_t i1) { + if (NULL == out) { + return EUNDEFINEDBUFFER; + } + + if (i0 >= 8 || i1 >= 8 || i0 == i1) { + return ENOELEMENT; + } + + uint8_t byte_0 = ((uint8_t *) &in)[i0]; + uint8_t byte_1 = ((uint8_t *) &in)[i1]; + *(((uint8_t *) out) + i0) = byte_1; + *(((uint8_t *) out) + i1) = byte_0; + return PASS; +} + +static inline status_code bitwise_left_cyclic_shift(uint64_t in, + uint64_t *out, + uint8_t bits) { + if (NULL == out) { + return EUNDEFINEDBUFFER; + } + + if (bits >= (sizeof (in) * 8)) { + return EINCOMPATTYPE; + } + + *out = (in << bits) | (in >> (sizeof (in) * 8 - bits)); + + return PASS; +} + +static inline status_code bitwise_right_cyclic_shift(uint64_t in, + uint64_t *out, + uint8_t bits) { + if (NULL == out) { + return EUNDEFINEDBUFFER; + } + + if (bits >= (sizeof (in) * 8)) { + return EINCOMPATTYPE; + } + + *out = (in >> bits) | (in << (sizeof (in) * 8 - bits)); + + return PASS; +} + +#ifdef __cplusplus +}; +#endif + +#endif \ No newline at end of file diff --git a/sdk/core/src/include/electronetsoft/util/number/crypto.h b/sdk/core/src/include/electronetsoft/util/number/crypto.h new file mode 100644 index 0000000..c7aef5e --- /dev/null +++ b/sdk/core/src/include/electronetsoft/util/number/crypto.h @@ -0,0 +1,153 @@ +#ifndef __NUM_CRYPTO_H_ +#define __NUM_CRYPTO_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { // disable C++ name mangling by declaring function prototypes + // a C externally linked space +#endif + +struct hash_component { + typed_pointer key; + uint64_t *hash; + uint64_t user_key; +}; + +static inline status_code crypto_spread_64(uint64_t in, uint64_t *out) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + in = in ^ ((in ^ (in >> 32)) >> 32); + *out = in; + + return PASS; +} + +static inline status_code crypto_hash_str(hash_component hasher) { + if (NULL == hasher.key.address.str || NULL == hasher.hash) { + return EUNDEFINEDBUFFER; + } + + if (TYPE_STR != hasher.key.type) { + return EINCOMPATTYPE; + } + + // Use a large prime constant to initialize (FNV-1a style) + uint64_t h = 0xcbf29ce484222325ULL; + status_code __code; + + // Process every character + // Algorithm for polynomial hashing using Horner's rule + for (const char *address = hasher.key.address.str; *address != '\0'; address++) { + // use reverse Horner's Rule to compute the hash + // 1. XOR the character into the hash + h ^= (*address); + // 2. Multiply by 2^5 (aka 32) which is the same as left-shifting by + // 5 bits using Cyclic Shift Hashcode + __code = bitwise_left_cyclic_shift(h, &h, 5); + if (PASS != __code) { + return __code; + } + // 4. Combine MSB Component with LSB Component + h = (h >> 32) ^ h; + } + + // Apply your spread_64 as a finalizer to ensure high entropy + return crypto_spread_64(h ^ hasher.user_key, hasher.hash); +} + +static inline status_code crypto_hash_long(hash_component hasher) { + if (NULL == hasher.key.address.id || NULL == hasher.hash) { + return EUNDEFINEDBUFFER; + } + + if (TYPE_ID != hasher.key.type) { + return EINCOMPATTYPE; + } + + status_code __code; + uint64_t in = *(hasher.key.address.id); + + for (int i = 0; i < 4; i += 2) { + __code = bitwise_exchange_bytes(in, hasher.hash, i, i + 1); + if (PASS != __code) { + + return __code; + } + + __code = bitwise_exchange_bytes(in, hasher.hash, + 7 - i, 7 - (i + 1)); + if (PASS != __code) { + return __code; + } + } + + *hasher.hash ^= in; + + return crypto_spread_64(*hasher.hash ^ hasher.user_key, hasher.hash); +} + +static inline status_code crypto_hash_key(hash_component hasher) { + if (NULL == hasher.key.address.str || + NULL == hasher.key.address.id || + NULL == hasher.hash) { + return EUNDEFINEDBUFFER; + } + + if (TYPE_ID != hasher.key.type && + TYPE_STR != hasher.key.type) { + return EINCOMPATTYPE; + } + + // TYPE LONG ID + if (TYPE_ID == hasher.key.type) { + return crypto_hash_long(hasher); + } + + // TYPE_STR + return crypto_hash_str(hasher); +} + +static inline uint64_t crypto_hash_compress(uint64_t hash, + uint64_t limit) { + // the equivalent of modulus operation + // finds the remainder of an integer division operation + return hash - (((uint64_t) (hash/limit)) * limit); +} + +/** + * @brief Hashes a key in a string or long identifier format and + * then compresses it using modular arithmetics. + * @details Typical hashing algorithms; include Polynomial hashing + * for string keys using Horner's Rule, and bytes exchange and random + * spreading for unsigned long identifiers. + * + * @param hasher the hasher component structure with generic pointer. + * @param limit the limit of the compression algorithm. + */ +static inline status_code crypto_hashkey_compress64(hash_component hasher, + uint64_t limit) { + status_code __code = crypto_hash_key(hasher); + if (PASS != __code) { + return __code; + } + *(hasher.hash) = crypto_hash_compress(*(hasher.hash), limit); + + return PASS; +} + +#ifdef __cplusplus +}; +#endif + +#endif \ No newline at end of file diff --git a/sdk/core/src/include/electronetsoft/util/number/decimal.h b/sdk/core/src/include/electronetsoft/util/number/decimal.h new file mode 100644 index 0000000..d3e4196 --- /dev/null +++ b/sdk/core/src/include/electronetsoft/util/number/decimal.h @@ -0,0 +1,81 @@ +#ifndef __NUM_DECIMAL_H_ +#define __NUM_DECIMAL_H_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { // disable C++ name mangling by declaring function prototypes + // a C externally linked space +#endif + +/** + * @brief Subtracts the last (n) digits from the input (in) of base 10 + * and stores the result into the output (out) buffer. + * + * @param in an input of decimal integer format up-to 64-bit number. + * @param out an output buffer to store the result. + * @param n the number of digits to subtract from the input counted + * from the least significant digit + * (i.e., the last digit from the right). + * @return EUNDEFINEDBUFFER if the (out) buffer is not pre-allocated. + * EINCOMPATTYPE if the input is less than the divisor. + * PASS if the operation has passed successfully. + */ +static inline status_code dec_subtract_last_digits_b10(uint64_t in, + uint64_t *out, + uint8_t n) { + if (NULL == out) { + return EUNDEFINEDBUFFER; + } + + if (in < pow(10, n)) { + return EINCOMPATTYPE; + } + + *out = in / ((uint64_t) pow(10, n)); + + return PASS; +} + +/** + * @brief Extracts the last (n) digits from the input (n) of base 10 + * (i.e., decimal) into the output buffer. + * + * @param in an input of decimal integer format up-to 64-bit number. + * @param out an output buffer to store the result. + * @param n the number of digits to extract from the input counted + * from the least significant digit. + * @return EUNDEFINEDBUFFER if the (out) buffer is not pre-allocated. + * EINCOMPATTYPE if the input is less than the divisor. + * PASS if the operation has passed successfully. + */ +static inline status_code dec_extract_last_digits_b10(uint64_t in, + uint64_t *out, + uint8_t n) { + if (NULL == out) { + return EUNDEFINEDBUFFER; + } + + if (in < pow(10, n)) { + return EINCOMPATTYPE; + } + + *out = in % ((uint64_t) pow(10, n)); + return PASS; +} + +static inline uint64_t dec_generate_next_odd(uint64_t n) { + return (n * 2) + 1; +} + +#ifdef __cplusplus +}; +#endif + +#endif \ No newline at end of file diff --git a/sdk/core/src/include/electronetsoft/util/utilities.h b/sdk/core/src/include/electronetsoft/util/utilities.h index a26f117..c62a852 100644 --- a/sdk/core/src/include/electronetsoft/util/utilities.h +++ b/sdk/core/src/include/electronetsoft/util/utilities.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -21,6 +22,8 @@ union pointer { list_element *m_list_element; linked_buffer *m_linked_buffer; list_function_table *m_list_function_table; + uint64_t *id; + char *str; }; typedef enum pointer_type { @@ -29,6 +32,8 @@ typedef enum pointer_type { TYPE_LINKED_BUFFER = TYPE_LIST_ELEMENT + 1, TYPE_LIST_FUNCTION_TABLE = TYPE_LINKED_BUFFER + 1, TYPE_UNKNOWN = TYPE_LIST_FUNCTION_TABLE + 1, + TYPE_ID = TYPE_UNKNOWN + 1, + TYPE_STR = TYPE_ID + 1 } pointer_type; struct typed_pointer { @@ -41,12 +46,6 @@ struct api_lifecycle { void (*on_operation_failed)(void *api, void *caller, status_code cause); }; -struct hash_component { - char *key; - uint64_t *hash; - uint64_t user_key; -}; - /** * Uses a pointer as an r-value for safe * comparison reasons. @@ -110,86 +109,6 @@ static inline typed_pointer get_typed_pointer(void *address, pointer_type type) return pointer; } -static inline status_code spread_64(uint64_t in, uint64_t *out) { - if (rvalue(out) == NULL) { - return EUNDEFINEDBUFFER; - } - - in = in ^ ((in ^ (in >> 32)) >> 32); - *out = in; - - return PASS; -} - -static inline status_code hash_key(hash_component hasher) { - if (rvalue((void *) hasher.key) == NULL || - rvalue(hasher.hash) == NULL) { - return EUNDEFINEDBUFFER; - } - - // Use a large prime constant to initialize (FNV-1a style) - uint64_t h = 0xcbf29ce484222325ULL; - - // Process every character - // Algorithm for polynomial hashing using Horner's rule - for (const char *address = hasher.key; *address != '\0'; address++) { - // use reverse Horner's Rule to compute the hash - // 1. XOR the character into the hash - h ^= (*address); - // 2. Multiply by 2^5 (aka 32) which is the same as left-shifting by - // 5 bits using Cyclic Shift Hashcode - h = (h << 5) | (h >> (64 - 5)); - // 4. Combine MSB Component with LSB Component - h = (h >> 32) ^ h; - } - - // Apply your spread_64 as a finalizer to ensure high entropy - return spread_64(h ^ hasher.user_key, hasher.hash); -} - -static inline uint64_t hash_compress(uint64_t hash, - uint64_t limit) { - // the equivalent of modulus operation - // finds the remainder of an integer division operation - return hash - (((uint64_t) (hash/limit)) * limit); -} - -static inline uint64_t generate_next_odd(uint64_t n) { - return (n * 2) + 1; -} - -static inline status_code hashkey_compress64(hash_component hasher, - uint64_t limit) { - if (rvalue((void *) hasher.key) == NULL || - rvalue(hasher.hash) == NULL) { - return EUNDEFINEDBUFFER; - } - - status_code __code = hash_key(hasher); - if (PASS != __code) { - return __code; - } - *(hasher.hash) = hash_compress(*(hasher.hash), limit); - - return PASS; -} - -//static inline status_code is_prime(uint64_t n) { -// return PASS; -//} -// -//static inline uint64_t generate_next_prime(uint64_t n) { -// uint64_t next_odd = n; -// -// while (1) { -// next_odd = generate_next_odd(next_odd); -// if (is_prime(next_odd)) { -// return next_odd; -// } -// } -// return n; -//} - #ifdef __cplusplus }; #endif diff --git a/sdk/core/src/libs/electrostatic-primer/electronetsoft/arithmos/map/hashmap.c b/sdk/core/src/libs/electrostatic-primer/electronetsoft/arithmos/map/hashmap.c index 72b2c2c..1932989 100644 --- a/sdk/core/src/libs/electrostatic-primer/electronetsoft/arithmos/map/hashmap.c +++ b/sdk/core/src/libs/electrostatic-primer/electronetsoft/arithmos/map/hashmap.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include typedef struct { @@ -37,7 +37,7 @@ static inline status_code init_adt_list(list **buffer, uint64_t limit) { return init_list_function_table(*buffer, elements, list_table, NULL); } -static inline status_code get_element_by_key(list *buffer, +static inline status_code get_element_by_str_key(list *buffer, const char *__key0, key_element *__out) { char *__key1 = NULL; @@ -65,6 +65,48 @@ static inline status_code get_element_by_key(list *buffer, return __code; } +static inline status_code get_element_by_long_key(list *buffer, uint64_t *key, + key_element *__out) { + uint64_t *__key1 = NULL; + status_code __code; + + for (uint64_t i = 0; i < buffer->limit; i += 1) { + if (NULL == buffer->elements[i] || + NULL == buffer->elements[i]->data) { + continue; + } + // HERE + __key1 = buffer->elements[i]->metadata; + if (*__key1 != *key) { + __code = ENOELEMENT; + continue; + } + __code = PASS; + + if (NULL != __out) { + __out->index = i; + __out->value = buffer->elements[i]; + } + break; + } + return __code; +} + +static inline status_code get_element_by_typed_key(list *buffer, typed_pointer key, + key_element *out) { + if (TYPE_STR == key.type) { + return get_element_by_str_key(buffer, + (const char *) key.address.str, out); + } else if (TYPE_ID == key.type) { + return get_element_by_long_key(buffer, + key.address.id, out); + } else { + return EINCOMPATTYPE; + } + + return PASS; +} + static inline status_code collision_init_separate_chain (list *buffer, list_element *header, @@ -94,6 +136,7 @@ static inline status_code collision_init_separate_chain __chain_element->data = __separate_chain; __chain_element->type = ELEMENT_LIST; __chain_element->size = sizeof (list); + __chain_element->metadata = buffer->elements[index]->metadata; __code = buffer->function_table->insert_overwrite(buffer, __chain_element, index); if (PASS != __code) { @@ -116,8 +159,8 @@ static inline status_code hashmap_on_collision(list *buffer, // test if the list has the element with the exact key // add to the secondary buffer only if it is not present // if the element is not present in the buffer; add it - if (ENOELEMENT == get_element_by_key(__internal_buffer, - (const char *) element->metadata, NULL)) { + if (ENOELEMENT == get_element_by_typed_key(__internal_buffer, + *((typed_pointer *) element->metadata), NULL)) { return __internal_buffer->function_table-> add(__internal_buffer, element); } @@ -160,7 +203,7 @@ static inline status_code hashmap_on_collision(list *buffer, return __code; } -static inline status_code hashmap_resize(map *hashmap, uint64_t limit) { +static inline status_code hashmap_rehash(map *hashmap, uint64_t limit) { if (NULL == hashmap || NULL == hashmap->adt || 0 == hashmap->adt->limit || 0 == limit) { return EUNDEFINEDBUFFER; @@ -170,51 +213,82 @@ static inline status_code hashmap_resize(map *hashmap, uint64_t limit) { return INVALID_OP; } - list_element **elements = calloc(limit, sizeof (void *)); - if (NULL == elements) { - return EBUFFEROVERFLOW; + list *buffer = hashmap->adt; + list *_buffer = NULL; + status_code __code = init_adt_list(&_buffer, limit); + if (PASS != __code) { + return __code; } - list *buffer = hashmap->adt; + _buffer->function_table->on_collision = &hashmap_on_collision; + uint64_t hashcode; hash_component hasher = { .hash = &hashcode, .user_key = ((uint64_t) INT16_MAX << 8) + 1 }; - status_code __code; for (uint64_t i = 0; i < buffer->limit; i++) { if (NULL == buffer->elements[i]) { continue; } - hasher.key = buffer->elements[i]->metadata; - __code = hashkey_compress64(hasher, limit); - if (PASS != __code) { + if (ELEMENT_LIST == buffer->elements[i]->type) { + list *__buffer = buffer->elements[i]->data; + if (NULL == __buffer->elements) { + continue; + } + for (uint64_t j = 0; j < __buffer->limit; j++) { + if (NULL == __buffer->elements[j]) { + continue; + } + hasher.key = *((typed_pointer *) __buffer->elements[j]->metadata); + __code = crypto_hashkey_compress64(hasher, limit); + if (PASS != __code) { + break; + } + __code = _buffer->function_table->insert(_buffer, __buffer->elements[j], *hasher.hash); + if (PASS != __code) { + break; + } + } continue; } + if (ELEMENT_MAP_ITEM == buffer->elements[i]->type) { + hasher.key = *((typed_pointer *) buffer->elements[i]->metadata); + __code = crypto_hashkey_compress64(hasher, limit); + if (PASS != __code) { + break; + } - // deep/physical copy of the data from the - // old memory to the newly allocated buffer - elements[*hasher.hash] = buffer->elements[i]; + // deep/physical copy of the data from the + // old memory to the newly allocated buffer + __code = _buffer->function_table->insert(_buffer, buffer->elements[i], *hasher.hash); + if (PASS != __code) { + break; + } + } } // post-processing automata -- re-invalidate the internal buffer - free(buffer->elements); - buffer->elements = elements; - buffer->limit = limit; + __code = hashmap_deinit(hashmap, NULL); + if (PASS != __code) { + return __code; + } + hashmap->adt = _buffer; if (NULL != hashmap->processors && - NULL != hashmap->processors->on_resize_dispatch) { - hashmap->processors->on_resize_dispatch(hashmap, buffer->elements); + NULL != hashmap->processors->on_rehash_dispatch) { + hashmap->processors->on_rehash_dispatch(hashmap, buffer->elements); } return PASS; } -static inline status_code hashmap_insert(map *hashmap, map_element *element) { +static inline status_code hashmap_insert(map *hashmap, + map_element *element) { // preprocessing automata -- Input Validation - if (NULL == hashmap || NULL == hashmap->adt || NULL == element || - NULL == element->key || 0 == hashmap->adt->limit) { + if (NULL == hashmap || NULL == hashmap->adt || NULL == element + || 0 == hashmap->adt->limit) { return EUNDEFINEDBUFFER; } @@ -225,11 +299,11 @@ static inline status_code hashmap_insert(map *hashmap, map_element *element) { // processing automata -- Hashing the key uint64_t hash_code = 0; hash_component hasher = { - .key = (char *) element->key, + .key = element->key, .user_key = ((uint64_t) INT16_MAX << 8) + 1, .hash = &hash_code }; - status_code __code = hashkey_compress64(hasher, hashmap->adt->limit); + status_code __code = crypto_hashkey_compress64(hasher, hashmap->adt->limit); if (PASS != __code) { return __code; } @@ -240,7 +314,7 @@ static inline status_code hashmap_insert(map *hashmap, map_element *element) { element->value->size = sizeof(map_element); element->value->type = ELEMENT_MAP_ITEM; - element->value->metadata = element->key; + element->value->metadata = &(element->key); __code = hashmap->adt->function_table->insert(hashmap->adt, element->value, hash_code); @@ -255,9 +329,9 @@ static inline status_code hashmap_insert(map *hashmap, map_element *element) { if (PASS != __code) { return __code; } - if (lambda_factor >= 1.0f) { + if (lambda_factor >= 0.75f) { // appy resize and rehashing algorithm - __code = hashmap_resize(hashmap, hashmap->adt->limit << 4); + __code = hashmap_rehash(hashmap, hashmap->adt->limit << 4); if (PASS != __code) { return __code; } @@ -278,10 +352,10 @@ static inline status_code hashmap_insert_all(map *hashmap, } static inline status_code hashmap_get(map *hashmap, - const char *key, + typed_pointer key, map_element *out) { // preprocessing automata -- Input Validation - if (NULL == hashmap || NULL == hashmap->adt || NULL == key || + if (NULL == hashmap || NULL == hashmap->adt || 0 == hashmap->adt->limit || NULL == out) { return EUNDEFINEDBUFFER; } @@ -289,11 +363,11 @@ static inline status_code hashmap_get(map *hashmap, // processing automata -- Hashing the key uint64_t hash_code = 0; hash_component hasher = { - .key = (char *) key, + .key = key, .user_key = ((uint64_t) INT16_MAX << 8) + 1, .hash = &hash_code }; - status_code __code = hashkey_compress64(hasher, hashmap->adt->limit); + status_code __code = crypto_hashkey_compress64(hasher, hashmap->adt->limit); if (PASS != __code) { return __code; } @@ -310,7 +384,7 @@ static inline status_code hashmap_get(map *hashmap, .value = NULL, .index = 0 }; - __code = get_element_by_key(buffer, key, &(__key_element)); + __code = get_element_by_typed_key(buffer, key, &(__key_element)); if (PASS != __code) { return __code; } @@ -318,16 +392,16 @@ static inline status_code hashmap_get(map *hashmap, return PASS; } - out->key = (char *) key; + out->key = key; out->value = element; return PASS; } -static inline status_code hashmap_contains(map *hashmap, const char *key) { +static inline status_code hashmap_contains(map *hashmap, typed_pointer key) { map_element out = { .value = NULL, - .key = (char *) key + .key = key }; status_code __code = hashmap_get(hashmap, key, &out); @@ -341,7 +415,7 @@ static inline status_code hashmap_contains(map *hashmap, const char *key) { static inline status_code __hashmap_remove(map *hashmap, hash_component hasher) { // preprocessing automata -- Input Validation if (NULL == hashmap || NULL == hashmap->adt || - NULL == hasher.hash || NULL == hasher.key || + NULL == hasher.hash || 0 == hashmap->adt->limit) { return EUNDEFINEDBUFFER; } @@ -362,8 +436,8 @@ static inline status_code __hashmap_remove(map *hashmap, hash_component hasher) .value = NULL, .index = 0 }; - __code = get_element_by_key(buffer, - (const char *) hasher.key, + __code = get_element_by_typed_key(buffer, + hasher.key, &__key_element); if (PASS != __code) { return __code; @@ -392,20 +466,20 @@ static inline status_code __hashmap_remove(map *hashmap, hash_component hasher) return PASS; } -static inline status_code hashmap_remove(map *hashmap, const char *key) { +static inline status_code hashmap_remove(map *hashmap, typed_pointer key) { // preprocessing automata -- Input Validation - if (NULL == hashmap || NULL == hashmap->adt || NULL == key || + if (NULL == hashmap || NULL == hashmap->adt || 0 == hashmap->adt->limit) { return EUNDEFINEDBUFFER; } // processing automata -- Hashing the key uint64_t hash_code = 0; hash_component hasher = { - .key = (char *) key, + .key = key, .user_key = ((uint64_t) INT16_MAX << 8) + 1, .hash = &hash_code }; - status_code __code = hashkey_compress64(hasher, hashmap->adt->limit); + status_code __code = crypto_hashkey_compress64(hasher, hashmap->adt->limit); if (PASS != __code) { return __code; } @@ -414,10 +488,10 @@ static inline status_code hashmap_remove(map *hashmap, const char *key) { } static inline status_code hashmap_remove_all(map *hashmap, - const char **keys) { + typed_pointer **keys) { // preprocessing automata -- Input Validation - if (NULL == hashmap || NULL == hashmap->adt || NULL == keys || - 0 == hashmap->adt->limit || NULL == keys[0]) { + if (NULL == hashmap || NULL == hashmap->adt || + 0 == hashmap->adt->limit || NULL == keys || NULL == keys[0]) { return EUNDEFINEDBUFFER; } @@ -430,8 +504,8 @@ static inline status_code hashmap_remove_all(map *hashmap, status_code __code; for (uint64_t i = 0; NULL != keys[i]; i++) { - __hasher.key = (char *) keys[i]; - __code = hashkey_compress64(__hasher, hashmap->adt->limit); + __hasher.key = *(keys[i]); + __code = crypto_hashkey_compress64(__hasher, hashmap->adt->limit); if (PASS != __code) { return __code; } @@ -452,7 +526,7 @@ static inline status_code hashmap_remove_all(map *hashmap, } status_code hashmap_contains_all(map *hashmap, - const char **keys) { + typed_pointer **keys) { // preprocessing automata -- Input Validation if (NULL == hashmap || NULL == hashmap->adt || NULL == keys || 0 == hashmap->adt->limit || NULL == keys[0]) { @@ -462,7 +536,7 @@ status_code hashmap_contains_all(map *hashmap, status_code __code; for (uint64_t i = 0; NULL != keys[i]; i++) { - __code = hashmap_contains(hashmap, (const char *) keys[i]); + __code = hashmap_contains(hashmap, *(keys[i])); if (PASS != __code) { return __code; } @@ -500,7 +574,7 @@ status_code hashmap_iterator(map *hashmap, continue; } element.value = __buffer->elements[j]; - element.key = __buffer->elements[j]->metadata; + element.key = *((typed_pointer *) __buffer->elements[j]->metadata); __code = callback(hashmap, &element); if (PASS != __code) { return __code; @@ -509,7 +583,7 @@ status_code hashmap_iterator(map *hashmap, continue; } element.value = buffer->elements[i]; - element.key = buffer->elements[i]->metadata; + element.key = *((typed_pointer *) buffer->elements[i]->metadata); __code = callback(hashmap, &element); if (PASS != __code) { return __code; @@ -552,7 +626,7 @@ status_code hashmap_init(map *hashmap, map_function_table *table, table->insert = &hashmap_insert; table->insert_all = &hashmap_insert_all; - table->resize = &hashmap_resize; + table->rehash = &hashmap_rehash; table->iterator = &hashmap_iterator; table->contains = &hashmap_contains; table->contains_all = &hashmap_contains_all; diff --git a/sdk/examples/src/hello_bit_manipulation.c b/sdk/examples/src/hello_bit_manipulation.c new file mode 100644 index 0000000..9d98d18 --- /dev/null +++ b/sdk/examples/src/hello_bit_manipulation.c @@ -0,0 +1,14 @@ +#include +#include + +int main() { + uint64_t value = 0b00000000000000000000000011111111; + fprintf(stdout, "PRINT %lu\n", value); + status_code __code = bitwise_push_byte(0x00, + (uint64_t *) &value, 0); + if (PASS != __code) { + fprintf(stderr, "ERROR %d\n", __code); + } + fprintf(stdout, "PRINT %lu\n", value); + return 0; +} \ No newline at end of file diff --git a/sdk/examples/src/hello_hashing.c b/sdk/examples/src/hello_hashing.c index 7731275..14db3f4 100644 --- a/sdk/examples/src/hello_hashing.c +++ b/sdk/examples/src/hello_hashing.c @@ -1,13 +1,25 @@ #include #include -#include +#include int main() { - const char *key = "test_message_11"; uint64_t hash = 0; - hash_key(key, &hash, (1024 << 8) + 1); + hash_component component = { + .key = (typed_pointer) { + .address.str = "message_test_11", + .type = TYPE_STR, + }, + .user_key = (1024 << 8) + 1, + .hash = &hash + }; + status_code __code = crypto_hash_key(component); + if (PASS != __code) { + fprintf(stderr, + "Failed to hash the key; exit with error = %d\n", __code); + return __code; + } fprintf(stdout, "%lu\n", hash); - fprintf(stdout, "%lu\n", hash_compress(hash, 201)); + fprintf(stdout, "%lu\n", crypto_hash_compress(hash, 201)); return 0; } \ No newline at end of file diff --git a/sdk/examples/src/hello_hashing_long.c b/sdk/examples/src/hello_hashing_long.c new file mode 100644 index 0000000..2d010f6 --- /dev/null +++ b/sdk/examples/src/hello_hashing_long.c @@ -0,0 +1,23 @@ +#include +#include +#include + +int main() { + uint64_t hash = 2131112; + status_code __code = crypto_hashkey_compress64( + (hash_component ) { + .key = (typed_pointer) { + .address.id = &hash, + .type = TYPE_ID + }, + .user_key = (UINT16_MAX << 8) | (UINT16_MAX >> 8), + .hash = &hash + }, 900); + if (PASS != __code) { + fprintf(stderr, "Error while hashing = %d\n", __code); + return __code; + } + + fprintf(stdout, "Hashed Key = %lul\n", hash); + return 0; +} \ No newline at end of file diff --git a/sdk/examples/src/hello_hashmaps.c b/sdk/examples/src/hello_hashmaps.c index 66e8de7..aeacf19 100644 --- a/sdk/examples/src/hello_hashmaps.c +++ b/sdk/examples/src/hello_hashmaps.c @@ -15,6 +15,22 @@ int main() { map_function_table table = (map_function_table) { }; + + typed_pointer __key_0 = (typed_pointer) { + .address.str = "test_hashes", + .type = TYPE_STR + }; + + typed_pointer __key_1 = (typed_pointer) { + .address.str = "hashes_test", + .type = TYPE_STR + }; + + typed_pointer __key_2 = (typed_pointer) { + .address.str = "test_hashes112", + .type = TYPE_STR + }; + status_code __code = init_map_function_table(&hash_map, &table, NULL); @@ -24,7 +40,7 @@ int main() { } __code = hash_map.function_table->insert(&hash_map, &((map_element) { - .key = "test_hashes", + .key = __key_0, .value = &((list_element) { .type = ELEMENT_MAP_ITEM, .data = "Data 00" @@ -39,10 +55,10 @@ int main() { } __code = hash_map.function_table->insert(&hash_map, &((map_element) { - .key = "test_hashes", + .key = __key_1, .value = &((list_element) { .type = ELEMENT_MAP_ITEM, - .data = "Data 00" + .data = "Data 01" }) })); if (PASS == __code) { @@ -54,7 +70,7 @@ int main() { } __code = hash_map.function_table->insert(&hash_map, &((map_element) { - .key = "test_hashes", + .key = __key_2, .value = &((list_element) { .type = ELEMENT_MAP_ITEM, .data = "Data 00" @@ -69,10 +85,10 @@ int main() { } __code = hash_map.function_table->insert(&hash_map, &((map_element) { - .key = "hashes_test", + .key = __key_0, .value = &((list_element) { .type = ELEMENT_MAP_ITEM, - .data = "Data 01" + .data = "Data 013132" }) })); if (PASS == __code) { @@ -85,7 +101,7 @@ int main() { map_element out = { }; - __code = hash_map.function_table->get(&hash_map, "hashes_test", &out); + __code = hash_map.function_table->get(&hash_map, __key_0, &out); if (PASS != __code) { fprintf(stderr, "%s %d\n", "Error while retrieving the Map item!", __code); @@ -94,7 +110,6 @@ int main() { (const char *) out.value->data); } - __code = hash_map.function_table->iterator(&hash_map, &iterator_callback); if (PASS != __code) { fprintf(stderr, "%s %d\n", @@ -103,14 +118,15 @@ int main() { fprintf(stdout, "Iterated successfully!\n"); } - __code = hash_map.function_table->remove(&hash_map, "hashes_test"); + __code = hash_map.function_table->remove(&hash_map, __key_0); if (PASS != __code) { fprintf(stderr, "%s %d\n", "Error while retrieving the Map item!", __code); } - __code = hash_map.function_table->contains_all(&hash_map, (const char *[]) { - "hashes_test", "test_hashes", + __code = hash_map.function_table->contains_all(&hash_map, + (typed_pointer *[]) { + &__key_1, &__key_2, NULL }); if (PASS != __code) { fprintf(stderr, "%s %d\n", @@ -119,7 +135,7 @@ int main() { fprintf(stdout, GREEN "Contains Passed!\n" RESET); } - __code = hash_map.function_table->resize(&hash_map, hash_map.adt->limit << 4); + __code = hash_map.function_table->rehash(&hash_map, hash_map.adt->limit << 4); if (PASS != __code) { fprintf(stderr, "%s %d\n", "Resizing has failed!", __code); @@ -128,7 +144,7 @@ int main() { hash_map.adt->limit); } - __code = hash_map.function_table->get(&hash_map, "hashes_test", &out); + __code = hash_map.function_table->get(&hash_map, __key_0, &out); if (PASS != __code) { fprintf(stderr, "%s %d\n", "Error while retrieving the Map item!", __code);