-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhashtab_shrink.c
executable file
·168 lines (158 loc) · 5.06 KB
/
hashtab_shrink.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* hashtab_shrink.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: akharrou <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/03/07 11:25:00 by akharrou #+# #+# */
/* Updated: 2019/03/09 12:16:16 by akharrou ### ########.fr */
/* */
/* ************************************************************************** */
/*
** NAME
** hashtab_grow -- shrink a hashtable (to HTAB_DIVISER times less the
** size).
**
** SYNOPSIS
** #include "stdlib_42.h"
** #include "hashtable.h"
**
** int
** hashtab_shrink(t_hashtable **table);
**
** PARAMETERS
**
** t_hashtable **table Pointer to a pointer to a hashtable.
**
** DESCRIPTION
** Allocates a new hashtable, the size of the current hashtable size
** divided by HTAB_DIVISER (+ a little more is added to it inorder to
** get to the closest prime number). Then all entries of the current
** hashtable are rehashed and stored into it the new hashtable. Finally,
** the current hashtable is destroyed/free'd and (*table) is made to
** the new hashtable.
**
** RETURN VALUES
** If successful returns 0; otherwise -1.
*/
#include "../Includes/stdlib_42.h"
#include "../Includes/hashtable.h"
/*
** NAME
** hashtab_rehash_entry -- brief.
**
** SYNOPSIS
** #include "stdlib_42.h"
** #include "hashtable.h"
**
** static int
** hashtab_rehash_entry(t_hashtable **dest_table, t_entry **entry);
**
** PARAMETERS
**
** t_hashtable **dest_table Pointer to a pointer to the
** destination hashtable for the
** rehashed entry.
**
** t_entry **entry Pointer to an entry that is to
** be rehashed.
**
** DESCRIPTION
** The entry is rehashed and the output is modulo'ed with the
** size of the (*dest_table) size and stored at that index in the
** hashtable that (*dest_table) points to.
**
** RETURN VALUES
** If successful returns 0; otherwise -1.
*/
static int hashtab_rehash_entry(t_hashtable **dest_table, t_entry **entry)
{
unsigned int index;
if (dest_table && *dest_table && entry && *entry)
{
index = HASHCODE((*entry)->key, (*dest_table)->num_buckets);
(*entry)->next = ((*dest_table)->buckets)[index];
((*dest_table)->buckets)[index] = (*entry);
(*dest_table)->entries += 1;
return (0);
}
return (-1);
}
/*
** NAME
** hashtab_rehash_table -- rehash all entries of hashtable.
**
** SYNOPSIS
** #include <libft.h>
**
** static int
** hashtab_rehash_table(t_hashtable **src_table,
** t_hashtable **dest_table);
**
** PARAMETERS
**
** t_hashtable **src_table Pointer to a pointer to the
** hashtable whose entries are
** to be rehashed.
**
** t_hashtable **dest_table Pointer to a pointer to the
** destination hashtable that
** will store the rehashed entries.
**
** DESCRIPTION
** Rehashes all entries of the 'src_table' hashtable into the
** 'dest_table' hashtable. The output of the hash function is
** modulo'ed with the size of the 'dest_table' hashtable.
**
** RETURN VALUES
** If successful returns 0; otherwise -1.
*/
static int hashtab_rehash_table(t_hashtable **src_table,
t_hashtable **dest_table)
{
t_entry *cur_entry;
t_entry *temp;
unsigned int i;
if (src_table && *src_table && dest_table && *dest_table)
{
i = 0;
while (i < (*src_table)->num_buckets)
{
if (((*src_table)->buckets)[i])
{
cur_entry = ((*src_table)->buckets)[i];
while (cur_entry)
{
temp = cur_entry->next;
if (hashtab_rehash_entry(dest_table, &cur_entry) == -1)
return (-1);
cur_entry = temp;
}
((*src_table)->buckets)[i] = NULL;
}
i++;
}
}
return (((*dest_table)->entries == (*src_table)->entries) ? 0 : -1);
}
int hashtab_shrink(t_hashtable **table)
{
t_hashtable *new_table;
if (table && *table)
{
if ((*table)->num_buckets > 1)
{
new_table = hashtab_new((*table)->num_buckets / 2);
if (new_table == NULL)
return (-1);
if (hashtab_rehash_table(table, &new_table) == -1)
return (-1);
hashtab_destroy(table);
(*table) = new_table;
return (0);
}
return (0);
}
return (-1);
}