From ad087be36a2b8b966debd35977f03653c8a613d6 Mon Sep 17 00:00:00 2001 From: Aoran Zeng Date: Wed, 20 Aug 2025 16:15:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20`xy=5Fmap=5Fset()`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/xy.h | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/lib/xy.h b/lib/xy.h index 0e30de4..3abb803 100644 --- a/lib/xy.h +++ b/lib/xy.h @@ -1236,4 +1236,79 @@ xy_seq_each (XySeq_t *seq, void (*func)(void *)) } } + +#define _XY_Map_Buckets_Count 97 + +struct _XyHashBucket_t +{ + struct _XyHashBucket_t *next; + char *key; + void *value; +}; + +typedef struct XyMap_t +{ + struct _XyHashBucket_t **buckets; + + uint32_t length; +} +XyMap_t; + + +XyMap_t * +xy_map_new () +{ + XyMap_t *map = xy_malloc0 (sizeof (XyMap_t)); + map->buckets = xy_malloc0 (sizeof (struct _XyHashBucket_t *) * _XY_Map_Buckets_Count); + + map->length = 0; + + return map; +} + + +unsigned long +xy_hash (const char* str) +{ + unsigned long h = 5381; + int c; + while ((c = *str++)) + h = ((h << 5) + h) + c; /* h * 33 + c */ + return h; +} + + +void +xy_map_set (XyMap_t *map, const char *key, void *value) +{ + xy_cant_be_null (map); + xy_cant_be_null (key); + + unsigned long hash = xy_hash (key); + uint32_t index = hash % _XY_Map_Buckets_Count; + + // 若 key 已经存在 + _XyHashBucket_t *maybe = map->buckets[index]; + while (maybe) + { + if (xy_streql (maybe->key, key)) + { + maybe->value = value; + return; + } + maybe = maybe->next; + } + + // 若 key 不存在 + _XyHashBucket_t *bucket = xy_malloc0 (sizeof (struct _XyHashBucket_t)); + + bucket->key = xy_strdup (key); + bucket->value = value; + bucket->next = map->buckets[index]; + map->buckets[index] = bucket; + + map->length++; +} + + #endif