Coverage Report

Created: 2025-10-10 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libplist/src/hashtable.c
Line
Count
Source
1
/*
2
 * hashtable.c
3
 * really simple hash table implementation
4
 *
5
 * Copyright (c) 2011-2016 Nikias Bassen, All Rights Reserved.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20
 */
21
#include "hashtable.h"
22
23
hashtable_t* hash_table_new(hash_func_t hash_func, compare_func_t compare_func, free_func_t free_func)
24
0
{
25
0
  hashtable_t* ht = (hashtable_t*)malloc(sizeof(hashtable_t));
26
0
  int i;
27
0
  for (i = 0; i < 4096; i++) {
28
0
    ht->entries[i] = NULL;
29
0
  }
30
0
  ht->count = 0;
31
0
  ht->hash_func = hash_func;
32
0
  ht->compare_func = compare_func;
33
0
  ht->free_func = free_func;
34
0
  return ht;
35
0
}
36
37
void hash_table_destroy(hashtable_t *ht)
38
1.68k
{
39
1.68k
  if (!ht) return;
40
41
0
  int i = 0;
42
0
  for (i = 0; i < 4096; i++) {
43
0
    if (ht->entries[i]) {
44
0
      hashentry_t* e = ht->entries[i];
45
0
      while (e) {
46
0
        if (ht->free_func) {
47
0
          ht->free_func(e->value);
48
0
        }
49
0
        hashentry_t* old = e;
50
0
        e = (hashentry_t*)e->next;
51
0
        free(old);
52
0
      }
53
0
    }
54
0
  }
55
0
  free(ht);
56
0
}
57
58
void hash_table_insert(hashtable_t* ht, void *key, void *value)
59
0
{
60
0
  if (!ht || !key) return;
61
62
0
  unsigned int hash = ht->hash_func(key);
63
64
0
  int idx0 = hash & 0xFFF;
65
66
  // get the idx0 list
67
0
  hashentry_t* e = ht->entries[idx0];
68
0
  while (e) {
69
0
    if (ht->compare_func(e->key, key)) {
70
      // element already present. replace value.
71
0
      e->value = value;
72
0
      return;
73
0
    }
74
0
    e = (hashentry_t*)e->next;
75
0
  }
76
77
  // if we get here, the element is not yet in the list.
78
79
  // make a new entry.
80
0
  hashentry_t* entry = (hashentry_t*)malloc(sizeof(hashentry_t));
81
0
  entry->key = key;
82
0
  entry->value = value;
83
0
  if (!ht->entries[idx0]) {
84
    // first entry
85
0
    entry->next = NULL;
86
0
  } else {
87
    // add to list
88
0
    entry->next = ht->entries[idx0];
89
0
  }
90
0
  ht->entries[idx0] = entry;
91
0
  ht->count++;
92
0
}
93
94
void* hash_table_lookup(hashtable_t* ht, void *key)
95
0
{
96
0
  if (!ht || !key) return NULL;
97
0
  unsigned int hash = ht->hash_func(key);
98
99
0
  int idx0 = hash & 0xFFF;
100
101
0
  hashentry_t* e = ht->entries[idx0];
102
0
  while (e) {
103
0
    if (ht->compare_func(e->key, key)) {
104
0
      return e->value;
105
0
    }
106
0
    e = (hashentry_t*)e->next;
107
0
  }
108
0
  return NULL;
109
0
}
110
111
void hash_table_remove(hashtable_t* ht, void *key)
112
0
{
113
0
  if (!ht || !key) return;
114
115
0
  unsigned int hash = ht->hash_func(key);
116
117
0
  int idx0 = hash & 0xFFF;
118
119
  // get the idx0 list
120
0
  hashentry_t* e = ht->entries[idx0];
121
0
  hashentry_t* last = e;
122
0
  while (e) {
123
0
    if (ht->compare_func(e->key, key)) {
124
      // found element, remove it from the list
125
0
      hashentry_t* old = e;
126
0
      if (e == ht->entries[idx0]) {
127
0
        ht->entries[idx0] = (hashentry_t*)e->next;
128
0
      } else {
129
0
        last->next = e->next;
130
0
      }
131
0
      if (ht->free_func) {
132
0
        ht->free_func(old->value);
133
0
      }
134
0
      free(old);
135
0
      return;
136
0
    }
137
0
    last = e;
138
0
    e = (hashentry_t*)e->next;
139
0
  }
140
0
}