summaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/aws-c-common/source/linked_hash_table.c
diff options
context:
space:
mode:
authorrobot-contrib <[email protected]>2022-10-28 07:50:04 +0300
committerrobot-contrib <[email protected]>2022-10-28 07:50:04 +0300
commit9b6cded108571fe7983a855c40c7545bf4b7aad2 (patch)
treebf5fe3a440a47d1a49f05eae25af134c0c831408 /contrib/restricted/aws/aws-c-common/source/linked_hash_table.c
parente86badd466683de764e9ca22bc185566b43b82e6 (diff)
Update contrib/restricted/aws/aws-c-common to 0.8.3
Diffstat (limited to 'contrib/restricted/aws/aws-c-common/source/linked_hash_table.c')
-rw-r--r--contrib/restricted/aws/aws-c-common/source/linked_hash_table.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/contrib/restricted/aws/aws-c-common/source/linked_hash_table.c b/contrib/restricted/aws/aws-c-common/source/linked_hash_table.c
index 42c6a1b530c..02452bbcc70 100644
--- a/contrib/restricted/aws/aws-c-common/source/linked_hash_table.c
+++ b/contrib/restricted/aws/aws-c-common/source/linked_hash_table.c
@@ -30,6 +30,7 @@ int aws_linked_hash_table_init(
table->allocator = allocator;
table->user_on_value_destroy = destroy_value_fn;
+ table->user_on_key_destroy = destroy_key_fn;
aws_linked_list_init(&table->list);
return aws_hash_table_init(
@@ -95,7 +96,29 @@ int aws_linked_hash_table_put(struct aws_linked_hash_table *table, const void *k
}
if (element->value) {
+ AWS_ASSERT(!was_added);
+
+ /*
+ * There's an existing element with a key that is "equal" to the submitted key. We need to destroy that
+ * existing element's value if applicable.
+ */
s_element_destroy(element->value);
+
+ /*
+ * We're reusing an old element. The keys might be different references but "equal" via comparison. In that
+ * case we need to destroy the key (if appropriate) and point the element to the new key. This underhanded
+ * mutation of the element is safe with respect to the hash table because the keys are "equal."
+ */
+ if (table->user_on_key_destroy && element->key != key) {
+ table->user_on_key_destroy((void *)element->key);
+ }
+
+ /*
+ * Potentially a NOOP, but under certain circumstances (when the key and value are a part of the same structure
+ * and we're overwriting the existing entry, for example), this is necessary. Equality via function does not
+ * imply equal pointers.
+ */
+ element->key = key;
}
node->value = p_value;