diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index db261adfec..cdee4c574f 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -145,7 +145,6 @@ _dedup_obj_full_equal (const NMDedupMultiObj *obj_a, static const NMDedupMultiObjClass dedup_obj_class = { .obj_clone = _dedup_obj_clone, .obj_destroy = _dedup_obj_destroy, - .obj_full_equality_allows_different_class = FALSE, .obj_full_hash = _dedup_obj_full_hash, .obj_full_equal = _dedup_obj_full_equal, }; diff --git a/shared/nm-utils/nm-dedup-multi.c b/shared/nm-utils/nm-dedup-multi.c index 9e26065b39..f94bdf853e 100644 --- a/shared/nm-utils/nm-dedup-multi.c +++ b/shared/nm-utils/nm-dedup-multi.c @@ -155,6 +155,17 @@ _entry_unpack (const NMDedupMultiEntry *entry, nm_assert (NM_IN_SET (*out_lookup_head, FALSE, TRUE)); ASSERT_idx_type (*out_idx_type); + + /* for lookup of the head, we allow to omit object, but only + * if the idx_type does not parition the objects. Otherwise, we + * require a obj to compare. */ + nm_assert ( !*out_lookup_head + || ( *out_obj + || !(*out_idx_type)->klass->idx_obj_partition_equal)); + + /* lookup of the object requires always an object. */ + nm_assert ( *out_lookup_head + || *out_obj); } static guint @@ -286,6 +297,7 @@ _add (NMDedupMultiIndex *self, break; }; + nm_assert (obj->klass == ((const NMDedupMultiObj *) entry->obj)->klass); if ( obj == entry->obj || obj->klass->obj_full_equal (obj, entry->obj)) { @@ -775,24 +787,9 @@ static gboolean _dict_idx_objs_equal (const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b) { - const NMDedupMultiObjClass *klass; - - klass = obj_a->klass; - - /* if the class differs, but at least one of them supports calls with - * differing klass, choose it. - * - * Implementing a klass that can compare equality for multiple - * types is hard to get right. E.g. hash(), equal() and get_ref() - * must all agree so that instances of different types look identical. */ - if ( klass != obj_b->klass - && !klass->obj_full_equality_allows_different_class) { - klass = obj_b->klass; - if (!klass->obj_full_equality_allows_different_class) - return FALSE; - } - - return klass->obj_full_equal (obj_a, obj_b); + return obj_a == obj_b + || ( obj_a->klass == obj_b->klass + && obj_a->klass->obj_full_equal (obj_a, obj_b)); } void diff --git a/shared/nm-utils/nm-dedup-multi.h b/shared/nm-utils/nm-dedup-multi.h index 77a2fd122d..e44fbe451b 100644 --- a/shared/nm-utils/nm-dedup-multi.h +++ b/shared/nm-utils/nm-dedup-multi.h @@ -69,8 +69,6 @@ struct _NMDedupMultiObjClass { void (*obj_destroy) (NMDedupMultiObj *obj); - gboolean obj_full_equality_allows_different_class; - /* the NMDedupMultiObj can be deduplicated. For that the obj_full_hash() * and obj_full_equal() compare *all* fields of the object, even minor ones. */ guint (*obj_full_hash) (const NMDedupMultiObj *obj); @@ -167,9 +165,10 @@ nm_dedup_multi_idx_type_id_equal (const NMDedupMultiIdxType *idx_type, /* const NMDedupMultiObj * */ gconstpointer obj_b) { nm_assert (idx_type); - return idx_type->klass->idx_obj_id_equal (idx_type, - obj_a, - obj_b); + return obj_a == obj_b + || idx_type->klass->idx_obj_id_equal (idx_type, + obj_a, + obj_b); } static inline gboolean @@ -181,9 +180,10 @@ nm_dedup_multi_idx_type_partition_equal (const NMDedupMultiIdxType *idx_type, if (idx_type->klass->idx_obj_partition_equal) { nm_assert (obj_a); nm_assert (obj_b); - return idx_type->klass->idx_obj_partition_equal (idx_type, - obj_a, - obj_b); + return obj_a == obj_b + || idx_type->klass->idx_obj_partition_equal (idx_type, + obj_a, + obj_b); } return TRUE; }