203 |
205 |
204 TEST(CxHashMap, RemoveViaIterator) { |
206 TEST(CxHashMap, RemoveViaIterator) { |
205 CxTestingAllocator allocator; |
207 CxTestingAllocator allocator; |
206 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 4); |
208 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 4); |
207 |
209 |
208 cxMapPut(map, cx_hash_key_str("key 1"), (void *) "val 1"); |
210 cxMapPut(map, "key 1", (void *) "val 1"); |
209 cxMapPut(map, cx_hash_key_str("key 2"), (void *) "val 2"); |
211 cxMapPut(map, "key 2", (void *) "val 2"); |
210 cxMapPut(map, cx_hash_key_str("key 3"), (void *) "val 3"); |
212 cxMapPut(map, "key 3", (void *) "val 3"); |
211 cxMapPut(map, cx_hash_key_str("key 4"), (void *) "val 4"); |
213 cxMapPut(map, "key 4", (void *) "val 4"); |
212 cxMapPut(map, cx_hash_key_str("key 5"), (void *) "val 5"); |
214 cxMapPut(map, "key 5", (void *) "val 5"); |
213 cxMapPut(map, cx_hash_key_str("key 6"), (void *) "val 6"); |
215 cxMapPut(map, "key 6", (void *) "val 6"); |
214 |
216 |
215 auto iter = cxMapMutIterator(map); |
217 auto iter = cxMapMutIterator(map); |
216 cx_foreach(CxMapEntry*, entry, iter) { |
218 cx_foreach(CxMapEntry*, entry, iter) { |
217 if (reinterpret_cast<char const*>(entry->key->data)[4] % 2 == 1) cxIteratorFlagRemoval(iter); |
219 if (reinterpret_cast<char const *>(entry->key->data)[4] % 2 == 1) cxIteratorFlagRemoval(iter); |
218 } |
220 } |
219 EXPECT_EQ(map->size, 3); |
221 EXPECT_EQ(map->size, 3); |
220 EXPECT_EQ(iter.index, map->size); |
222 EXPECT_EQ(iter.index, map->size); |
221 |
223 |
222 EXPECT_EQ(cxMapGet(map, cx_hash_key_str("key 1")), nullptr); |
224 EXPECT_EQ(cxMapGet(map, "key 1"), nullptr); |
223 EXPECT_NE(cxMapGet(map, cx_hash_key_str("key 2")), nullptr); |
225 EXPECT_NE(cxMapGet(map, "key 2"), nullptr); |
224 EXPECT_EQ(cxMapGet(map, cx_hash_key_str("key 3")), nullptr); |
226 EXPECT_EQ(cxMapGet(map, "key 3"), nullptr); |
225 EXPECT_NE(cxMapGet(map, cx_hash_key_str("key 4")), nullptr); |
227 EXPECT_NE(cxMapGet(map, "key 4"), nullptr); |
226 EXPECT_EQ(cxMapGet(map, cx_hash_key_str("key 5")), nullptr); |
228 EXPECT_EQ(cxMapGet(map, "key 5"), nullptr); |
227 EXPECT_NE(cxMapGet(map, cx_hash_key_str("key 6")), nullptr); |
229 EXPECT_NE(cxMapGet(map, "key 6"), nullptr); |
228 |
230 |
229 cxMapDestroy(map); |
231 cxMapDestroy(map); |
230 EXPECT_TRUE(allocator.verify()); |
232 EXPECT_TRUE(allocator.verify()); |
231 } |
233 } |
232 |
234 |
233 TEST(CxHashMap, RehashNotRequired) { |
235 TEST(CxHashMap, RehashNotRequired) { |
234 CxTestingAllocator allocator; |
236 CxTestingAllocator allocator; |
235 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 8); |
237 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 8); |
236 |
238 |
237 cxMapPut(map, cx_hash_key_str("key 1"), (void *) "val 1"); |
239 cxMapPut(map, "key 1", (void *) "val 1"); |
238 cxMapPut(map, cx_hash_key_str("key 2"), (void *) "val 2"); |
240 cxMapPut(map, "key 2", (void *) "val 2"); |
239 cxMapPut(map, cx_hash_key_str("key 3"), (void *) "val 3"); |
241 cxMapPut(map, "key 3", (void *) "val 3"); |
240 cxMapPut(map, cx_hash_key_str("key 4"), (void *) "val 4"); |
242 cxMapPut(map, "key 4", (void *) "val 4"); |
241 cxMapPut(map, cx_hash_key_str("key 5"), (void *) "val 5"); |
243 cxMapPut(map, "key 5", (void *) "val 5"); |
242 cxMapPut(map, cx_hash_key_str("key 6"), (void *) "val 6"); |
244 cxMapPut(map, "key 6", (void *) "val 6"); |
243 |
245 |
244 // 6/8 does not exceed 0.75, therefore the function should not rehash |
246 // 6/8 does not exceed 0.75, therefore the function should not rehash |
245 int result = cxMapRehash(map); |
247 int result = cxMapRehash(map); |
246 EXPECT_EQ(result, 0); |
248 EXPECT_EQ(result, 0); |
247 EXPECT_EQ(reinterpret_cast<struct cx_hash_map_s *>(map)->bucket_count, 8); |
249 EXPECT_EQ(reinterpret_cast<struct cx_hash_map_s *>(map)->bucket_count, 8); |
252 |
254 |
253 TEST(CxHashMap, Rehash) { |
255 TEST(CxHashMap, Rehash) { |
254 CxTestingAllocator allocator; |
256 CxTestingAllocator allocator; |
255 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 7); |
257 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 7); |
256 |
258 |
257 cxMapPut(map, cx_hash_key_str("key 1"), (void *) "val 1"); |
259 cxMapPut(map, "key 1", (void *) "val 1"); |
258 cxMapPut(map, cx_hash_key_str("key 2"), (void *) "val 2"); |
260 cxMapPut(map, "key 2", (void *) "val 2"); |
259 cxMapPut(map, cx_hash_key_str("key 3"), (void *) "val 3"); |
261 cxMapPut(map, "key 3", (void *) "val 3"); |
260 cxMapPut(map, cx_hash_key_str("foo 4"), (void *) "val 4"); |
262 cxMapPut(map, "foo 4", (void *) "val 4"); |
261 cxMapPut(map, cx_hash_key_str("key 5"), (void *) "val 5"); |
263 cxMapPut(map, "key 5", (void *) "val 5"); |
262 cxMapPut(map, cx_hash_key_str("key 6"), (void *) "val 6"); |
264 cxMapPut(map, "key 6", (void *) "val 6"); |
263 cxMapPut(map, cx_hash_key_str("bar 7"), (void *) "val 7"); |
265 cxMapPut(map, "bar 7", (void *) "val 7"); |
264 cxMapPut(map, cx_hash_key_str("key 8"), (void *) "val 8"); |
266 cxMapPut(map, "key 8", (void *) "val 8"); |
265 cxMapPut(map, cx_hash_key_str("key 9"), (void *) "val 9"); |
267 cxMapPut(map, "key 9", (void *) "val 9"); |
266 cxMapPut(map, cx_hash_key_str("key 10"), (void *) "val 10"); |
268 cxMapPut(map, "key 10", (void *) "val 10"); |
267 |
269 |
268 int result = cxMapRehash(map); |
270 int result = cxMapRehash(map); |
269 EXPECT_EQ(result, 0); |
271 EXPECT_EQ(result, 0); |
270 EXPECT_EQ(reinterpret_cast<struct cx_hash_map_s *>(map)->bucket_count, 25); |
272 EXPECT_EQ(reinterpret_cast<struct cx_hash_map_s *>(map)->bucket_count, 25); |
271 EXPECT_EQ(map->size, 10); |
273 EXPECT_EQ(map->size, 10); |
272 |
274 |
273 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("key 1")), "val 1"), 0); |
275 EXPECT_STREQ((char *) cxMapGet(map, "key 1"), "val 1"); |
274 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("key 2")), "val 2"), 0); |
276 EXPECT_STREQ((char *) cxMapGet(map, "key 2"), "val 2"); |
275 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("key 3")), "val 3"), 0); |
277 EXPECT_STREQ((char *) cxMapGet(map, "key 3"), "val 3"); |
276 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("foo 4")), "val 4"), 0); |
278 EXPECT_STREQ((char *) cxMapGet(map, "foo 4"), "val 4"); |
277 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("key 5")), "val 5"), 0); |
279 EXPECT_STREQ((char *) cxMapGet(map, "key 5"), "val 5"); |
278 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("key 6")), "val 6"), 0); |
280 EXPECT_STREQ((char *) cxMapGet(map, "key 6"), "val 6"); |
279 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("bar 7")), "val 7"), 0); |
281 EXPECT_STREQ((char *) cxMapGet(map, "bar 7"), "val 7"); |
280 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("key 8")), "val 8"), 0); |
282 EXPECT_STREQ((char *) cxMapGet(map, "key 8"), "val 8"); |
281 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("key 9")), "val 9"), 0); |
283 EXPECT_STREQ((char *) cxMapGet(map, "key 9"), "val 9"); |
282 EXPECT_EQ(strcmp((char *) cxMapGet(map, cx_hash_key_str("key 10")), "val 10"), 0); |
284 EXPECT_STREQ((char *) cxMapGet(map, "key 10"), "val 10"); |
283 |
285 |
284 cxMapDestroy(map); |
286 cxMapDestroy(map); |
285 EXPECT_TRUE(allocator.verify()); |
287 EXPECT_TRUE(allocator.verify()); |
286 } |
288 } |
287 |
289 |
288 TEST(CxHashMap, Clear) { |
290 TEST(CxHashMap, Clear) { |
289 CxTestingAllocator allocator; |
291 CxTestingAllocator allocator; |
290 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 0); |
292 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 0); |
291 |
293 |
292 cxMapPut(map, cx_hash_key_str("key 1"), (void *) "val 1"); |
294 cxMapPut(map, "key 1", (void *) "val 1"); |
293 cxMapPut(map, cx_hash_key_str("key 2"), (void *) "val 2"); |
295 cxMapPut(map, "key 2", (void *) "val 2"); |
294 cxMapPut(map, cx_hash_key_str("key 3"), (void *) "val 3"); |
296 cxMapPut(map, "key 3", (void *) "val 3"); |
295 |
297 |
296 EXPECT_EQ(map->size, 3); |
298 EXPECT_EQ(map->size, 3); |
297 |
299 |
298 cxMapClear(map); |
300 cxMapClear(map); |
299 |
301 |
300 EXPECT_EQ(map->size, 0); |
302 EXPECT_EQ(map->size, 0); |
301 EXPECT_EQ(cxMapGet(map, cx_hash_key_str("key 1")), nullptr); |
303 EXPECT_EQ(cxMapGet(map, "key 1"), nullptr); |
302 EXPECT_EQ(cxMapGet(map, cx_hash_key_str("key 2")), nullptr); |
304 EXPECT_EQ(cxMapGet(map, "key 2"), nullptr); |
303 EXPECT_EQ(cxMapGet(map, cx_hash_key_str("key 3")), nullptr); |
305 EXPECT_EQ(cxMapGet(map, "key 3"), nullptr); |
304 |
306 |
305 cxMapDestroy(map); |
307 cxMapDestroy(map); |
306 EXPECT_TRUE(allocator.verify()); |
308 EXPECT_TRUE(allocator.verify()); |
307 } |
309 } |
308 |
310 |
317 auto s3 = CX_STR("a"); |
319 auto s3 = CX_STR("a"); |
318 auto s4 = CX_STR("test"); |
320 auto s4 = CX_STR("test"); |
319 auto s5 = CX_STR("setup"); |
321 auto s5 = CX_STR("setup"); |
320 |
322 |
321 // put them into the map |
323 // put them into the map |
322 cxMapPut(map, cx_hash_key_str("s1"), &s1); |
324 cxMapPut(map, "s1", &s1); |
323 cxMapPut(map, cx_hash_key_str("s2"), &s2); |
325 cxMapPut(map, "s2", &s2); |
324 cxMapPut(map, cx_hash_key_str("s3"), &s3); |
326 cxMapPut(map, "s3", &s3); |
325 cxMapPut(map, cx_hash_key_str("s4"), &s4); |
327 cxMapPut(map, "s4", &s4); |
326 |
328 |
327 // overwrite a value |
329 // overwrite a value |
328 cxMapPut(map, cx_hash_key_str("s1"), &s5); |
330 cxMapPut(map, "s1", &s5); |
329 |
331 |
330 // look up a string |
332 // look up a string |
331 auto s3p = reinterpret_cast<cxstring *>(cxMapGet(map, cx_hash_key_str("s3"))); |
333 auto s3p = reinterpret_cast<cxstring *>(cxMapGet(map, "s3")); |
332 EXPECT_EQ(s3p->length, s3.length); |
334 EXPECT_EQ(s3p->length, s3.length); |
333 EXPECT_EQ(s3p->ptr, s3.ptr); |
335 EXPECT_EQ(s3p->ptr, s3.ptr); |
334 EXPECT_NE(s3p, &s3); |
336 EXPECT_NE(s3p, &s3); |
335 |
337 |
336 // remove a string |
338 // remove a string |
337 cxMapRemove(map, cx_hash_key_str("s2")); |
339 cxMapRemove(map, "s2"); |
338 |
340 |
339 // iterate |
341 // iterate |
340 auto ref = std::vector{s5.ptr, s3.ptr, s4.ptr}; |
342 auto ref = std::vector{s5.ptr, s3.ptr, s4.ptr}; |
341 auto iter = cxMapIteratorValues(map); |
343 auto iter = cxMapIteratorValues(map); |
342 cx_foreach(cxstring*, s, iter) { |
344 cx_foreach(cxstring*, s, iter) { |
445 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 0); |
447 auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 0); |
446 map->advanced_destructor = test_advanced_destructor; |
448 map->advanced_destructor = test_advanced_destructor; |
447 verify_any_destructor(map); |
449 verify_any_destructor(map); |
448 EXPECT_TRUE(allocator.verify()); |
450 EXPECT_TRUE(allocator.verify()); |
449 } |
451 } |
|
452 |
|
453 TEST(CxHashMap, Generics) { |
|
454 CxTestingAllocator allocator; |
|
455 auto map = test_map_generics_step_1(&allocator); |
|
456 |
|
457 EXPECT_EQ(map->size, 3); |
|
458 EXPECT_STREQ((char *) cxMapGet(map, "test"), "test"); |
|
459 EXPECT_STREQ((char *) cxMapGet(map, "foo"), "bar"); |
|
460 EXPECT_STREQ((char *) cxMapGet(map, "hallo"), "welt"); |
|
461 |
|
462 test_map_generics_step_2(map); |
|
463 |
|
464 EXPECT_EQ(map->size, 2); |
|
465 EXPECT_STREQ((char *) cxMapGet(map, "key"), "value"); |
|
466 EXPECT_STREQ((char *) cxMapGet(map, "foo"), "bar"); |
|
467 |
|
468 test_map_generics_step_3(map); |
|
469 |
|
470 EXPECT_EQ(map->size, 0); |
|
471 |
|
472 cxMapDestroy(map); |
|
473 EXPECT_TRUE(allocator.verify()); |
|
474 } |