quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ares_htable_vpvp.c (4645B)


      1 /* MIT License
      2  *
      3  * Copyright (c) 2024 Brad House
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a copy
      6  * of this software and associated documentation files (the "Software"), to deal
      7  * in the Software without restriction, including without limitation the rights
      8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9  * copies of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  * SPDX-License-Identifier: MIT
     25  */
     26 #include "ares_private.h"
     27 #include "ares_htable.h"
     28 #include "ares_htable_vpvp.h"
     29 
     30 struct ares_htable_vpvp {
     31   ares_htable_vpvp_key_free_t free_key;
     32   ares_htable_vpvp_val_free_t free_val;
     33   ares_htable_t              *hash;
     34 };
     35 
     36 typedef struct {
     37   void               *key;
     38   void               *val;
     39   ares_htable_vpvp_t *parent;
     40 } ares_htable_vpvp_bucket_t;
     41 
     42 void ares_htable_vpvp_destroy(ares_htable_vpvp_t *htable)
     43 {
     44   if (htable == NULL) {
     45     return; /* LCOV_EXCL_LINE: DefensiveCoding */
     46   }
     47 
     48   ares_htable_destroy(htable->hash);
     49   ares_free(htable);
     50 }
     51 
     52 static unsigned int hash_func(const void *key, unsigned int seed)
     53 {
     54   return ares_htable_hash_FNV1a((const unsigned char *)&key, sizeof(key), seed);
     55 }
     56 
     57 static const void *bucket_key(const void *bucket)
     58 {
     59   const ares_htable_vpvp_bucket_t *arg = bucket;
     60   return arg->key;
     61 }
     62 
     63 static void bucket_free(void *bucket)
     64 {
     65   ares_htable_vpvp_bucket_t *arg = bucket;
     66 
     67   if (arg->parent->free_key) {
     68     arg->parent->free_key(arg->key);
     69   }
     70 
     71   if (arg->parent->free_val) {
     72     arg->parent->free_val(arg->val);
     73   }
     74 
     75   ares_free(arg);
     76 }
     77 
     78 static ares_bool_t key_eq(const void *key1, const void *key2)
     79 {
     80   if (key1 == key2) {
     81     return ARES_TRUE;
     82   }
     83 
     84   return ARES_FALSE;
     85 }
     86 
     87 ares_htable_vpvp_t *
     88   ares_htable_vpvp_create(ares_htable_vpvp_key_free_t key_free,
     89                           ares_htable_vpvp_val_free_t val_free)
     90 {
     91   ares_htable_vpvp_t *htable = ares_malloc(sizeof(*htable));
     92   if (htable == NULL) {
     93     goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
     94   }
     95 
     96   htable->hash = ares_htable_create(hash_func, bucket_key, bucket_free, key_eq);
     97   if (htable->hash == NULL) {
     98     goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
     99   }
    100 
    101   htable->free_key = key_free;
    102   htable->free_val = val_free;
    103 
    104   return htable;
    105 
    106 /* LCOV_EXCL_START: OutOfMemory */
    107 fail:
    108   if (htable) {
    109     ares_htable_destroy(htable->hash);
    110     ares_free(htable);
    111   }
    112   return NULL;
    113   /* LCOV_EXCL_STOP */
    114 }
    115 
    116 ares_bool_t ares_htable_vpvp_insert(ares_htable_vpvp_t *htable, void *key,
    117                                     void *val)
    118 {
    119   ares_htable_vpvp_bucket_t *bucket = NULL;
    120 
    121   if (htable == NULL) {
    122     goto fail;
    123   }
    124 
    125   bucket = ares_malloc(sizeof(*bucket));
    126   if (bucket == NULL) {
    127     goto fail;
    128   }
    129 
    130   bucket->parent = htable;
    131   bucket->key    = key;
    132   bucket->val    = val;
    133 
    134   if (!ares_htable_insert(htable->hash, bucket)) {
    135     goto fail;
    136   }
    137 
    138   return ARES_TRUE;
    139 
    140 fail:
    141   if (bucket) {
    142     ares_free(bucket);
    143   }
    144   return ARES_FALSE;
    145 }
    146 
    147 ares_bool_t ares_htable_vpvp_get(const ares_htable_vpvp_t *htable,
    148                                  const void *key, void **val)
    149 {
    150   ares_htable_vpvp_bucket_t *bucket = NULL;
    151 
    152   if (val) {
    153     *val = NULL;
    154   }
    155 
    156   if (htable == NULL) {
    157     return ARES_FALSE;
    158   }
    159 
    160   bucket = ares_htable_get(htable->hash, key);
    161   if (bucket == NULL) {
    162     return ARES_FALSE;
    163   }
    164 
    165   if (val) {
    166     *val = bucket->val;
    167   }
    168   return ARES_TRUE;
    169 }
    170 
    171 void *ares_htable_vpvp_get_direct(const ares_htable_vpvp_t *htable,
    172                                   const void               *key)
    173 {
    174   void *val = NULL;
    175   ares_htable_vpvp_get(htable, key, &val);
    176   return val;
    177 }
    178 
    179 ares_bool_t ares_htable_vpvp_remove(ares_htable_vpvp_t *htable, const void *key)
    180 {
    181   if (htable == NULL) {
    182     return ARES_FALSE;
    183   }
    184 
    185   return ares_htable_remove(htable->hash, key);
    186 }
    187 
    188 size_t ares_htable_vpvp_num_keys(const ares_htable_vpvp_t *htable)
    189 {
    190   if (htable == NULL) {
    191     return 0;
    192   }
    193   return ares_htable_num_keys(htable->hash);
    194 }