Coverage Report

Created: 2023-09-25 06:35

/src/xpdf-4.04/goo/GHash.cc
Line
Count
Source (jump to first uncovered line)
1
//========================================================================
2
//
3
// GHash.cc
4
//
5
// Copyright 2001-2003 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#ifdef USE_GCC_PRAGMAS
12
#pragma implementation
13
#endif
14
15
#include "gmem.h"
16
#include "gmempp.h"
17
#include "GString.h"
18
#include "GHash.h"
19
20
//------------------------------------------------------------------------
21
22
struct GHashBucket {
23
  GString *key;
24
  union {
25
    void *p;
26
    int i;
27
  } val;
28
  GHashBucket *next;
29
};
30
31
struct GHashIter {
32
  int h;
33
  GHashBucket *p;
34
};
35
36
//------------------------------------------------------------------------
37
38
380k
GHash::GHash(GBool deleteKeysA) {
39
380k
  int h;
40
41
380k
  deleteKeys = deleteKeysA;
42
380k
  size = 7;
43
380k
  tab = (GHashBucket **)gmallocn(size, sizeof(GHashBucket *));
44
3.04M
  for (h = 0; h < size; ++h) {
45
2.66M
    tab[h] = NULL;
46
2.66M
  }
47
380k
  len = 0;
48
380k
}
49
50
380k
GHash::~GHash() {
51
380k
  GHashBucket *p;
52
380k
  int h;
53
54
3.04M
  for (h = 0; h < size; ++h) {
55
2.69M
    while (tab[h]) {
56
33.8k
      p = tab[h];
57
33.8k
      tab[h] = p->next;
58
33.8k
      if (deleteKeys) {
59
2.37k
  delete p->key;
60
2.37k
      }
61
33.8k
      delete p;
62
33.8k
    }
63
2.66M
  }
64
380k
  gfree(tab);
65
380k
}
66
67
31.7k
void GHash::add(GString *key, void *val) {
68
31.7k
  GHashBucket *p;
69
31.7k
  int h;
70
71
  // expand the table if necessary
72
31.7k
  if (len >= size) {
73
44
    expand();
74
44
  }
75
76
  // add the new symbol
77
31.7k
  p = new GHashBucket;
78
31.7k
  p->key = key;
79
31.7k
  p->val.p = val;
80
31.7k
  h = hash(key);
81
31.7k
  p->next = tab[h];
82
31.7k
  tab[h] = p;
83
31.7k
  ++len;
84
31.7k
}
85
86
2.08k
void GHash::add(GString *key, int val) {
87
2.08k
  GHashBucket *p;
88
2.08k
  int h;
89
90
  // expand the table if necessary
91
2.08k
  if (len >= size) {
92
28
    expand();
93
28
  }
94
95
  // add the new symbol
96
2.08k
  p = new GHashBucket;
97
2.08k
  p->key = key;
98
2.08k
  p->val.i = val;
99
2.08k
  h = hash(key);
100
2.08k
  p->next = tab[h];
101
2.08k
  tab[h] = p;
102
2.08k
  ++len;
103
2.08k
}
104
105
0
void GHash::replace(GString *key, void *val) {
106
0
  GHashBucket *p;
107
0
  int h;
108
109
0
  if ((p = find(key, &h))) {
110
0
    p->val.p = val;
111
0
    if (deleteKeys) {
112
0
      delete key;
113
0
    }
114
0
  } else {
115
0
    add(key, val);
116
0
  }
117
0
}
118
119
4.73k
void GHash::replace(GString *key, int val) {
120
4.73k
  GHashBucket *p;
121
4.73k
  int h;
122
123
4.73k
  if ((p = find(key, &h))) {
124
2.65k
    p->val.i = val;
125
2.65k
    if (deleteKeys) {
126
0
      delete key;
127
0
    }
128
2.65k
  } else {
129
2.08k
    add(key, val);
130
2.08k
  }
131
4.73k
}
132
133
248
void *GHash::lookup(GString *key) {
134
248
  GHashBucket *p;
135
248
  int h;
136
137
248
  if (!(p = find(key, &h))) {
138
230
    return NULL;
139
230
  }
140
18
  return p->val.p;
141
248
}
142
143
4.73k
int GHash::lookupInt(GString *key) {
144
4.73k
  GHashBucket *p;
145
4.73k
  int h;
146
147
4.73k
  if (!(p = find(key, &h))) {
148
2.08k
    return 0;
149
2.08k
  }
150
2.65k
  return p->val.i;
151
4.73k
}
152
153
289k
void *GHash::lookup(const char *key) {
154
289k
  GHashBucket *p;
155
289k
  int h;
156
157
289k
  if (!(p = find(key, &h))) {
158
285k
    return NULL;
159
285k
  }
160
4.87k
  return p->val.p;
161
289k
}
162
163
0
int GHash::lookupInt(const char *key) {
164
0
  GHashBucket *p;
165
0
  int h;
166
167
0
  if (!(p = find(key, &h))) {
168
0
    return 0;
169
0
  }
170
0
  return p->val.i;
171
0
}
172
173
0
void *GHash::remove(GString *key) {
174
0
  GHashBucket *p;
175
0
  GHashBucket **q;
176
0
  void *val;
177
0
  int h;
178
179
0
  if (!(p = find(key, &h))) {
180
0
    return NULL;
181
0
  }
182
0
  q = &tab[h];
183
0
  while (*q != p) {
184
0
    q = &((*q)->next);
185
0
  }
186
0
  *q = p->next;
187
0
  if (deleteKeys) {
188
0
    delete p->key;
189
0
  }
190
0
  val = p->val.p;
191
0
  delete p;
192
0
  --len;
193
0
  return val;
194
0
}
195
196
0
int GHash::removeInt(GString *key) {
197
0
  GHashBucket *p;
198
0
  GHashBucket **q;
199
0
  int val;
200
0
  int h;
201
202
0
  if (!(p = find(key, &h))) {
203
0
    return 0;
204
0
  }
205
0
  q = &tab[h];
206
0
  while (*q != p) {
207
0
    q = &((*q)->next);
208
0
  }
209
0
  *q = p->next;
210
0
  if (deleteKeys) {
211
0
    delete p->key;
212
0
  }
213
0
  val = p->val.i;
214
0
  delete p;
215
0
  --len;
216
0
  return val;
217
0
}
218
219
0
void *GHash::remove(const char *key) {
220
0
  GHashBucket *p;
221
0
  GHashBucket **q;
222
0
  void *val;
223
0
  int h;
224
225
0
  if (!(p = find(key, &h))) {
226
0
    return NULL;
227
0
  }
228
0
  q = &tab[h];
229
0
  while (*q != p) {
230
0
    q = &((*q)->next);
231
0
  }
232
0
  *q = p->next;
233
0
  if (deleteKeys) {
234
0
    delete p->key;
235
0
  }
236
0
  val = p->val.p;
237
0
  delete p;
238
0
  --len;
239
0
  return val;
240
0
}
241
242
0
int GHash::removeInt(const char *key) {
243
0
  GHashBucket *p;
244
0
  GHashBucket **q;
245
0
  int val;
246
0
  int h;
247
248
0
  if (!(p = find(key, &h))) {
249
0
    return 0;
250
0
  }
251
0
  q = &tab[h];
252
0
  while (*q != p) {
253
0
    q = &((*q)->next);
254
0
  }
255
0
  *q = p->next;
256
0
  if (deleteKeys) {
257
0
    delete p->key;
258
0
  }
259
0
  val = p->val.i;
260
0
  delete p;
261
0
  --len;
262
0
  return val;
263
0
}
264
265
372k
void GHash::startIter(GHashIter **iter) {
266
372k
  *iter = new GHashIter;
267
372k
  (*iter)->h = -1;
268
372k
  (*iter)->p = NULL;
269
372k
}
270
271
404k
GBool GHash::getNext(GHashIter **iter, GString **key, void **val) {
272
404k
  if (!*iter) {
273
0
    return gFalse;
274
0
  }
275
404k
  if ((*iter)->p) {
276
31.7k
    (*iter)->p = (*iter)->p->next;
277
31.7k
  }
278
3.01M
  while (!(*iter)->p) {
279
2.98M
    if (++(*iter)->h == size) {
280
372k
      delete *iter;
281
372k
      *iter = NULL;
282
372k
      return gFalse;
283
372k
    }
284
2.61M
    (*iter)->p = tab[(*iter)->h];
285
2.61M
  }
286
31.7k
  *key = (*iter)->p->key;
287
31.7k
  *val = (*iter)->p->val.p;
288
31.7k
  return gTrue;
289
404k
}
290
291
0
GBool GHash::getNext(GHashIter **iter, GString **key, int *val) {
292
0
  if (!*iter) {
293
0
    return gFalse;
294
0
  }
295
0
  if ((*iter)->p) {
296
0
    (*iter)->p = (*iter)->p->next;
297
0
  }
298
0
  while (!(*iter)->p) {
299
0
    if (++(*iter)->h == size) {
300
0
      delete *iter;
301
0
      *iter = NULL;
302
0
      return gFalse;
303
0
    }
304
0
    (*iter)->p = tab[(*iter)->h];
305
0
  }
306
0
  *key = (*iter)->p->key;
307
0
  *val = (*iter)->p->val.i;
308
0
  return gTrue;
309
0
}
310
311
0
void GHash::killIter(GHashIter **iter) {
312
0
  delete *iter;
313
0
  *iter = NULL;
314
0
}
315
316
72
void GHash::expand() {
317
72
  GHashBucket **oldTab;
318
72
  GHashBucket *p;
319
72
  int oldSize, h, i;
320
321
72
  oldSize = size;
322
72
  oldTab = tab;
323
72
  size = 2*size + 1;
324
72
  tab = (GHashBucket **)gmallocn(size, sizeof(GHashBucket *));
325
1.37k
  for (h = 0; h < size; ++h) {
326
1.30k
    tab[h] = NULL;
327
1.30k
  }
328
688
  for (i = 0; i < oldSize; ++i) {
329
1.23k
    while (oldTab[i]) {
330
616
      p = oldTab[i];
331
616
      oldTab[i] = oldTab[i]->next;
332
616
      h = hash(p->key);
333
616
      p->next = tab[h];
334
616
      tab[h] = p;
335
616
    }
336
616
  }
337
72
  gfree(oldTab);
338
72
}
339
340
9.71k
GHashBucket *GHash::find(GString *key, int *h) {
341
9.71k
  GHashBucket *p;
342
343
9.71k
  *h = hash(key);
344
11.5k
  for (p = tab[*h]; p; p = p->next) {
345
7.12k
    if (!p->key->cmp(key)) {
346
5.32k
      return p;
347
5.32k
    }
348
7.12k
  }
349
4.39k
  return NULL;
350
9.71k
}
351
352
289k
GHashBucket *GHash::find(const char *key, int *h) {
353
289k
  GHashBucket *p;
354
355
289k
  *h = hash(key);
356
290k
  for (p = tab[*h]; p; p = p->next) {
357
5.73k
    if (!p->key->cmp(key)) {
358
4.87k
      return p;
359
4.87k
    }
360
5.73k
  }
361
285k
  return NULL;
362
289k
}
363
364
44.2k
int GHash::hash(GString *key) {
365
44.2k
  const char *p;
366
44.2k
  unsigned int h;
367
44.2k
  int i;
368
369
44.2k
  h = 0;
370
1.17M
  for (p = key->getCString(), i = 0; i < key->getLength(); ++p, ++i) {
371
1.13M
    h = 17 * h + (int)(*p & 0xff);
372
1.13M
  }
373
44.2k
  return (int)(h % size);
374
44.2k
}
375
376
289k
int GHash::hash(const char *key) {
377
289k
  const char *p;
378
289k
  unsigned int h;
379
380
289k
  h = 0;
381
2.40M
  for (p = key; *p; ++p) {
382
2.11M
    h = 17 * h + (int)(*p & 0xff);
383
2.11M
  }
384
289k
  return (int)(h % size);
385
289k
}