From 5c39f4970c32157c88553b6ac8844bad52380a1f Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Sun, 14 Aug 2022 21:05:33 +0300 Subject: [PATCH] Add containers hashing implementation --- src/array/base.c | 38 +++++++++++++++++++++++++++++--------- src/list/base.c | 16 ++++++++++++++++ src/string/base.c | 16 ++++++++++++++++ 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/array/base.c b/src/array/base.c index 1133689..49ee49f 100644 --- a/src/array/base.c +++ b/src/array/base.c @@ -4,17 +4,20 @@ #include "include.h" #include "../__internal/assert.h" -size_t array_size (const arr_t* x) { - return x->size; -} +/*#####################################################################################################################*/ -size_t array_nmemb(const arr_t* x) { - return x->size*vtype_size(x->type); -} +hash_t array_hash(const arr_t* s) { + hash_t hash = 0; -void* array_at(const arr_t* x, ssize_t i) { - if (i < 0 && (i += x->size) < 0) i = 0; - return x->mem + i*vtype_size(x->type); + if (s->size > 0) + hash = vtype_hash(s->mem, s->type); + + if (s->size > 1) + hash += vtype_hash(array_internal_at(s, s->size - 1), s->type); + + hash ^= s->size; + + return hash + VTYPE_ARRAY; } void array_init(arr_t* x, vtype t) { @@ -52,6 +55,23 @@ void array_free(arr_t* x) { memset(x, 0, sizeof(*x)); } +/*#####################################################################################################################*/ + +size_t array_size (const arr_t* x) { + return x->size; +} + +size_t array_nmemb(const arr_t* x) { + return x->size*vtype_size(x->type); +} + +void* array_at(const arr_t* x, ssize_t i) { + if (i < 0 && (i += x->size) < 0) i = 0; + return x->mem + i*vtype_size(x->type); +} + +/*#####################################################################################################################*/ + int array_compare(const arr_t* s0, const arr_t* s1) { void *e; diff --git a/src/list/base.c b/src/list/base.c index 16260f1..57071fb 100644 --- a/src/list/base.c +++ b/src/list/base.c @@ -5,6 +5,22 @@ /*#####################################################################################################################*/ +hash_t list_hash(const list_t* s) { + + hash_t hash = 0; + + if (!is_null(s->first)) { + hash = vnode_hash(&s->first->node, s->first->type); + + if (s->first != s->last) { + hash += vnode_hash(&s->first->node, s->first->type); + hash ^= list_size(s); + } else hash ^= 1; + } + + return hash + VTYPE_LIST; +} + void list_init(list_t* x) { memset(x, 0, sizeof(*x)); } diff --git a/src/string/base.c b/src/string/base.c index a131640..805140d 100644 --- a/src/string/base.c +++ b/src/string/base.c @@ -3,6 +3,22 @@ #include "include.h" +hash_t string_hash(const str_t* s) { + hash_t hash = 0; + size_t nmemb = string_nmemb(s); + + if (nmemb > 0) + hash = s->buffer[0]; + + if (nmemb > 1) + hash += s->buffer[nmemb-1]; + + hash ^= nmemb; + + return hash + VTYPE_STRING; +} + + size_t string_nmemb(const str_t* s) { return (!is_null(s->buffer)) ? strlen(s->buffer) : 0; }