static void test_hashmap_remove_and_replace(void) { _cleanup_hashmap_free_ Hashmap *m = NULL; int valid; void *key1 = UINT_TO_PTR(1); void *key2 = UINT_TO_PTR(2); void *key3 = UINT_TO_PTR(3); void *r; int i, j; log_info("%s", __func__); m = hashmap_new(&trivial_hash_ops); assert_se(m); valid = hashmap_remove_and_replace(m, key1, key2, NULL); assert_se(valid == -ENOENT); valid = hashmap_put(m, key1, key1); assert_se(valid == 1); valid = hashmap_remove_and_replace(NULL, key1, key2, key2); assert_se(valid == -ENOENT); valid = hashmap_remove_and_replace(m, key1, key2, key2); assert_se(valid == 0); r = hashmap_get(m, key2); assert_se(r == key2); assert_se(!hashmap_get(m, key1)); valid = hashmap_put(m, key3, key3); assert_se(valid == 1); valid = hashmap_remove_and_replace(m, key3, key2, key2); assert_se(valid == 0); r = hashmap_get(m, key2); assert_se(r == key2); assert_se(!hashmap_get(m, key3)); /* Repeat this test several times to increase the chance of hitting * the less likely case in hashmap_remove_and_replace where it * compensates for the backward shift. */ for (i = 0; i < 20; i++) { hashmap_clear(m); for (j = 1; j < 7; j++) hashmap_put(m, UINT_TO_PTR(10*i + j), UINT_TO_PTR(10*i + j)); valid = hashmap_remove_and_replace(m, UINT_TO_PTR(10*i + 1), UINT_TO_PTR(10*i + 2), UINT_TO_PTR(10*i + 2)); assert_se(valid == 0); assert_se(!hashmap_get(m, UINT_TO_PTR(10*i + 1))); for (j = 2; j < 7; j++) { r = hashmap_get(m, UINT_TO_PTR(10*i + j)); assert_se(r == UINT_TO_PTR(10*i + j)); } } }
static void device_unset_sysfs(Device *d) { Device *first; assert(d); if (!d->sysfs) return; /* Remove this unit from the chain of devices which share the * same sysfs path. */ first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, d->sysfs); LIST_REMOVE(Device, same_sysfs, first, d); if (first) hashmap_remove_and_replace(UNIT(d)->manager->devices_by_sysfs, d->sysfs, first->sysfs, first); else hashmap_remove(UNIT(d)->manager->devices_by_sysfs, d->sysfs); free(d->sysfs); d->sysfs = NULL; }