-
Notifications
You must be signed in to change notification settings - Fork 0
/
hashtab_grow.c
executable file
·164 lines (154 loc) · 4.9 KB
/
hashtab_grow.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
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* hashtab_grow.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: akharrou <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/03/07 11:25:07 by akharrou #+# #+# */
/* Updated: 2019/03/09 12:16:07 by akharrou ### ########.fr */
/* */
/* ************************************************************************** */
/*
** NAME
** hashtab_grow -- grow a hashtable (to HTAB_MULTIPLIER times the size).
**
** SYNOPSIS
** #include "stdlib_42.h"
** #include "hashtable.h"
**
** int
** hashtab_grow(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
** multipled by HTAB_MULTIPLIER (+ a little more is added to it
** 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.
**
** 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_grow(t_hashtable **table)
{
t_hashtable *new_table;
if (table && *table)
{
new_table = hashtab_new((*table)->num_buckets * HTAB_MULTIPLIER);
if (new_table)
{
if (hashtab_rehash_table(table, &new_table) == 0)
{
hashtab_destroy(table);
(*table) = new_table;
return (0);
}
}
}
return (-1);
}