blob: 52e421b1bfe235b10d8d0346f862fdd7e5d3236d [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Andy McFadden734155e2009-07-16 18:11:22 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Test the hash table functions.
19 */
20#include "Dalvik.h"
21
22#include <stdlib.h>
23
Andy McFadden734155e2009-07-16 18:11:22 -070024#ifndef NDEBUG
25
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080026#define kNumTestEntries 14
27
28/*
29 * Test foreach.
30 */
31static int printFunc(void* data, void* arg)
32{
33 //printf(" '%s'\n", (const char*) data);
34 // (should verify strings)
35
36 int* count = (int*) arg;
37 (*count)++;
38 return 0;
39}
40static void dumpForeach(HashTable* pTab)
41{
42 int count = 0;
43
44 //printf("Print from foreach:\n");
45 dvmHashForeach(pTab, printFunc, &count);
46 if (count != kNumTestEntries) {
Steve Blockc1a4ab92012-01-06 19:16:58 +000047 ALOGE("TestHash foreach test failed");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080048 assert(false);
49 }
50}
51
52/*
53 * Test iterator.
54 */
55static void dumpIterator(HashTable* pTab)
56{
57 int count = 0;
58
59 //printf("Print from iterator:\n");
60 HashIter iter;
61 for (dvmHashIterBegin(pTab, &iter); !dvmHashIterDone(&iter);
62 dvmHashIterNext(&iter))
63 {
Brian Carlstromfbdcfb92010-05-28 15:42:12 -070064 //const char* str = (const char*) dvmHashIterData(&iter);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080065 //printf(" '%s'\n", str);
66 // (should verify strings)
67 count++;
68 }
69 if (count != kNumTestEntries) {
Steve Blockc1a4ab92012-01-06 19:16:58 +000070 ALOGE("TestHash iterator test failed");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080071 assert(false);
72 }
73}
74
75/*
76 * Some quick hash table tests.
77 */
Carl Shapiro1e1433e2011-04-20 16:51:38 -070078bool dvmTestHash()
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080079{
80 HashTable* pTab;
81 char tmpStr[64];
82 const char* str;
83 u4 hash;
84 int i;
85
Steve Block92c1f6f2011-10-20 11:55:54 +010086 ALOGV("TestHash BEGIN");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080087
88 pTab = dvmHashTableCreate(dvmHashSize(12), free);
89 if (pTab == NULL)
90 return false;
91
92 dvmHashTableLock(pTab);
93
94 /* add some entries */
95 for (i = 0; i < kNumTestEntries; i++) {
96 sprintf(tmpStr, "entry %d", i);
97 hash = dvmComputeUtf8Hash(tmpStr);
98 dvmHashTableLookup(pTab, hash, strdup(tmpStr),
99 (HashCompareFunc) strcmp, true);
100 }
101
102 dvmHashTableUnlock(pTab);
103
104 /* make sure we can find all entries */
105 for (i = 0; i < kNumTestEntries; i++) {
106 sprintf(tmpStr, "entry %d", i);
107 hash = dvmComputeUtf8Hash(tmpStr);
108 str = (const char*) dvmHashTableLookup(pTab, hash, tmpStr,
109 (HashCompareFunc) strcmp, false);
110 if (str == NULL) {
Steve Blockc1a4ab92012-01-06 19:16:58 +0000111 ALOGE("TestHash: failure: could not find '%s'", tmpStr);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800112 /* return false */
113 }
114 }
115
116 /* make sure it behaves correctly when entry not found and !doAdd */
117 sprintf(tmpStr, "entry %d", 17);
118 hash = dvmComputeUtf8Hash(tmpStr);
119 str = (const char*) dvmHashTableLookup(pTab, hash, tmpStr,
120 (HashCompareFunc) strcmp, false);
121 if (str == NULL) {
122 /* good */
123 } else {
Steve Blockc1a4ab92012-01-06 19:16:58 +0000124 ALOGE("TestHash found nonexistent string (improper add?)");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800125 }
126
127 dumpForeach(pTab);
128 dumpIterator(pTab);
129
130 /* make sure they all get freed */
131 dvmHashTableFree(pTab);
132
133
134 /*
135 * Round 2: verify probing & tombstones.
136 */
137 pTab = dvmHashTableCreate(dvmHashSize(2), free);
138 if (pTab == NULL)
139 return false;
140
141 hash = 0;
142
143 /* two entries, same hash, different values */
Carl Shapirod5c36b92011-04-15 18:38:06 -0700144 const char* str1;
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800145 str1 = (char*) dvmHashTableLookup(pTab, hash, strdup("one"),
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800146 (HashCompareFunc) strcmp, true);
147 assert(str1 != NULL);
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800148 str = (const char*) dvmHashTableLookup(pTab, hash, strdup("two"),
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800149 (HashCompareFunc) strcmp, true);
150
151 /* remove the first one */
Carl Shapirod5c36b92011-04-15 18:38:06 -0700152 if (!dvmHashTableRemove(pTab, hash, (void*)str1))
Steve Blockc1a4ab92012-01-06 19:16:58 +0000153 ALOGE("TestHash failed to delete item");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800154 else
Carl Shapirod5c36b92011-04-15 18:38:06 -0700155 free((void*)str1); // "Remove" doesn't call the free func
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800156
157 /* make sure iterator doesn't included deleted entries */
158 int count = 0;
159 HashIter iter;
160 for (dvmHashIterBegin(pTab, &iter); !dvmHashIterDone(&iter);
161 dvmHashIterNext(&iter))
162 {
163 count++;
164 }
165 if (count != 1) {
Steve Blockc1a4ab92012-01-06 19:16:58 +0000166 ALOGE("TestHash wrong number of entries (%d)", count);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800167 }
168
169 /* see if we can find them */
Carl Shapirod5c36b92011-04-15 18:38:06 -0700170 str = (const char*) dvmHashTableLookup(pTab, hash, (void*)"one",
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800171 (HashCompareFunc) strcmp,false);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800172 if (str != NULL)
Steve Blockc1a4ab92012-01-06 19:16:58 +0000173 ALOGE("TestHash deleted entry has returned!");
Carl Shapirod5c36b92011-04-15 18:38:06 -0700174 str = (const char*) dvmHashTableLookup(pTab, hash, (void*)"two",
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800175 (HashCompareFunc) strcmp,false);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800176 if (str == NULL)
Steve Blockc1a4ab92012-01-06 19:16:58 +0000177 ALOGE("TestHash entry vanished");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800178
179 /* force a table realloc to exercise tombstone removal */
180 for (i = 0; i < 20; i++) {
181 sprintf(tmpStr, "entry %d", i);
182 str = (const char*) dvmHashTableLookup(pTab, hash, strdup(tmpStr),
183 (HashCompareFunc) strcmp, true);
184 assert(str != NULL);
185 }
186
187 dvmHashTableFree(pTab);
Steve Block92c1f6f2011-10-20 11:55:54 +0100188 ALOGV("TestHash END");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800189
190 return true;
191}
192
Andy McFadden734155e2009-07-16 18:11:22 -0700193#endif /*NDEBUG*/