57
49
static const char *
58
50
key_function (NihList *entry)
60
assert (entry != NULL);
62
52
return ((HashEntry *)entry)->key;
73
printf ("Testing nih_hash_new()\n");
75
printf ("...with zero size\n");
76
hash = nih_hash_new (0, key_function);
78
/* Size should be smallest prime number */
79
if (hash->size != 17) {
80
printf ("BAD: size set incorrectly.\n");
84
/* Bins should be non-NULL */
85
if (hash->bins == NULL) {
86
printf ("BAD: bins not allocated.\n");
90
/* Bins should be a child of the hash table */
91
if (nih_alloc_parent (hash->bins) != hash) {
92
printf ("BAD: bins not child allocation of hash.\n");
96
/* All bins should be empty */
97
for (i = 0; i < hash->size; i++) {
98
if (! NIH_LIST_EMPTY (&hash->bins[i])) {
99
printf ("BAD: bin not initialised.\n");
104
/* Key function should be what we gave */
105
if (hash->key_function != key_function) {
106
printf ("BAD: key_function set incorrectly.\n");
113
printf ("...with medium size\n");
114
hash = nih_hash_new (650, key_function);
116
/* Size should be closest prime number */
117
if (hash->size != 331) {
118
printf ("BAD: size set incorrectly.\n");
122
/* Bins should be non-NULL */
123
if (hash->bins == NULL) {
124
printf ("BAD: bins not allocated.\n");
128
/* Bins should be a child of the hash table */
129
if (nih_alloc_parent (hash->bins) != hash) {
130
printf ("BAD: bins not child allocation of hash.\n");
134
/* All bins should be empty */
135
for (i = 0; i < hash->size; i++) {
136
if (! NIH_LIST_EMPTY (&hash->bins[i])) {
137
printf ("BAD: bin not initialised.\n");
142
/* Key function should be what we gave */
143
if (hash->key_function != key_function) {
144
printf ("BAD: key_function set incorrectly.\n");
151
printf ("...with large size\n");
152
hash = nih_hash_new (40000000, key_function);
154
/* Size should be largest prime number */
155
if (hash->size != 10250323) {
156
printf ("BAD: size set incorrectly.\n");
160
/* Bins should be non-NULL */
161
if (hash->bins == NULL) {
162
printf ("BAD: bins not allocated.\n");
166
/* Bins should be a child of the hash table */
167
if (nih_alloc_parent (hash->bins) != hash) {
168
printf ("BAD: bins not child allocation of hash.\n");
172
/* All bins should be empty */
173
for (i = 0; i < hash->size; i++) {
174
if (! NIH_LIST_EMPTY (&hash->bins[i])) {
175
printf ("BAD: bin not initialised.\n");
180
/* Key function should be what we gave */
181
if (hash->key_function != key_function) {
182
printf ("BAD: key_function set incorrectly.\n");
62
TEST_FUNCTION ("nih_hash_new");
64
/* Check that we can create a small hash table; a small prime number
65
* should be selected for the actual size, and that number of empty
66
* bins should be allocated as a child of the hash table.
68
TEST_FEATURE ("with zero size");
70
hash = nih_hash_new (NULL, 0, key_function);
72
if (test_alloc_failed) {
73
TEST_EQ_P (hash, NULL);
77
TEST_ALLOC_SIZE (hash, sizeof(NihHash));
78
TEST_EQ_P (hash->key_function, key_function);
80
TEST_EQ (hash->size, 17);
81
TEST_NE_P (hash->bins, NULL);
82
TEST_ALLOC_PARENT (hash->bins, hash);
84
for (i = 0; i < hash->size; i++)
85
TEST_LIST_EMPTY (&hash->bins[i]);
91
/* Check again with a medium size, which should pick a medium prime
94
TEST_FEATURE ("with medium size");
96
hash = nih_hash_new (NULL, 650, key_function);
98
if (test_alloc_failed) {
99
TEST_EQ_P (hash, NULL);
103
TEST_EQ (hash->size, 331);
104
TEST_NE_P (hash->bins, NULL);
105
TEST_ALLOC_PARENT (hash->bins, hash);
107
for (i = 0; i < hash->size; i++)
108
TEST_LIST_EMPTY (&hash->bins[i]);
114
/* Check with a much larger size, which should pick the largest prime
117
TEST_FEATURE ("with large size");
119
hash = nih_hash_new (NULL, 40000000, key_function);
121
if (test_alloc_failed) {
122
TEST_EQ_P (hash, NULL);
126
TEST_EQ (hash->size, 10250323);
127
TEST_NE_P (hash->bins, NULL);
128
TEST_ALLOC_PARENT (hash->bins, hash);
130
for (i = 0; i < hash->size; i++)
131
TEST_LIST_EMPTY (&hash->bins[i]);
196
141
NihList *entry1, *entry2, *entry3, *entry4, *ptr;
199
printf ("Testing nih_hash_add()\n");
200
hash = nih_hash_new (0, key_function);
143
TEST_FUNCTION ("nih_hash_add");
144
hash = nih_hash_new (NULL, 0, key_function);
201
145
entry1 = new_entry (hash, "entry 1");
202
146
entry2 = new_entry (hash, "entry 2");
203
147
entry3 = new_entry (hash, "entry 1");
204
148
entry4 = new_entry (hash, "entry 4");
206
printf ("...with empty hash\n");
150
/* Check that we can add an entry to an empty hash table; it should
151
* be returned and turn up in the appropriate bin.
153
TEST_FEATURE ("with empty hash");
207
154
ptr = nih_hash_add (hash, entry1);
209
/* The added entry should be returned */
211
printf ("BAD: return value wasn't what we expected.\n");
215
/* 15th hash bin head's next pointer should be the entry */
216
if (hash->bins[15].next != entry1) {
217
printf ("BAD: head next pointer set incorrectly.\n");
221
/* 15th hash bin head's previous pointer should be the entry */
222
if (hash->bins[15].prev != entry1) {
223
printf ("BAD: previous next pointer set incorrectly.\n");
227
/* Entry's next pointer should be the 15th hash bin */
228
if (entry1->next != &hash->bins[15]) {
229
printf ("BAD: entry next pointer set incorrectly.\n");
233
/* Entry's previous pointer should be the 15th hash bin */
234
if (entry1->prev != &hash->bins[15]) {
235
printf ("BAD: entry next pointer set incorrectly.\n");
240
printf ("...with non-empty hash\n");
156
TEST_EQ_P (ptr, entry1);
158
TEST_EQ_P (hash->bins[15].next, entry1);
159
TEST_EQ_P (entry1->next, &hash->bins[15]);
160
TEST_EQ_P (hash->bins[15].prev, entry1);
161
TEST_EQ_P (entry1->prev, &hash->bins[15]);
164
/* Check that we can add an entry to a populated hash table. */
165
TEST_FEATURE ("with non-empty hash");
241
166
nih_hash_add (hash, entry2);
243
/* 14th hash bin head's next pointer should be the entry */
244
if (hash->bins[14].next != entry2) {
245
printf ("BAD: head next pointer set incorrectly.\n");
249
/* 14th hash bin head's previous pointer should be the entry */
250
if (hash->bins[14].prev != entry2) {
251
printf ("BAD: head previous pointer set incorrectly.\n");
255
/* Entry's next pointer should be the 14th hash bin */
256
if (entry2->next != &hash->bins[14]) {
257
printf ("BAD: entry next pointer set incorrectly.\n");
261
/* Entry's previous pointer should be the 14th hash bin */
262
if (entry2->prev != &hash->bins[14]) {
263
printf ("BAD: entry next pointer set incorrectly.\n");
268
printf ("...with duplicate key\n");
168
TEST_EQ_P (hash->bins[14].next, entry2);
169
TEST_EQ_P (entry2->next, &hash->bins[14]);
170
TEST_EQ_P (hash->bins[14].prev, entry2);
171
TEST_EQ_P (entry2->prev, &hash->bins[14]);
174
/* Check that we can add an entry with a duplicate key, and it is
175
* added to the end of the same bin as the previous entry with that
178
TEST_FEATURE ("with duplicate key");
269
179
nih_hash_add (hash, entry3);
271
/* First entry's next pointer should be the new entry */
272
if (entry1->next != entry3) {
273
printf ("BAD: first entry next pointer set incorrectly.\n");
277
/* First entry's previous pointer should still be the head */
278
if (entry1->prev != &hash->bins[15]) {
279
printf ("BAD: first entry previous pointer changed.\n");
283
/* New entry's previous pointer should be the first entry */
284
if (entry3->prev != entry1) {
285
printf ("BAD: entry previous pointer set incorrectly.\n");
289
/* New entry's next pointer should be the head */
290
if (entry3->next != &hash->bins[15]) {
291
printf ("BAD: entry next pointer set incorrectly.\n");
295
/* Head's previous pointer should be the new entry */
296
if (hash->bins[15].prev != entry3) {
297
printf ("BAD: head previous pointer set incorrectly.\n");
301
/* Head's next pointer should still be the first entry */
302
if (hash->bins[15].next != entry1) {
303
printf ("BAD: head next pointer changed.\n");
308
printf ("...with entry already in a list\n");
309
ptr = nih_list_new ();
181
TEST_EQ_P (hash->bins[15].next, entry1);
182
TEST_EQ_P (entry1->next, entry3);
183
TEST_EQ_P (entry3->next, &hash->bins[15]);
184
TEST_EQ_P (hash->bins[15].prev, entry3);
185
TEST_EQ_P (entry3->prev, entry1);
186
TEST_EQ_P (entry1->prev, &hash->bins[15]);
189
/* Check that nih_hash_add can rip an entry out of an existing list
190
* and place it in the hash table.
192
TEST_FEATURE ("with entry already in a list");
193
ptr = nih_list_new (NULL);
310
194
nih_list_add (ptr, entry4);
311
195
nih_hash_add (hash, entry4);
313
/* List's previous pointer should point back to itself */
314
if (ptr->prev != ptr) {
315
printf ("BAD: list previous pointer set incorrectly.\n");
319
/* List's next pointer should point back to itself */
320
if (ptr->next != ptr) {
321
printf ("BAD: list next pointer set incorrectly.\n");
325
/* 3rd hash bin head's next pointer should be the entry */
326
if (hash->bins[3].next != entry4) {
327
printf ("BAD: head next pointer set incorrectly.\n");
331
/* 3rd hash bin head's previous pointer should be the entry */
332
if (hash->bins[3].prev != entry4) {
333
printf ("BAD: previous next pointer set incorrectly.\n");
337
/* Entry's next pointer should be the 3rd hash bin */
338
if (entry4->next != &hash->bins[3]) {
339
printf ("BAD: entry next pointer set incorrectly.\n");
343
/* Entry's previous pointer should be the 3rd hash bin */
344
if (entry4->prev != &hash->bins[3]) {
345
printf ("BAD: entry next pointer set incorrectly.\n");
197
TEST_EQ_P (ptr->next, ptr);
198
TEST_EQ_P (ptr->prev, ptr);
200
TEST_EQ_P (hash->bins[3].next, entry4);
201
TEST_EQ_P (entry4->next, &hash->bins[3]);
202
TEST_EQ_P (hash->bins[3].prev, entry4);
203
TEST_EQ_P (entry4->prev, &hash->bins[3]);
356
210
test_add_unique (void)
359
213
NihList *entry1, *entry2, *entry3, *entry4, *ptr;
362
printf ("Testing nih_hash_add_unique()\n");
363
hash = nih_hash_new (0, key_function);
215
TEST_FUNCTION ("nih_hash_add_unique");
216
hash = nih_hash_new (NULL, 0, key_function);
364
217
entry1 = new_entry (hash, "entry 1");
365
218
entry2 = new_entry (hash, "entry 2");
366
219
entry3 = new_entry (hash, "entry 1");
367
220
entry4 = new_entry (hash, "entry 4");
369
printf ("...with empty hash\n");
222
/* Check that we can add an entry to an empty hash table; it should
223
* be returned and turn up in the appropriate bin.
225
TEST_FEATURE ("with empty hash");
370
226
ptr = nih_hash_add_unique (hash, entry1);
372
/* The added entry should be returned */
374
printf ("BAD: return value wasn't what we expected.\n");
378
/* 15th hash bin head's next pointer should be the entry */
379
if (hash->bins[15].next != entry1) {
380
printf ("BAD: head next pointer set incorrectly.\n");
384
/* 15th hash bin head's previous pointer should be the entry */
385
if (hash->bins[15].prev != entry1) {
386
printf ("BAD: previous next pointer set incorrectly.\n");
390
/* Entry's next pointer should be the 15th hash bin */
391
if (entry1->next != &hash->bins[15]) {
392
printf ("BAD: entry next pointer set incorrectly.\n");
396
/* Entry's previous pointer should be the 15th hash bin */
397
if (entry1->prev != &hash->bins[15]) {
398
printf ("BAD: entry next pointer set incorrectly.\n");
403
printf ("...with non-empty hash\n");
228
TEST_EQ_P (ptr, entry1);
230
TEST_EQ_P (hash->bins[15].next, entry1);
231
TEST_EQ_P (entry1->next, &hash->bins[15]);
232
TEST_EQ_P (hash->bins[15].prev, entry1);
233
TEST_EQ_P (entry1->prev, &hash->bins[15]);
236
/* Check that we can add an entry to a populated hash table. */
237
TEST_FEATURE ("with non-empty hash");
404
238
nih_hash_add_unique (hash, entry2);
406
/* 14th hash bin head's next pointer should be the entry */
407
if (hash->bins[14].next != entry2) {
408
printf ("BAD: head next pointer set incorrectly.\n");
412
/* 14th hash bin head's previous pointer should be the entry */
413
if (hash->bins[14].prev != entry2) {
414
printf ("BAD: head previous pointer set incorrectly.\n");
418
/* Entry's next pointer should be the 14th hash bin */
419
if (entry2->next != &hash->bins[14]) {
420
printf ("BAD: entry next pointer set incorrectly.\n");
424
/* Entry's previous pointer should be the 14th hash bin */
425
if (entry2->prev != &hash->bins[14]) {
426
printf ("BAD: entry next pointer set incorrectly.\n");
431
printf ("...with duplicate key\n");
240
TEST_EQ_P (hash->bins[14].next, entry2);
241
TEST_EQ_P (entry2->next, &hash->bins[14]);
242
TEST_EQ_P (hash->bins[14].prev, entry2);
243
TEST_EQ_P (entry2->prev, &hash->bins[14]);
246
/* Check that we get NULL if we try and add an entry with a
247
* duplicate key, and that the hash table is not altered.
249
TEST_FEATURE ("with duplicate key");
432
250
ptr = nih_hash_add_unique (hash, entry3);
434
/* Should have returned NULL */
436
printf ("BAD: return value not correct.\n");
440
/* First entry's next pointer should still be the head */
441
if (entry1->next != &hash->bins[15]) {
442
printf ("BAD: first entry next pointer changed.\n");
446
/* First entry's previous pointer should still be the head */
447
if (entry1->prev != &hash->bins[15]) {
448
printf ("BAD: first entry previous pointer changed.\n");
452
/* Head's previous pointer should still be the first entry */
453
if (hash->bins[15].prev != entry1) {
454
printf ("BAD: head previous pointer changed.\n");
458
/* Head's next pointer should still be the first entry */
459
if (hash->bins[15].next != entry1) {
460
printf ("BAD: head next pointer changed.\n");
464
/* New entry's previous pointer should still be itself */
465
if (entry3->prev != entry3) {
466
printf ("BAD: entry previous pointer changed.\n");
470
/* New entry's next pointer should be the head */
471
if (entry3->next != entry3) {
472
printf ("BAD: entry next pointer changed.\n");
477
printf ("...with entry already in a list\n");
478
ptr = nih_list_new ();
252
TEST_EQ_P (ptr, NULL);
254
TEST_EQ_P (hash->bins[15].next, entry1);
255
TEST_EQ_P (entry1->next, &hash->bins[15]);
256
TEST_EQ_P (hash->bins[15].prev, entry1);
257
TEST_EQ_P (entry1->prev, &hash->bins[15]);
260
/* Check that nih_hash_add can rip an entry out of an existing list
261
* and place it in the hash table.
263
TEST_FEATURE ("with entry already in a list");
264
ptr = nih_list_new (NULL);
479
265
nih_list_add (ptr, entry4);
480
266
nih_hash_add_unique (hash, entry4);
482
/* List's previous pointer should point back to itself */
483
if (ptr->prev != ptr) {
484
printf ("BAD: list previous pointer set incorrectly.\n");
488
/* List's next pointer should point back to itself */
489
if (ptr->next != ptr) {
490
printf ("BAD: list next pointer set incorrectly.\n");
494
/* 3rd hash bin head's next pointer should be the entry */
495
if (hash->bins[3].next != entry4) {
496
printf ("BAD: head next pointer set incorrectly.\n");
500
/* 3rd hash bin head's previous pointer should be the entry */
501
if (hash->bins[3].prev != entry4) {
502
printf ("BAD: previous next pointer set incorrectly.\n");
506
/* Entry's next pointer should be the 3rd hash bin */
507
if (entry4->next != &hash->bins[3]) {
508
printf ("BAD: entry next pointer set incorrectly.\n");
512
/* Entry's previous pointer should be the 3rd hash bin */
513
if (entry4->prev != &hash->bins[3]) {
514
printf ("BAD: entry next pointer set incorrectly.\n");
268
TEST_EQ_P (ptr->next, ptr);
269
TEST_EQ_P (ptr->prev, ptr);
271
TEST_EQ_P (hash->bins[3].next, entry4);
272
TEST_EQ_P (entry4->next, &hash->bins[3]);
273
TEST_EQ_P (hash->bins[3].prev, entry4);
274
TEST_EQ_P (entry4->prev, &hash->bins[3]);
525
281
test_replace (void)
528
284
NihList *entry1, *entry2, *entry3, *entry4, *ptr;
531
printf ("Testing nih_hash_replace()\n");
532
hash = nih_hash_new (0, key_function);
286
TEST_FUNCTION ("nih_hash_replace");
287
hash = nih_hash_new (NULL, 0, key_function);
533
288
entry1 = new_entry (hash, "entry 1");
534
289
entry2 = new_entry (hash, "entry 2");
535
290
entry3 = new_entry (hash, "entry 1");
536
291
entry4 = new_entry (hash, "entry 4");
538
printf ("...with empty hash\n");
293
/* Check that we can add an entry to an empty hash table; NULL should
294
* be returned (nothing replaced) and the entry should turn up in the
297
TEST_FEATURE ("with empty hash");
539
298
ptr = nih_hash_replace (hash, entry1);
541
/* NULL should be returned */
543
printf ("BAD: return value wasn't what we expected.\n");
547
/* 15th hash bin head's next pointer should be the entry */
548
if (hash->bins[15].next != entry1) {
549
printf ("BAD: head next pointer set incorrectly.\n");
553
/* 15th hash bin head's previous pointer should be the entry */
554
if (hash->bins[15].prev != entry1) {
555
printf ("BAD: previous next pointer set incorrectly.\n");
559
/* Entry's next pointer should be the 15th hash bin */
560
if (entry1->next != &hash->bins[15]) {
561
printf ("BAD: entry next pointer set incorrectly.\n");
565
/* Entry's previous pointer should be the 15th hash bin */
566
if (entry1->prev != &hash->bins[15]) {
567
printf ("BAD: entry next pointer set incorrectly.\n");
572
printf ("...with non-empty hash\n");
300
TEST_EQ_P (ptr, NULL);
302
TEST_EQ_P (hash->bins[15].next, entry1);
303
TEST_EQ_P (entry1->next, &hash->bins[15]);
304
TEST_EQ_P (hash->bins[15].prev, entry1);
305
TEST_EQ_P (entry1->prev, &hash->bins[15]);
308
/* Check that we can add an entry to a populated hash table. */
309
TEST_FEATURE ("with non-empty hash");
573
310
nih_hash_replace (hash, entry2);
575
/* 14th hash bin head's next pointer should be the entry */
576
if (hash->bins[14].next != entry2) {
577
printf ("BAD: head next pointer set incorrectly.\n");
581
/* 14th hash bin head's previous pointer should be the entry */
582
if (hash->bins[14].prev != entry2) {
583
printf ("BAD: head previous pointer set incorrectly.\n");
587
/* Entry's next pointer should be the 14th hash bin */
588
if (entry2->next != &hash->bins[14]) {
589
printf ("BAD: entry next pointer set incorrectly.\n");
593
/* Entry's previous pointer should be the 14th hash bin */
594
if (entry2->prev != &hash->bins[14]) {
595
printf ("BAD: entry next pointer set incorrectly.\n");
600
printf ("...with duplicate key\n");
312
TEST_EQ_P (hash->bins[14].next, entry2);
313
TEST_EQ_P (entry2->next, &hash->bins[14]);
314
TEST_EQ_P (hash->bins[14].prev, entry2);
315
TEST_EQ_P (entry2->prev, &hash->bins[14]);
318
/* Check that we can add an entry with a duplicate key, replacing
319
* the existing one in the hash. The replaced entry should be
320
* returned, and removed from the bin.
322
TEST_FEATURE ("with duplicate key");
601
323
ptr = nih_hash_replace (hash, entry3);
603
/* The replaced entry should be returned */
605
printf ("BAD: return value not correct.\n");
609
/* Replaced entry's next pointer should point back to itself */
610
if (entry1->next != entry1) {
611
printf ("BAD: replaced entry next pointer set incorrectly.\n");
615
/* Replaced entry's previous pointer should point back to itself */
616
if (entry1->prev != entry1) {
617
printf ("BAD: replaced entry previous set incorrectly.\n");
621
/* Head's previous pointer should point to the new entry */
622
if (hash->bins[15].prev != entry3) {
623
printf ("BAD: head previous pointer set incorrectly.\n");
627
/* Head's next pointer should point to the new entry */
628
if (hash->bins[15].next != entry3) {
629
printf ("BAD: head next pointer set incorrectly.\n");
633
/* New entry's previous pointer should point to the head */
634
if (entry3->prev != &hash->bins[15]) {
635
printf ("BAD: entry previous pointer set incorrectly.\n");
639
/* New entry's next pointer should point to the head */
640
if (entry3->next != &hash->bins[15]) {
641
printf ("BAD: entry next pointer set incorrectly.\n");
646
printf ("...with entry already in a list\n");
647
ptr = nih_list_new ();
325
TEST_EQ_P (ptr, entry1);
327
TEST_EQ_P (entry1->next, entry1);
328
TEST_EQ_P (entry1->prev, entry1);
330
TEST_EQ_P (hash->bins[15].next, entry3);
331
TEST_EQ_P (entry3->next, &hash->bins[15]);
332
TEST_EQ_P (hash->bins[15].prev, entry3);
333
TEST_EQ_P (entry3->prev, &hash->bins[15]);
336
/* Check that nih_hash_add can rip an entry out of an existing list
337
* and place it in the hash table.
339
TEST_FEATURE ("with entry already in a list");
340
ptr = nih_list_new (NULL);
648
341
nih_list_add (ptr, entry4);
649
342
nih_hash_replace (hash, entry4);
651
/* List's previous pointer should point back to itself */
652
if (ptr->prev != ptr) {
653
printf ("BAD: list previous pointer set incorrectly.\n");
657
/* List's next pointer should point back to itself */
658
if (ptr->next != ptr) {
659
printf ("BAD: list next pointer set incorrectly.\n");
663
/* 3rd hash bin head's next pointer should be the entry */
664
if (hash->bins[3].next != entry4) {
665
printf ("BAD: head next pointer set incorrectly.\n");
669
/* 3rd hash bin head's previous pointer should be the entry */
670
if (hash->bins[3].prev != entry4) {
671
printf ("BAD: previous next pointer set incorrectly.\n");
675
/* Entry's next pointer should be the 3rd hash bin */
676
if (entry4->next != &hash->bins[3]) {
677
printf ("BAD: entry next pointer set incorrectly.\n");
681
/* Entry's previous pointer should be the 3rd hash bin */
682
if (entry4->prev != &hash->bins[3]) {
683
printf ("BAD: entry next pointer set incorrectly.\n");
344
TEST_EQ_P (ptr->next, ptr);
345
TEST_EQ_P (ptr->prev, ptr);
347
TEST_EQ_P (hash->bins[3].next, entry4);
348
TEST_EQ_P (entry4->next, &hash->bins[3]);
349
TEST_EQ_P (hash->bins[3].prev, entry4);
350
TEST_EQ_P (entry4->prev, &hash->bins[3]);
694
357
test_search (void)
697
360
NihList *entry1, *entry2, *entry3, *ptr;
700
printf ("Testing nih_hash_search()\n");
701
hash = nih_hash_new (0, key_function);
362
TEST_FUNCTION ("nih_hash_search");
363
hash = nih_hash_new (NULL, 0, key_function);
702
364
entry1 = nih_hash_add (hash, new_entry (hash, "entry 1"));
703
365
entry2 = nih_hash_add (hash, new_entry (hash, "entry 2"));
704
366
entry3 = nih_hash_add (hash, new_entry (hash, "entry 2"));
706
printf ("...with single match\n");
368
/* Check that we find the sole matching entry. */
707
369
ptr = nih_hash_search (hash, "entry 1", NULL);
709
/* First return value should be the entry */
711
printf ("BAD: return value was not correct.\n");
371
TEST_EQ_P (ptr, entry1);
373
/* Searching again should find nothing */
715
374
ptr = nih_hash_search (hash, "entry 1", ptr);
717
/* Second return value should be NULL */
719
printf ("BAD: return value was not correct.\n");
724
printf ("...with multiple matches\n");
376
TEST_EQ_P (ptr, NULL);
379
/* Check that where there's multiple matches, we find the first one. */
380
TEST_FEATURE ("with multiple matches");
725
381
ptr = nih_hash_search (hash, "entry 2", NULL);
727
/* Return value should be first added */
729
printf ("BAD: return value was not correct.\n");
733
ptr = nih_hash_search (hash, "entry 2", ptr);
735
/* Second return value should be second added */
737
printf ("BAD: return value was not correct.\n");
741
ptr = nih_hash_search (hash, "entry 2", ptr);
743
/* Third return value should be NULL */
745
printf ("BAD: return value was not correct.\n");
750
printf ("...with no matches\n");
383
TEST_EQ_P (ptr, entry2);
385
/* And that searching again finds the second one. */
386
ptr = nih_hash_search (hash, "entry 2", ptr);
388
TEST_EQ_P (ptr, entry3);
390
/* And again finds nothing. */
391
ptr = nih_hash_search (hash, "entry 2", ptr);
393
TEST_EQ_P (ptr, NULL);
396
/* Check that we get NULL if there are no matches. */
397
TEST_FEATURE ("with no matches");
751
398
ptr = nih_hash_search (hash, "entry 3", NULL);
753
/* Return value should be NULL */
755
printf ("BAD: return value was not correct.\n");
400
TEST_EQ_P (ptr, NULL);
765
406
test_lookup (void)
768
409
NihList *entry1, *entry2, *entry3, *ptr;
771
printf ("Testing nih_hash_lookup()\n");
772
hash = nih_hash_new (0, key_function);
411
TEST_FUNCTION ("nih_hash_lookup");
412
hash = nih_hash_new (NULL, 0, key_function);
773
413
entry1 = nih_hash_add (hash, new_entry (hash, "entry 1"));
774
414
entry2 = nih_hash_add (hash, new_entry (hash, "entry 2"));
775
415
entry3 = nih_hash_add (hash, new_entry (hash, "entry 2"));
777
printf ("...with single match\n");
417
/* Check that we find a single matching entry. */
418
TEST_FEATURE ("with single match");
778
419
ptr = nih_hash_lookup (hash, "entry 1");
780
/* Return value should be the entry */
782
printf ("BAD: return value was not correct.\n");
787
printf ("...with multiple matches\n");
421
TEST_EQ_P (ptr, entry1);
424
/* Check that we find the first matching entry. */
425
TEST_FEATURE ("with multiple matches");
788
426
ptr = nih_hash_lookup (hash, "entry 2");
790
/* Return value should be first added */
792
printf ("BAD: return value was not correct.\n");
797
printf ("...with no matches\n");
428
TEST_EQ_P (ptr, entry2);
431
/* Check that we get NULL when there are no matching entries. */
432
TEST_FEATURE ("with no matches");
798
433
ptr = nih_hash_lookup (hash, "entry 3");
800
/* Return value should be NULL */
802
printf ("BAD: return value was not correct.\n");
435
TEST_EQ_P (ptr, NULL);
445
NihList *entry[4], *entry0, *entry1, *entry2, *entry3;
448
/* Check that NIH_HASH_FOREACH iterates the hash correctly in order,
449
* visiting each entry in each bin. Note that we stage the entries
450
* in the hash in the order we expect them to come out in, but add
451
* them in a different order for sanity.
453
TEST_FUNCTION ("nih_HASH_FOREACH");
454
hash = nih_hash_new (NULL, 0, key_function);
455
entry0 = entry[2] = new_entry (hash, "entry 1");
456
entry1 = entry[1] = new_entry (hash, "entry 2");
457
entry2 = entry[3] = new_entry (hash, "entry 1");
458
entry3 = entry[0] = new_entry (hash, "entry 4");
460
nih_hash_add (hash, entry0);
461
nih_hash_add (hash, entry1);
462
nih_hash_add (hash, entry2);
463
nih_hash_add (hash, entry3);
466
NIH_HASH_FOREACH (hash, iter) {
468
TEST_FAILED ("wrong number of iterations, expected %d got %d",
471
if (iter != entry[i])
472
TEST_FAILED ("wrong list entry, expected %p got %p",
482
test_foreach_safe (void)
485
NihList *entry[4], *entry0, *entry1, *entry2, *entry3;
488
/* Check that NIH_HASH_FOREACH_SAFE iterates the hash correctly in
489
* order, visiting each entry in each bin; and that it's safe to
490
* remove the entries while doing so.
492
TEST_FUNCTION ("nih_HASH_FOREACH");
493
hash = nih_hash_new (NULL, 0, key_function);
494
entry0 = entry[2] = new_entry (hash, "entry 1");
495
entry1 = entry[1] = new_entry (hash, "entry 2");
496
entry2 = entry[3] = new_entry (hash, "entry 1");
497
entry3 = entry[0] = new_entry (hash, "entry 4");
499
nih_hash_add (hash, entry0);
500
nih_hash_add (hash, entry1);
501
nih_hash_add (hash, entry2);
502
nih_hash_add (hash, entry3);
505
NIH_HASH_FOREACH_SAFE (hash, iter) {
507
TEST_FAILED ("wrong number of iterations, expected %d got %d",
510
if (iter != entry[i])
511
TEST_FAILED ("wrong list entry, expected %p got %p",
514
nih_list_remove (entry[i]);
524
test_string_key (void)
530
/* Check that the string key function returns a pointer to the
531
* key in our test structure.
533
TEST_FUNCTION ("nih_hash_string_key");
534
entry = new_entry (NULL, "my entry");
536
key = nih_hash_string_key (entry);
538
TEST_EQ_P (key, ((HashEntry *)entry)->key);
539
TEST_EQ_STR (key, "my entry");
541
nih_list_free (entry);