Skip to content

Commit

Permalink
COMMON: Fix logic in erasing keys in sail_hash_map
Browse files Browse the repository at this point in the history
  • Loading branch information
HappySeaFox committed Oct 31, 2023
1 parent 9e186b8 commit 873a736
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 26 deletions.
4 changes: 2 additions & 2 deletions src/libsail-common/hash_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ void sail_erase_hash_map_key(struct sail_hash_map *hash_map, const char *key) {
/* Erase from the head. */
if (key_variant_node == *head_variant_node) {
*head_variant_node = next_key_variant_node;
} else if (next_key_variant_node == NULL) {
} else {
/* Erase from the middle/end. */
prev_key_variant_node->next = next_key_variant_node;
prev_key_variant_node->next->next = next_key_variant_node;
}

return;
Expand Down
108 changes: 84 additions & 24 deletions tests/sail-common/hash_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,44 +221,104 @@ static MunitResult test_overwrite(const MunitParameter params[], void *user_data
return MUNIT_OK;
}

static struct sail_hash_map *generate_specific_hash_map_for_erasing(int value) {

struct sail_hash_map *hash_map;
sail_alloc_hash_map(&hash_map);

/* Value 1. */
struct sail_variant *variant;
sail_alloc_variant(&variant);
sail_set_variant_int(variant, value);

sail_put_hash_map(hash_map, "z", variant);
sail_put_hash_map(hash_map, "i1", variant);
sail_put_hash_map(hash_map, "h2", variant);

sail_destroy_variant(variant);

return hash_map;
}

static MunitResult test_erase(const MunitParameter params[], void *user_data) {

(void)params;
(void)user_data;

/*
* The current hashing algorithm puts "z", "i1", and "h2" keys in the same bucket.
* Let's test this specific use-case.
*/

struct sail_hash_map *hash_map;
munit_assert(sail_alloc_hash_map(&hash_map) == SAIL_OK);
int reference_value;
const struct sail_variant *value_in_map;

/* Erase non-existing. */
reference_value = 444;
hash_map = generate_specific_hash_map_for_erasing(reference_value);

sail_erase_hash_map_key(hash_map, "oops");
munit_assert(sail_hash_map_has_key(hash_map, "z"));
munit_assert(sail_hash_map_has_key(hash_map, "i1"));
munit_assert(sail_hash_map_has_key(hash_map, "h2"));
munit_assert(sail_hash_map_size(hash_map) == 3);

value_in_map = sail_hash_map_value(hash_map, "z");
munit_assert_not_null(value_in_map);
munit_assert_int(sail_variant_to_int(value_in_map), ==, reference_value);
value_in_map = sail_hash_map_value(hash_map, "i1");
munit_assert_not_null(value_in_map);
munit_assert_int(sail_variant_to_int(value_in_map), ==, reference_value);
value_in_map = sail_hash_map_value(hash_map, "h2");
munit_assert_not_null(value_in_map);
munit_assert_int(sail_variant_to_int(value_in_map), ==, reference_value);

const double reference_value1 = 11.5;
const int reference_value2 = 101;
sail_destroy_hash_map(hash_map);

/* Value 1. */
struct sail_variant *value1;
munit_assert(sail_alloc_variant(&value1) == SAIL_OK);
sail_set_variant_double(value1, reference_value1);
/* Erase "z". */
reference_value = 555;
hash_map = generate_specific_hash_map_for_erasing(reference_value);

munit_assert(sail_put_hash_map(hash_map, "ktop", value1) == SAIL_OK);
sail_destroy_variant(value1);
sail_erase_hash_map_key(hash_map, "z");
munit_assert(!sail_hash_map_has_key(hash_map, "z"));
munit_assert(sail_hash_map_size(hash_map) == 2);

/* Value 2. */
struct sail_variant *value2;
munit_assert(sail_alloc_variant(&value2) == SAIL_OK);
sail_set_variant_int(value2, reference_value2);
value_in_map = sail_hash_map_value(hash_map, "i1");
munit_assert_int(sail_variant_to_int(value_in_map), ==, reference_value);
value_in_map = sail_hash_map_value(hash_map, "h2");
munit_assert_int(sail_variant_to_int(value_in_map), ==, reference_value);

munit_assert(sail_put_hash_map(hash_map, "range", value2) == SAIL_OK);
sail_destroy_variant(value2);
munit_assert(sail_hash_map_has_key(hash_map, "range"));
sail_destroy_hash_map(hash_map);

/* Erase. */
sail_erase_hash_map_key(hash_map, "ktop");
munit_assert(!sail_hash_map_has_key(hash_map, "ktop"));
munit_assert(sail_hash_map_size(hash_map) == 1);
/* Erase "i1". */
reference_value = 666;
hash_map = generate_specific_hash_map_for_erasing(reference_value);

sail_erase_hash_map_key(hash_map, "range");
munit_assert(!sail_hash_map_has_key(hash_map, "range"));
munit_assert(sail_hash_map_size(hash_map) == 0);
sail_erase_hash_map_key(hash_map, "i1");
munit_assert(!sail_hash_map_has_key(hash_map, "i1"));
munit_assert(sail_hash_map_size(hash_map) == 2);

value_in_map = sail_hash_map_value(hash_map, "z");
munit_assert_int(sail_variant_to_int(value_in_map), ==, reference_value);
value_in_map = sail_hash_map_value(hash_map, "h2");
munit_assert_int(sail_variant_to_int(value_in_map), ==, reference_value);

sail_destroy_hash_map(hash_map);

/* Erase "h2". */
reference_value = 777;
hash_map = generate_specific_hash_map_for_erasing(reference_value);

sail_erase_hash_map_key(hash_map, "h2");
munit_assert(!sail_hash_map_has_key(hash_map, "h2"));
munit_assert(sail_hash_map_size(hash_map) == 2);

value_in_map = sail_hash_map_value(hash_map, "z");
munit_assert_int(sail_variant_to_int(value_in_map), ==, reference_value);
value_in_map = sail_hash_map_value(hash_map, "i1");
munit_assert_int(sail_variant_to_int(value_in_map), ==, reference_value);

/* Cleanup. */
sail_destroy_hash_map(hash_map);

return MUNIT_OK;
Expand Down

0 comments on commit 873a736

Please sign in to comment.