This source file includes following definitions.
- ino_hash
- ino_compare
- ino_map_alloc
- ino_map_free
- ino_map_insert
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21 #include "ino-map.h"
22
23 #include "hash.h"
24 #include "verify.h"
25
26 #include <limits.h>
27 #include <stdlib.h>
28
29
30
31 struct ino_map_ent
32 {
33 ino_t ino;
34 size_t mapped_ino;
35 };
36
37
38 struct ino_map
39 {
40
41
42 struct hash_table *map;
43
44
45 size_t next_mapped_ino;
46
47
48
49 struct ino_map_ent *probe;
50 };
51
52
53 static size_t
54 ino_hash (void const *x, size_t table_size)
55 {
56 struct ino_map_ent const *p = x;
57 ino_t ino = p->ino;
58
59
60
61
62 size_t h = ino;
63 unsigned int i;
64 unsigned int n_words = sizeof ino / sizeof h + (sizeof ino % sizeof h != 0);
65 for (i = 1; i < n_words; i++)
66 h ^= ino >> CHAR_BIT * sizeof h * i;
67
68 return h % table_size;
69 }
70
71
72 static bool
73 ino_compare (void const *x, void const *y)
74 {
75 struct ino_map_ent const *a = x;
76 struct ino_map_ent const *b = y;
77 return a->ino == b->ino;
78 }
79
80
81
82 struct ino_map *
83 ino_map_alloc (size_t next_mapped_ino)
84 {
85 struct ino_map *im = malloc (sizeof *im);
86
87 if (im)
88 {
89 enum { INITIAL_INO_MAP_TABLE_SIZE = 1021 };
90 im->map = hash_initialize (INITIAL_INO_MAP_TABLE_SIZE, NULL,
91 ino_hash, ino_compare, free);
92 if (! im->map)
93 {
94 free (im);
95 return NULL;
96 }
97 im->next_mapped_ino = next_mapped_ino;
98 im->probe = NULL;
99 }
100
101 return im;
102 }
103
104
105 void
106 ino_map_free (struct ino_map *map)
107 {
108 hash_free (map->map);
109 free (map->probe);
110 free (map);
111 }
112
113
114
115
116
117
118 size_t
119 ino_map_insert (struct ino_map *im, ino_t ino)
120 {
121 struct ino_map_ent *ent;
122
123
124 struct ino_map_ent *probe = im->probe;
125 if (probe)
126 {
127
128 if (probe->ino == ino)
129 return probe->mapped_ino;
130 }
131 else
132 {
133 im->probe = probe = malloc (sizeof *probe);
134 if (! probe)
135 return INO_MAP_INSERT_FAILURE;
136 }
137
138 probe->ino = ino;
139 ent = hash_insert (im->map, probe);
140 if (! ent)
141 return INO_MAP_INSERT_FAILURE;
142
143 if (ent != probe)
144 {
145
146 probe->mapped_ino = ent->mapped_ino;
147 }
148 else
149 {
150
151
152
153
154 verify (INO_MAP_INSERT_FAILURE + 1 == 0);
155
156
157 im->probe = NULL;
158
159
160 probe->mapped_ino = im->next_mapped_ino++;
161 }
162
163 return probe->mapped_ino;
164 }