diff options
Diffstat (limited to 'shared/nm-glib-aux/nm-dedup-multi.c')
| -rw-r--r-- | shared/nm-glib-aux/nm-dedup-multi.c | 1495 |
1 files changed, 742 insertions, 753 deletions
diff --git a/shared/nm-glib-aux/nm-dedup-multi.c b/shared/nm-glib-aux/nm-dedup-multi.c index 6e23228e..4a16f850 100644 --- a/shared/nm-glib-aux/nm-dedup-multi.c +++ b/shared/nm-glib-aux/nm-dedup-multi.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -13,383 +13,379 @@ /*****************************************************************************/ typedef struct { - /* the stack-allocated lookup entry. It has a compatible - * memory layout with NMDedupMultiEntry and NMDedupMultiHeadEntry. - * - * It is recognizable by having lst_entries_sentinel.next set to NULL. - * Contrary to the other entries, which have lst_entries.next - * always non-NULL. - * */ - CList lst_entries_sentinel; - const NMDedupMultiObj *obj; - const NMDedupMultiIdxType *idx_type; - bool lookup_head; + /* the stack-allocated lookup entry. It has a compatible + * memory layout with NMDedupMultiEntry and NMDedupMultiHeadEntry. + * + * It is recognizable by having lst_entries_sentinel.next set to NULL. + * Contrary to the other entries, which have lst_entries.next + * always non-NULL. + * */ + CList lst_entries_sentinel; + const NMDedupMultiObj * obj; + const NMDedupMultiIdxType *idx_type; + bool lookup_head; } LookupEntry; struct _NMDedupMultiIndex { - int ref_count; - GHashTable *idx_entries; - GHashTable *idx_objs; + int ref_count; + GHashTable *idx_entries; + GHashTable *idx_objs; }; /*****************************************************************************/ static void -ASSERT_idx_type (const NMDedupMultiIdxType *idx_type) +ASSERT_idx_type(const NMDedupMultiIdxType *idx_type) { - nm_assert (idx_type); + nm_assert(idx_type); #if NM_MORE_ASSERTS > 10 - nm_assert (idx_type->klass); - nm_assert (idx_type->klass->idx_obj_id_hash_update); - nm_assert (idx_type->klass->idx_obj_id_equal); - nm_assert (!!idx_type->klass->idx_obj_partition_hash_update == !!idx_type->klass->idx_obj_partition_equal); - nm_assert (idx_type->lst_idx_head.next); + nm_assert(idx_type->klass); + nm_assert(idx_type->klass->idx_obj_id_hash_update); + nm_assert(idx_type->klass->idx_obj_id_equal); + nm_assert(!!idx_type->klass->idx_obj_partition_hash_update + == !!idx_type->klass->idx_obj_partition_equal); + nm_assert(idx_type->lst_idx_head.next); #endif } void -nm_dedup_multi_idx_type_init (NMDedupMultiIdxType *idx_type, - const NMDedupMultiIdxTypeClass *klass) +nm_dedup_multi_idx_type_init(NMDedupMultiIdxType *idx_type, const NMDedupMultiIdxTypeClass *klass) { - nm_assert (idx_type); - nm_assert (klass); + nm_assert(idx_type); + nm_assert(klass); - memset (idx_type, 0, sizeof (*idx_type)); - idx_type->klass = klass; - c_list_init (&idx_type->lst_idx_head); + *idx_type = (NMDedupMultiIdxType){ + .klass = klass, + .lst_idx_head = C_LIST_INIT(idx_type->lst_idx_head), + }; - ASSERT_idx_type (idx_type); + ASSERT_idx_type(idx_type); } /*****************************************************************************/ static NMDedupMultiEntry * -_entry_lookup_obj (const NMDedupMultiIndex *self, - const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj) +_entry_lookup_obj(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj) { - const LookupEntry stack_entry = { - .obj = obj, - .idx_type = idx_type, - .lookup_head = FALSE, - }; - - ASSERT_idx_type (idx_type); - return g_hash_table_lookup (self->idx_entries, &stack_entry); + const LookupEntry stack_entry = { + .obj = obj, + .idx_type = idx_type, + .lookup_head = FALSE, + }; + + ASSERT_idx_type(idx_type); + return g_hash_table_lookup(self->idx_entries, &stack_entry); } static NMDedupMultiHeadEntry * -_entry_lookup_head (const NMDedupMultiIndex *self, - const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj) +_entry_lookup_head(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj) { - NMDedupMultiHeadEntry *head_entry; - const LookupEntry stack_entry = { - .obj = obj, - .idx_type = idx_type, - .lookup_head = TRUE, - }; - - ASSERT_idx_type (idx_type); - - if (!idx_type->klass->idx_obj_partition_equal) { - if (c_list_is_empty (&idx_type->lst_idx_head)) - head_entry = NULL; - else { - nm_assert (c_list_length (&idx_type->lst_idx_head) == 1); - head_entry = c_list_entry (idx_type->lst_idx_head.next, NMDedupMultiHeadEntry, lst_idx); - } - nm_assert (head_entry == g_hash_table_lookup (self->idx_entries, &stack_entry)); - return head_entry; - } - - return g_hash_table_lookup (self->idx_entries, &stack_entry); + NMDedupMultiHeadEntry *head_entry; + const LookupEntry stack_entry = { + .obj = obj, + .idx_type = idx_type, + .lookup_head = TRUE, + }; + + ASSERT_idx_type(idx_type); + + if (!idx_type->klass->idx_obj_partition_equal) { + if (c_list_is_empty(&idx_type->lst_idx_head)) + head_entry = NULL; + else { + nm_assert(c_list_length(&idx_type->lst_idx_head) == 1); + head_entry = c_list_entry(idx_type->lst_idx_head.next, NMDedupMultiHeadEntry, lst_idx); + } + nm_assert(head_entry == g_hash_table_lookup(self->idx_entries, &stack_entry)); + return head_entry; + } + + return g_hash_table_lookup(self->idx_entries, &stack_entry); } static void -_entry_unpack (const NMDedupMultiEntry *entry, - const NMDedupMultiIdxType **out_idx_type, - const NMDedupMultiObj **out_obj, - gboolean *out_lookup_head) +_entry_unpack(const NMDedupMultiEntry * entry, + const NMDedupMultiIdxType **out_idx_type, + const NMDedupMultiObj ** out_obj, + gboolean * out_lookup_head) { - const NMDedupMultiHeadEntry *head_entry; - const LookupEntry *lookup_entry; - - nm_assert (entry); - - G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (LookupEntry, lst_entries_sentinel) == G_STRUCT_OFFSET (NMDedupMultiEntry, lst_entries)); - G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMDedupMultiEntry, lst_entries) == G_STRUCT_OFFSET (NMDedupMultiHeadEntry, lst_entries_head)); - G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMDedupMultiEntry, obj) == G_STRUCT_OFFSET (NMDedupMultiHeadEntry, idx_type)); - G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMDedupMultiEntry, is_head) == G_STRUCT_OFFSET (NMDedupMultiHeadEntry, is_head)); - - if (!entry->lst_entries.next) { - /* the entry is stack-allocated by _entry_lookup(). */ - lookup_entry = (LookupEntry *) entry; - *out_obj = lookup_entry->obj; - *out_idx_type = lookup_entry->idx_type; - *out_lookup_head = lookup_entry->lookup_head; - } else if (entry->is_head) { - head_entry = (NMDedupMultiHeadEntry *) entry; - nm_assert (!c_list_is_empty (&head_entry->lst_entries_head)); - *out_obj = c_list_entry (head_entry->lst_entries_head.next, NMDedupMultiEntry, lst_entries)->obj; - *out_idx_type = head_entry->idx_type; - *out_lookup_head = TRUE; - } else { - *out_obj = entry->obj; - *out_idx_type = entry->head->idx_type; - *out_lookup_head = FALSE; - } - - 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 partition 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); + const NMDedupMultiHeadEntry *head_entry; + const LookupEntry * lookup_entry; + + nm_assert(entry); + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(LookupEntry, lst_entries_sentinel) + == G_STRUCT_OFFSET(NMDedupMultiEntry, lst_entries)); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMDedupMultiEntry, lst_entries) + == G_STRUCT_OFFSET(NMDedupMultiHeadEntry, lst_entries_head)); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMDedupMultiEntry, obj) + == G_STRUCT_OFFSET(NMDedupMultiHeadEntry, idx_type)); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMDedupMultiEntry, is_head) + == G_STRUCT_OFFSET(NMDedupMultiHeadEntry, is_head)); + + if (!entry->lst_entries.next) { + /* the entry is stack-allocated by _entry_lookup(). */ + lookup_entry = (LookupEntry *) entry; + *out_obj = lookup_entry->obj; + *out_idx_type = lookup_entry->idx_type; + *out_lookup_head = lookup_entry->lookup_head; + } else if (entry->is_head) { + head_entry = (NMDedupMultiHeadEntry *) entry; + nm_assert(!c_list_is_empty(&head_entry->lst_entries_head)); + *out_obj = + c_list_entry(head_entry->lst_entries_head.next, NMDedupMultiEntry, lst_entries)->obj; + *out_idx_type = head_entry->idx_type; + *out_lookup_head = TRUE; + } else { + *out_obj = entry->obj; + *out_idx_type = entry->head->idx_type; + *out_lookup_head = FALSE; + } + + 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 partition 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 -_dict_idx_entries_hash (const NMDedupMultiEntry *entry) +_dict_idx_entries_hash(const NMDedupMultiEntry *entry) { - const NMDedupMultiIdxType *idx_type; - const NMDedupMultiObj *obj; - gboolean lookup_head; - NMHashState h; + const NMDedupMultiIdxType *idx_type; + const NMDedupMultiObj * obj; + gboolean lookup_head; + NMHashState h; - _entry_unpack (entry, &idx_type, &obj, &lookup_head); + _entry_unpack(entry, &idx_type, &obj, &lookup_head); - nm_hash_init (&h, 1914869417u); - if (idx_type->klass->idx_obj_partition_hash_update) { - nm_assert (obj); - idx_type->klass->idx_obj_partition_hash_update (idx_type, obj, &h); - } + nm_hash_init(&h, 1914869417u); + if (idx_type->klass->idx_obj_partition_hash_update) { + nm_assert(obj); + idx_type->klass->idx_obj_partition_hash_update(idx_type, obj, &h); + } - if (!lookup_head) - idx_type->klass->idx_obj_id_hash_update (idx_type, obj, &h); + if (!lookup_head) + idx_type->klass->idx_obj_id_hash_update(idx_type, obj, &h); - nm_hash_update_val (&h, idx_type); - return nm_hash_complete (&h); + nm_hash_update_val(&h, idx_type); + return nm_hash_complete(&h); } static gboolean -_dict_idx_entries_equal (const NMDedupMultiEntry *entry_a, - const NMDedupMultiEntry *entry_b) +_dict_idx_entries_equal(const NMDedupMultiEntry *entry_a, const NMDedupMultiEntry *entry_b) { - const NMDedupMultiIdxType *idx_type_a, *idx_type_b; - const NMDedupMultiObj *obj_a, *obj_b; - gboolean lookup_head_a, lookup_head_b; - - _entry_unpack (entry_a, &idx_type_a, &obj_a, &lookup_head_a); - _entry_unpack (entry_b, &idx_type_b, &obj_b, &lookup_head_b); - - if ( idx_type_a != idx_type_b - || lookup_head_a != lookup_head_b) - return FALSE; - if (!nm_dedup_multi_idx_type_partition_equal (idx_type_a, obj_a, obj_b)) - return FALSE; - if ( !lookup_head_a - && !nm_dedup_multi_idx_type_id_equal (idx_type_a, obj_a, obj_b)) - return FALSE; - return TRUE; + const NMDedupMultiIdxType *idx_type_a, *idx_type_b; + const NMDedupMultiObj * obj_a, *obj_b; + gboolean lookup_head_a, lookup_head_b; + + _entry_unpack(entry_a, &idx_type_a, &obj_a, &lookup_head_a); + _entry_unpack(entry_b, &idx_type_b, &obj_b, &lookup_head_b); + + if (idx_type_a != idx_type_b || lookup_head_a != lookup_head_b) + return FALSE; + if (!nm_dedup_multi_idx_type_partition_equal(idx_type_a, obj_a, obj_b)) + return FALSE; + if (!lookup_head_a && !nm_dedup_multi_idx_type_id_equal(idx_type_a, obj_a, obj_b)) + return FALSE; + return TRUE; } /*****************************************************************************/ static gboolean -_add (NMDedupMultiIndex *self, - NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj, - NMDedupMultiEntry *entry, - NMDedupMultiIdxMode mode, - const NMDedupMultiEntry *entry_order, - NMDedupMultiHeadEntry *head_existing, - const NMDedupMultiEntry **out_entry, - const NMDedupMultiObj **out_obj_old) +_add(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + const NMDedupMultiObj * obj, + NMDedupMultiEntry * entry, + NMDedupMultiIdxMode mode, + const NMDedupMultiEntry * entry_order, + NMDedupMultiHeadEntry * head_existing, + const NMDedupMultiEntry **out_entry, + const NMDedupMultiObj ** out_obj_old) { - NMDedupMultiHeadEntry *head_entry; - const NMDedupMultiObj *obj_new, *obj_old; - gboolean add_head_entry = FALSE; - - nm_assert (self); - ASSERT_idx_type (idx_type); - nm_assert (obj); - nm_assert (NM_IN_SET (mode, - NM_DEDUP_MULTI_IDX_MODE_PREPEND, - NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, - NM_DEDUP_MULTI_IDX_MODE_APPEND, - NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE)); - nm_assert (!head_existing || head_existing->idx_type == idx_type); - nm_assert (({ - const NMDedupMultiHeadEntry *_h; - gboolean _ok = TRUE; - if (head_existing) { - _h = nm_dedup_multi_index_lookup_head (self, idx_type, obj); - if (head_existing == NM_DEDUP_MULTI_HEAD_ENTRY_MISSING) - _ok = (_h == NULL); - else - _ok = (_h == head_existing); - } - _ok; - })); - - if (entry) { - gboolean changed = FALSE; - - nm_dedup_multi_entry_set_dirty (entry, FALSE); - - nm_assert (!head_existing || entry->head == head_existing); - nm_assert (!entry_order || entry_order->head == entry->head); - nm_assert (!entry_order || c_list_contains (&entry->lst_entries, &entry_order->lst_entries)); - nm_assert (!entry_order || c_list_contains (&entry_order->lst_entries, &entry->lst_entries)); - - switch (mode) { - case NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE: - if (entry_order) { - if (nm_c_list_move_before ((CList *) &entry_order->lst_entries, &entry->lst_entries)) - changed = TRUE; - } else { - if (nm_c_list_move_front ((CList *) &entry->head->lst_entries_head, &entry->lst_entries)) - changed = TRUE; - } - break; - case NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE: - if (entry_order) { - if (nm_c_list_move_after ((CList *) &entry_order->lst_entries, &entry->lst_entries)) - changed = TRUE; - } else { - if (nm_c_list_move_tail ((CList *) &entry->head->lst_entries_head, &entry->lst_entries)) - changed = TRUE; - } - break; - case NM_DEDUP_MULTI_IDX_MODE_PREPEND: - case NM_DEDUP_MULTI_IDX_MODE_APPEND: - break; - }; - - nm_assert (obj->klass == ((const NMDedupMultiObj *) entry->obj)->klass); - if ( obj == entry->obj - || obj->klass->obj_full_equal (obj, - entry->obj)) { - NM_SET_OUT (out_entry, entry); - NM_SET_OUT (out_obj_old, nm_dedup_multi_obj_ref (entry->obj)); - return changed; - } - - obj_new = nm_dedup_multi_index_obj_intern (self, obj); - - obj_old = entry->obj; - entry->obj = obj_new; - - NM_SET_OUT (out_entry, entry); - if (out_obj_old) - *out_obj_old = obj_old; - else - nm_dedup_multi_obj_unref (obj_old); - return TRUE; - } - - if ( idx_type->klass->idx_obj_partitionable - && !idx_type->klass->idx_obj_partitionable (idx_type, obj)) { - /* this object cannot be partitioned by this idx_type. */ - nm_assert (!head_existing || head_existing == NM_DEDUP_MULTI_HEAD_ENTRY_MISSING); - NM_SET_OUT (out_entry, NULL); - NM_SET_OUT (out_obj_old, NULL); - return FALSE; - } - - obj_new = nm_dedup_multi_index_obj_intern (self, obj); - - if (!head_existing) - head_entry = _entry_lookup_head (self, idx_type, obj_new); - else if (head_existing == NM_DEDUP_MULTI_HEAD_ENTRY_MISSING) - head_entry = NULL; - else - head_entry = head_existing; - - if (!head_entry) { - head_entry = g_slice_new0 (NMDedupMultiHeadEntry); - head_entry->is_head = TRUE; - head_entry->idx_type = idx_type; - c_list_init (&head_entry->lst_entries_head); - c_list_link_tail (&idx_type->lst_idx_head, &head_entry->lst_idx); - add_head_entry = TRUE; - } else - nm_assert (c_list_contains (&idx_type->lst_idx_head, &head_entry->lst_idx)); - - if (entry_order) { - nm_assert (!add_head_entry); - nm_assert (entry_order->head == head_entry); - nm_assert (c_list_contains (&head_entry->lst_entries_head, &entry_order->lst_entries)); - nm_assert (c_list_contains (&entry_order->lst_entries, &head_entry->lst_entries_head)); - } - - entry = g_slice_new0 (NMDedupMultiEntry); - entry->obj = obj_new; - entry->head = head_entry; - - switch (mode) { - case NM_DEDUP_MULTI_IDX_MODE_PREPEND: - case NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE: - if (entry_order) - c_list_link_before ((CList *) &entry_order->lst_entries, &entry->lst_entries); - else - c_list_link_front (&head_entry->lst_entries_head, &entry->lst_entries); - break; - default: - if (entry_order) - c_list_link_after ((CList *) &entry_order->lst_entries, &entry->lst_entries); - else - c_list_link_tail (&head_entry->lst_entries_head, &entry->lst_entries); - break; - }; - - idx_type->len++; - head_entry->len++; - - if ( add_head_entry - && !g_hash_table_add (self->idx_entries, head_entry)) - nm_assert_not_reached (); - - if (!g_hash_table_add (self->idx_entries, entry)) - nm_assert_not_reached (); - - NM_SET_OUT (out_entry, entry); - NM_SET_OUT (out_obj_old, NULL); - return TRUE; + NMDedupMultiHeadEntry *head_entry; + const NMDedupMultiObj *obj_new, *obj_old; + gboolean add_head_entry = FALSE; + + nm_assert(self); + ASSERT_idx_type(idx_type); + nm_assert(obj); + nm_assert(NM_IN_SET(mode, + NM_DEDUP_MULTI_IDX_MODE_PREPEND, + NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, + NM_DEDUP_MULTI_IDX_MODE_APPEND, + NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE)); + nm_assert(!head_existing || head_existing->idx_type == idx_type); + nm_assert(({ + const NMDedupMultiHeadEntry *_h; + gboolean _ok = TRUE; + if (head_existing) { + _h = nm_dedup_multi_index_lookup_head(self, idx_type, obj); + if (head_existing == NM_DEDUP_MULTI_HEAD_ENTRY_MISSING) + _ok = (_h == NULL); + else + _ok = (_h == head_existing); + } + _ok; + })); + + if (entry) { + gboolean changed = FALSE; + + nm_dedup_multi_entry_set_dirty(entry, FALSE); + + nm_assert(!head_existing || entry->head == head_existing); + nm_assert(!entry_order || entry_order->head == entry->head); + nm_assert(!entry_order || c_list_contains(&entry->lst_entries, &entry_order->lst_entries)); + nm_assert(!entry_order || c_list_contains(&entry_order->lst_entries, &entry->lst_entries)); + + switch (mode) { + case NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE: + if (entry_order) { + if (nm_c_list_move_before((CList *) &entry_order->lst_entries, &entry->lst_entries)) + changed = TRUE; + } else { + if (nm_c_list_move_front((CList *) &entry->head->lst_entries_head, + &entry->lst_entries)) + changed = TRUE; + } + break; + case NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE: + if (entry_order) { + if (nm_c_list_move_after((CList *) &entry_order->lst_entries, &entry->lst_entries)) + changed = TRUE; + } else { + if (nm_c_list_move_tail((CList *) &entry->head->lst_entries_head, + &entry->lst_entries)) + changed = TRUE; + } + break; + case NM_DEDUP_MULTI_IDX_MODE_PREPEND: + case NM_DEDUP_MULTI_IDX_MODE_APPEND: + break; + }; + + nm_assert(obj->klass == ((const NMDedupMultiObj *) entry->obj)->klass); + if (obj == entry->obj || obj->klass->obj_full_equal(obj, entry->obj)) { + NM_SET_OUT(out_entry, entry); + NM_SET_OUT(out_obj_old, nm_dedup_multi_obj_ref(entry->obj)); + return changed; + } + + obj_new = nm_dedup_multi_index_obj_intern(self, obj); + + obj_old = entry->obj; + entry->obj = obj_new; + + NM_SET_OUT(out_entry, entry); + if (out_obj_old) + *out_obj_old = obj_old; + else + nm_dedup_multi_obj_unref(obj_old); + return TRUE; + } + + if (idx_type->klass->idx_obj_partitionable + && !idx_type->klass->idx_obj_partitionable(idx_type, obj)) { + /* this object cannot be partitioned by this idx_type. */ + nm_assert(!head_existing || head_existing == NM_DEDUP_MULTI_HEAD_ENTRY_MISSING); + NM_SET_OUT(out_entry, NULL); + NM_SET_OUT(out_obj_old, NULL); + return FALSE; + } + + obj_new = nm_dedup_multi_index_obj_intern(self, obj); + + if (!head_existing) + head_entry = _entry_lookup_head(self, idx_type, obj_new); + else if (head_existing == NM_DEDUP_MULTI_HEAD_ENTRY_MISSING) + head_entry = NULL; + else + head_entry = head_existing; + + if (!head_entry) { + head_entry = g_slice_new0(NMDedupMultiHeadEntry); + head_entry->is_head = TRUE; + head_entry->idx_type = idx_type; + c_list_init(&head_entry->lst_entries_head); + c_list_link_tail(&idx_type->lst_idx_head, &head_entry->lst_idx); + add_head_entry = TRUE; + } else + nm_assert(c_list_contains(&idx_type->lst_idx_head, &head_entry->lst_idx)); + + if (entry_order) { + nm_assert(!add_head_entry); + nm_assert(entry_order->head == head_entry); + nm_assert(c_list_contains(&head_entry->lst_entries_head, &entry_order->lst_entries)); + nm_assert(c_list_contains(&entry_order->lst_entries, &head_entry->lst_entries_head)); + } + + entry = g_slice_new0(NMDedupMultiEntry); + entry->obj = obj_new; + entry->head = head_entry; + + switch (mode) { + case NM_DEDUP_MULTI_IDX_MODE_PREPEND: + case NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE: + if (entry_order) + c_list_link_before((CList *) &entry_order->lst_entries, &entry->lst_entries); + else + c_list_link_front(&head_entry->lst_entries_head, &entry->lst_entries); + break; + default: + if (entry_order) + c_list_link_after((CList *) &entry_order->lst_entries, &entry->lst_entries); + else + c_list_link_tail(&head_entry->lst_entries_head, &entry->lst_entries); + break; + }; + + idx_type->len++; + head_entry->len++; + + if (add_head_entry && !g_hash_table_add(self->idx_entries, head_entry)) + nm_assert_not_reached(); + + if (!g_hash_table_add(self->idx_entries, entry)) + nm_assert_not_reached(); + + NM_SET_OUT(out_entry, entry); + NM_SET_OUT(out_obj_old, NULL); + return TRUE; } gboolean -nm_dedup_multi_index_add (NMDedupMultiIndex *self, - NMDedupMultiIdxType *idx_type, - /*const NMDedupMultiObj * */ gconstpointer obj, - NMDedupMultiIdxMode mode, - const NMDedupMultiEntry **out_entry, - /* const NMDedupMultiObj ** */ gpointer out_obj_old) +nm_dedup_multi_index_add(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj, + NMDedupMultiIdxMode mode, + const NMDedupMultiEntry ** out_entry, + /* const NMDedupMultiObj ** */ gpointer out_obj_old) { - NMDedupMultiEntry *entry; - - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (idx_type, FALSE); - g_return_val_if_fail (obj, FALSE); - g_return_val_if_fail (NM_IN_SET (mode, - NM_DEDUP_MULTI_IDX_MODE_PREPEND, - NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, - NM_DEDUP_MULTI_IDX_MODE_APPEND, - NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE), - FALSE); - - entry = _entry_lookup_obj (self, idx_type, obj); - return _add (self, idx_type, obj, - entry, mode, - NULL, NULL, - out_entry, out_obj_old); + NMDedupMultiEntry *entry; + + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(idx_type, FALSE); + g_return_val_if_fail(obj, FALSE); + g_return_val_if_fail(NM_IN_SET(mode, + NM_DEDUP_MULTI_IDX_MODE_PREPEND, + NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, + NM_DEDUP_MULTI_IDX_MODE_APPEND, + NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE), + FALSE); + + entry = _entry_lookup_obj(self, idx_type, obj); + return _add(self, idx_type, obj, entry, mode, NULL, NULL, out_entry, out_obj_old); } /* nm_dedup_multi_index_add_full: @@ -427,216 +423,211 @@ nm_dedup_multi_index_add (NMDedupMultiIndex *self, * Return: %TRUE if anything changed, %FALSE if nothing changed. */ gboolean -nm_dedup_multi_index_add_full (NMDedupMultiIndex *self, - NMDedupMultiIdxType *idx_type, - /*const NMDedupMultiObj * */ gconstpointer obj, - NMDedupMultiIdxMode mode, - const NMDedupMultiEntry *entry_order, - const NMDedupMultiEntry *entry_existing, - const NMDedupMultiHeadEntry *head_existing, - const NMDedupMultiEntry **out_entry, - /* const NMDedupMultiObj ** */ gpointer out_obj_old) +nm_dedup_multi_index_add_full(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj, + NMDedupMultiIdxMode mode, + const NMDedupMultiEntry * entry_order, + const NMDedupMultiEntry * entry_existing, + const NMDedupMultiHeadEntry * head_existing, + const NMDedupMultiEntry ** out_entry, + /* const NMDedupMultiObj ** */ gpointer out_obj_old) { - NMDedupMultiEntry *entry; - - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (idx_type, FALSE); - g_return_val_if_fail (obj, FALSE); - g_return_val_if_fail (NM_IN_SET (mode, - NM_DEDUP_MULTI_IDX_MODE_PREPEND, - NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, - NM_DEDUP_MULTI_IDX_MODE_APPEND, - NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE), - FALSE); - - if (entry_existing == NULL) - entry = _entry_lookup_obj (self, idx_type, obj); - else if (entry_existing == NM_DEDUP_MULTI_ENTRY_MISSING) { - nm_assert (!_entry_lookup_obj (self, idx_type, obj)); - entry = NULL; - } else { - nm_assert (entry_existing == _entry_lookup_obj (self, idx_type, obj)); - entry = (NMDedupMultiEntry *) entry_existing; - } - return _add (self, idx_type, obj, - entry, - mode, entry_order, - (NMDedupMultiHeadEntry *) head_existing, - out_entry, out_obj_old); + NMDedupMultiEntry *entry; + + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(idx_type, FALSE); + g_return_val_if_fail(obj, FALSE); + g_return_val_if_fail(NM_IN_SET(mode, + NM_DEDUP_MULTI_IDX_MODE_PREPEND, + NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, + NM_DEDUP_MULTI_IDX_MODE_APPEND, + NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE), + FALSE); + + if (entry_existing == NULL) + entry = _entry_lookup_obj(self, idx_type, obj); + else if (entry_existing == NM_DEDUP_MULTI_ENTRY_MISSING) { + nm_assert(!_entry_lookup_obj(self, idx_type, obj)); + entry = NULL; + } else { + nm_assert(entry_existing == _entry_lookup_obj(self, idx_type, obj)); + entry = (NMDedupMultiEntry *) entry_existing; + } + return _add(self, + idx_type, + obj, + entry, + mode, + entry_order, + (NMDedupMultiHeadEntry *) head_existing, + out_entry, + out_obj_old); } /*****************************************************************************/ static void -_remove_entry (NMDedupMultiIndex *self, - NMDedupMultiEntry *entry, - gboolean *out_head_entry_removed) +_remove_entry(NMDedupMultiIndex *self, NMDedupMultiEntry *entry, gboolean *out_head_entry_removed) { - const NMDedupMultiObj *obj; - NMDedupMultiHeadEntry *head_entry; - NMDedupMultiIdxType *idx_type; + const NMDedupMultiObj *obj; + NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIdxType * idx_type; - nm_assert (self); - nm_assert (entry); - nm_assert (entry->obj); - nm_assert (entry->head); - nm_assert (!c_list_is_empty (&entry->lst_entries)); - nm_assert (g_hash_table_lookup (self->idx_entries, entry) == entry); + nm_assert(self); + nm_assert(entry); + nm_assert(entry->obj); + nm_assert(entry->head); + nm_assert(!c_list_is_empty(&entry->lst_entries)); + nm_assert(g_hash_table_lookup(self->idx_entries, entry) == entry); - head_entry = (NMDedupMultiHeadEntry *) entry->head; - obj = entry->obj; + head_entry = (NMDedupMultiHeadEntry *) entry->head; + obj = entry->obj; - nm_assert (head_entry); - nm_assert (head_entry->len > 0); - nm_assert (g_hash_table_lookup (self->idx_entries, head_entry) == head_entry); + nm_assert(head_entry); + nm_assert(head_entry->len > 0); + nm_assert(g_hash_table_lookup(self->idx_entries, head_entry) == head_entry); - idx_type = (NMDedupMultiIdxType *) head_entry->idx_type; - ASSERT_idx_type (idx_type); + idx_type = (NMDedupMultiIdxType *) head_entry->idx_type; + ASSERT_idx_type(idx_type); - nm_assert (idx_type->len >= head_entry->len); - if (--head_entry->len > 0) { - nm_assert (idx_type->len > 1); - idx_type->len--; - head_entry = NULL; - } + nm_assert(idx_type->len >= head_entry->len); + if (--head_entry->len > 0) { + nm_assert(idx_type->len > 1); + idx_type->len--; + head_entry = NULL; + } - NM_SET_OUT (out_head_entry_removed, head_entry != NULL); + NM_SET_OUT(out_head_entry_removed, head_entry != NULL); - if (!g_hash_table_remove (self->idx_entries, entry)) - nm_assert_not_reached (); + if (!g_hash_table_remove(self->idx_entries, entry)) + nm_assert_not_reached(); - if ( head_entry - && !g_hash_table_remove (self->idx_entries, head_entry)) - nm_assert_not_reached (); + if (head_entry && !g_hash_table_remove(self->idx_entries, head_entry)) + nm_assert_not_reached(); - c_list_unlink_stale (&entry->lst_entries); - g_slice_free (NMDedupMultiEntry, entry); + c_list_unlink_stale(&entry->lst_entries); + g_slice_free(NMDedupMultiEntry, entry); - if (head_entry) { - nm_assert (c_list_is_empty (&head_entry->lst_entries_head)); - c_list_unlink_stale (&head_entry->lst_idx); - g_slice_free (NMDedupMultiHeadEntry, head_entry); - } + if (head_entry) { + nm_assert(c_list_is_empty(&head_entry->lst_entries_head)); + c_list_unlink_stale(&head_entry->lst_idx); + g_slice_free(NMDedupMultiHeadEntry, head_entry); + } - nm_dedup_multi_obj_unref (obj); + nm_dedup_multi_obj_unref(obj); } static guint -_remove_head (NMDedupMultiIndex *self, - NMDedupMultiHeadEntry *head_entry, - gboolean remove_all /* otherwise just dirty ones */, - gboolean mark_survivors_dirty) +_remove_head(NMDedupMultiIndex * self, + NMDedupMultiHeadEntry *head_entry, + gboolean remove_all /* otherwise just dirty ones */, + gboolean mark_survivors_dirty) { - guint n; - gboolean head_entry_removed; - CList *iter_entry, *iter_entry_safe; - - nm_assert (self); - nm_assert (head_entry); - nm_assert (head_entry->len > 0); - nm_assert (head_entry->len == c_list_length (&head_entry->lst_entries_head)); - nm_assert (g_hash_table_lookup (self->idx_entries, head_entry) == head_entry); - - n = 0; - c_list_for_each_safe (iter_entry, iter_entry_safe, &head_entry->lst_entries_head) { - NMDedupMultiEntry *entry; - - entry = c_list_entry (iter_entry, NMDedupMultiEntry, lst_entries); - if ( remove_all - || entry->dirty) { - _remove_entry (self, - entry, - &head_entry_removed); - n++; - if (head_entry_removed) - break; - } else if (mark_survivors_dirty) - nm_dedup_multi_entry_set_dirty (entry, TRUE); - } - - return n; + guint n; + gboolean head_entry_removed; + CList * iter_entry, *iter_entry_safe; + + nm_assert(self); + nm_assert(head_entry); + nm_assert(head_entry->len > 0); + nm_assert(head_entry->len == c_list_length(&head_entry->lst_entries_head)); + nm_assert(g_hash_table_lookup(self->idx_entries, head_entry) == head_entry); + + n = 0; + c_list_for_each_safe (iter_entry, iter_entry_safe, &head_entry->lst_entries_head) { + NMDedupMultiEntry *entry; + + entry = c_list_entry(iter_entry, NMDedupMultiEntry, lst_entries); + if (remove_all || entry->dirty) { + _remove_entry(self, entry, &head_entry_removed); + n++; + if (head_entry_removed) + break; + } else if (mark_survivors_dirty) + nm_dedup_multi_entry_set_dirty(entry, TRUE); + } + + return n; } static guint -_remove_idx_entry (NMDedupMultiIndex *self, - NMDedupMultiIdxType *idx_type, - gboolean remove_all /* otherwise just dirty ones */, - gboolean mark_survivors_dirty) +_remove_idx_entry(NMDedupMultiIndex * self, + NMDedupMultiIdxType *idx_type, + gboolean remove_all /* otherwise just dirty ones */, + gboolean mark_survivors_dirty) { - guint n; - CList *iter_idx, *iter_idx_safe; - - nm_assert (self); - ASSERT_idx_type (idx_type); - - n = 0; - c_list_for_each_safe (iter_idx, iter_idx_safe, &idx_type->lst_idx_head) { - n += _remove_head (self, - c_list_entry (iter_idx, NMDedupMultiHeadEntry, lst_idx), - remove_all, mark_survivors_dirty); - } - return n; + guint n; + CList *iter_idx, *iter_idx_safe; + + nm_assert(self); + ASSERT_idx_type(idx_type); + + n = 0; + c_list_for_each_safe (iter_idx, iter_idx_safe, &idx_type->lst_idx_head) { + n += _remove_head(self, + c_list_entry(iter_idx, NMDedupMultiHeadEntry, lst_idx), + remove_all, + mark_survivors_dirty); + } + return n; } guint -nm_dedup_multi_index_remove_entry (NMDedupMultiIndex *self, - gconstpointer entry) +nm_dedup_multi_index_remove_entry(NMDedupMultiIndex *self, gconstpointer entry) { - g_return_val_if_fail (self, 0); + g_return_val_if_fail(self, 0); - nm_assert (entry); + nm_assert(entry); - if (!((NMDedupMultiEntry *) entry)->is_head) { - _remove_entry (self, (NMDedupMultiEntry *) entry, NULL); - return 1; - } - return _remove_head (self, (NMDedupMultiHeadEntry *) entry, TRUE, FALSE); + if (!((NMDedupMultiEntry *) entry)->is_head) { + _remove_entry(self, (NMDedupMultiEntry *) entry, NULL); + return 1; + } + return _remove_head(self, (NMDedupMultiHeadEntry *) entry, TRUE, FALSE); } guint -nm_dedup_multi_index_remove_obj (NMDedupMultiIndex *self, - NMDedupMultiIdxType *idx_type, - /*const NMDedupMultiObj * */ gconstpointer obj, - /*const NMDedupMultiObj ** */ gconstpointer *out_obj) +nm_dedup_multi_index_remove_obj(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj, + /*const NMDedupMultiObj ** */ gconstpointer *out_obj) { - const NMDedupMultiEntry *entry; + const NMDedupMultiEntry *entry; - entry = nm_dedup_multi_index_lookup_obj (self, idx_type, obj); - if (!entry) { - NM_SET_OUT (out_obj, NULL); - return 0; - } + entry = nm_dedup_multi_index_lookup_obj(self, idx_type, obj); + if (!entry) { + NM_SET_OUT(out_obj, NULL); + return 0; + } - /* since we are about to remove the object, we obviously pass - * a reference to @out_obj, the caller MUST unref the object, - * if he chooses to provide @out_obj. */ - NM_SET_OUT (out_obj, nm_dedup_multi_obj_ref (entry->obj)); + /* since we are about to remove the object, we obviously pass + * a reference to @out_obj, the caller MUST unref the object, + * if he chooses to provide @out_obj. */ + NM_SET_OUT(out_obj, nm_dedup_multi_obj_ref(entry->obj)); - _remove_entry (self, (NMDedupMultiEntry *) entry, NULL); - return 1; + _remove_entry(self, (NMDedupMultiEntry *) entry, NULL); + return 1; } guint -nm_dedup_multi_index_remove_head (NMDedupMultiIndex *self, - NMDedupMultiIdxType *idx_type, - /*const NMDedupMultiObj * */ gconstpointer obj) +nm_dedup_multi_index_remove_head(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj) { - const NMDedupMultiHeadEntry *entry; + const NMDedupMultiHeadEntry *entry; - entry = nm_dedup_multi_index_lookup_head (self, idx_type, obj); - return entry - ? _remove_head (self, (NMDedupMultiHeadEntry *) entry, TRUE, FALSE) - : 0; + entry = nm_dedup_multi_index_lookup_head(self, idx_type, obj); + return entry ? _remove_head(self, (NMDedupMultiHeadEntry *) entry, TRUE, FALSE) : 0; } guint -nm_dedup_multi_index_remove_idx (NMDedupMultiIndex *self, - NMDedupMultiIdxType *idx_type) +nm_dedup_multi_index_remove_idx(NMDedupMultiIndex *self, NMDedupMultiIdxType *idx_type) { - g_return_val_if_fail (self, 0); - g_return_val_if_fail (idx_type, 0); + g_return_val_if_fail(self, 0); + g_return_val_if_fail(idx_type, 0); - return _remove_idx_entry (self, idx_type, TRUE, FALSE); + return _remove_idx_entry(self, idx_type, TRUE, FALSE); } /*****************************************************************************/ @@ -652,16 +643,16 @@ nm_dedup_multi_index_remove_idx (NMDedupMultiIndex *self, * Returns: the cache entry or %NULL if the entry wasn't found. */ const NMDedupMultiEntry * -nm_dedup_multi_index_lookup_obj (const NMDedupMultiIndex *self, - const NMDedupMultiIdxType *idx_type, - /*const NMDedupMultiObj * */ gconstpointer obj) +nm_dedup_multi_index_lookup_obj(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj) { - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (idx_type, FALSE); - g_return_val_if_fail (obj, FALSE); + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(idx_type, FALSE); + g_return_val_if_fail(obj, FALSE); - nm_assert (idx_type && idx_type->klass); - return _entry_lookup_obj (self, idx_type, obj); + nm_assert(idx_type && idx_type->klass); + return _entry_lookup_obj(self, idx_type, obj); } /** @@ -678,61 +669,60 @@ nm_dedup_multi_index_lookup_obj (const NMDedupMultiIndex *self, * Returns: the cache entry or %NULL if the entry wasn't found. */ const NMDedupMultiHeadEntry * -nm_dedup_multi_index_lookup_head (const NMDedupMultiIndex *self, - const NMDedupMultiIdxType *idx_type, - /*const NMDedupMultiObj * */ gconstpointer obj) +nm_dedup_multi_index_lookup_head(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj) { - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (idx_type, FALSE); + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(idx_type, FALSE); - return _entry_lookup_head (self, idx_type, obj); + return _entry_lookup_head(self, idx_type, obj); } /*****************************************************************************/ void -nm_dedup_multi_index_dirty_set_head (NMDedupMultiIndex *self, - const NMDedupMultiIdxType *idx_type, - /*const NMDedupMultiObj * */ gconstpointer obj) +nm_dedup_multi_index_dirty_set_head(NMDedupMultiIndex * self, + const NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj) { - NMDedupMultiHeadEntry *head_entry; - CList *iter_entry; + NMDedupMultiHeadEntry *head_entry; + CList * iter_entry; - g_return_if_fail (self); - g_return_if_fail (idx_type); + g_return_if_fail(self); + g_return_if_fail(idx_type); - head_entry = _entry_lookup_head (self, idx_type, obj); - if (!head_entry) - return; + head_entry = _entry_lookup_head(self, idx_type, obj); + if (!head_entry) + return; - c_list_for_each (iter_entry, &head_entry->lst_entries_head) { - NMDedupMultiEntry *entry; + c_list_for_each (iter_entry, &head_entry->lst_entries_head) { + NMDedupMultiEntry *entry; - entry = c_list_entry (iter_entry, NMDedupMultiEntry, lst_entries); - nm_dedup_multi_entry_set_dirty (entry, TRUE); - } + entry = c_list_entry(iter_entry, NMDedupMultiEntry, lst_entries); + nm_dedup_multi_entry_set_dirty(entry, TRUE); + } } void -nm_dedup_multi_index_dirty_set_idx (NMDedupMultiIndex *self, - const NMDedupMultiIdxType *idx_type) +nm_dedup_multi_index_dirty_set_idx(NMDedupMultiIndex *self, const NMDedupMultiIdxType *idx_type) { - CList *iter_idx, *iter_entry; + CList *iter_idx, *iter_entry; - g_return_if_fail (self); - g_return_if_fail (idx_type); + g_return_if_fail(self); + g_return_if_fail(idx_type); - c_list_for_each (iter_idx, &idx_type->lst_idx_head) { - NMDedupMultiHeadEntry *head_entry; + c_list_for_each (iter_idx, &idx_type->lst_idx_head) { + NMDedupMultiHeadEntry *head_entry; - head_entry = c_list_entry (iter_idx, NMDedupMultiHeadEntry, lst_idx); - c_list_for_each (iter_entry, &head_entry->lst_entries_head) { - NMDedupMultiEntry *entry; + head_entry = c_list_entry(iter_idx, NMDedupMultiHeadEntry, lst_idx); + c_list_for_each (iter_entry, &head_entry->lst_entries_head) { + NMDedupMultiEntry *entry; - entry = c_list_entry (iter_entry, NMDedupMultiEntry, lst_entries); - nm_dedup_multi_entry_set_dirty (entry, TRUE); - } - } + entry = c_list_entry(iter_entry, NMDedupMultiEntry, lst_entries); + nm_dedup_multi_entry_set_dirty(entry, TRUE); + } + } } /** @@ -750,219 +740,212 @@ nm_dedup_multi_index_dirty_set_idx (NMDedupMultiIndex *self, * Returns: number of deleted entries. */ guint -nm_dedup_multi_index_dirty_remove_idx (NMDedupMultiIndex *self, - NMDedupMultiIdxType *idx_type, - gboolean mark_survivors_dirty) +nm_dedup_multi_index_dirty_remove_idx(NMDedupMultiIndex * self, + NMDedupMultiIdxType *idx_type, + gboolean mark_survivors_dirty) { - g_return_val_if_fail (self, 0); - g_return_val_if_fail (idx_type, 0); + g_return_val_if_fail(self, 0); + g_return_val_if_fail(idx_type, 0); - return _remove_idx_entry (self, idx_type, FALSE, mark_survivors_dirty); + return _remove_idx_entry(self, idx_type, FALSE, mark_survivors_dirty); } /*****************************************************************************/ static guint -_dict_idx_objs_hash (const NMDedupMultiObj *obj) +_dict_idx_objs_hash(const NMDedupMultiObj *obj) { - NMHashState h; + NMHashState h; - nm_hash_init (&h, 1748638583u); - obj->klass->obj_full_hash_update (obj, &h); - return nm_hash_complete (&h); + nm_hash_init(&h, 1748638583u); + obj->klass->obj_full_hash_update(obj, &h); + return nm_hash_complete(&h); } static gboolean -_dict_idx_objs_equal (const NMDedupMultiObj *obj_a, - const NMDedupMultiObj *obj_b) +_dict_idx_objs_equal(const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b) { - return obj_a == obj_b - || ( obj_a->klass == obj_b->klass - && obj_a->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 -nm_dedup_multi_index_obj_release (NMDedupMultiIndex *self, - /* const NMDedupMultiObj * */ gconstpointer obj) +nm_dedup_multi_index_obj_release(NMDedupMultiIndex * self, + /* const NMDedupMultiObj * */ gconstpointer obj) { - nm_assert (self); - nm_assert (obj); - nm_assert (g_hash_table_lookup (self->idx_objs, obj) == obj); - nm_assert (((const NMDedupMultiObj *) obj)->_multi_idx == self); - - ((NMDedupMultiObj *) obj)->_multi_idx = NULL; - if (!g_hash_table_remove (self->idx_objs, obj)) - nm_assert_not_reached (); + nm_assert(self); + nm_assert(obj); + nm_assert(g_hash_table_lookup(self->idx_objs, obj) == obj); + nm_assert(((const NMDedupMultiObj *) obj)->_multi_idx == self); + + ((NMDedupMultiObj *) obj)->_multi_idx = NULL; + if (!g_hash_table_remove(self->idx_objs, obj)) + nm_assert_not_reached(); } gconstpointer -nm_dedup_multi_index_obj_find (NMDedupMultiIndex *self, - /* const NMDedupMultiObj * */ gconstpointer obj) +nm_dedup_multi_index_obj_find(NMDedupMultiIndex * self, + /* const NMDedupMultiObj * */ gconstpointer obj) { - g_return_val_if_fail (self, NULL); - g_return_val_if_fail (obj, NULL); + g_return_val_if_fail(self, NULL); + g_return_val_if_fail(obj, NULL); - return g_hash_table_lookup (self->idx_objs, obj); + return g_hash_table_lookup(self->idx_objs, obj); } gconstpointer -nm_dedup_multi_index_obj_intern (NMDedupMultiIndex *self, - /* const NMDedupMultiObj * */ gconstpointer obj) +nm_dedup_multi_index_obj_intern(NMDedupMultiIndex * self, + /* const NMDedupMultiObj * */ gconstpointer obj) { - const NMDedupMultiObj *obj_new = obj; - const NMDedupMultiObj *obj_old; + const NMDedupMultiObj *obj_new = obj; + const NMDedupMultiObj *obj_old; - nm_assert (self); - nm_assert (obj_new); + nm_assert(self); + nm_assert(obj_new); - if (obj_new->_multi_idx == self) { - nm_assert (g_hash_table_lookup (self->idx_objs, obj_new) == obj_new); - nm_dedup_multi_obj_ref (obj_new); - return obj_new; - } + if (obj_new->_multi_idx == self) { + nm_assert(g_hash_table_lookup(self->idx_objs, obj_new) == obj_new); + nm_dedup_multi_obj_ref(obj_new); + return obj_new; + } - obj_old = g_hash_table_lookup (self->idx_objs, obj_new); - nm_assert (obj_old != obj_new); + obj_old = g_hash_table_lookup(self->idx_objs, obj_new); + nm_assert(obj_old != obj_new); - if (obj_old) { - nm_assert (obj_old->_multi_idx == self); - nm_dedup_multi_obj_ref (obj_old); - return obj_old; - } + if (obj_old) { + nm_assert(obj_old->_multi_idx == self); + nm_dedup_multi_obj_ref(obj_old); + return obj_old; + } - if (nm_dedup_multi_obj_needs_clone (obj_new)) - obj_new = nm_dedup_multi_obj_clone (obj_new); - else - obj_new = nm_dedup_multi_obj_ref (obj_new); + if (nm_dedup_multi_obj_needs_clone(obj_new)) + obj_new = nm_dedup_multi_obj_clone(obj_new); + else + obj_new = nm_dedup_multi_obj_ref(obj_new); - nm_assert (obj_new); - nm_assert (!obj_new->_multi_idx); + nm_assert(obj_new); + nm_assert(!obj_new->_multi_idx); - if (!g_hash_table_add (self->idx_objs, (gpointer) obj_new)) - nm_assert_not_reached (); + if (!g_hash_table_add(self->idx_objs, (gpointer) obj_new)) + nm_assert_not_reached(); - ((NMDedupMultiObj *) obj_new)->_multi_idx = self; - return obj_new; + ((NMDedupMultiObj *) obj_new)->_multi_idx = self; + return obj_new; } void -nm_dedup_multi_obj_unref (const NMDedupMultiObj *obj) +nm_dedup_multi_obj_unref(const NMDedupMultiObj *obj) { - if (obj) { - nm_assert (obj->_ref_count > 0); - nm_assert (obj->_ref_count != NM_OBJ_REF_COUNT_STACKINIT); + if (obj) { + nm_assert(obj->_ref_count > 0); + nm_assert(obj->_ref_count != NM_OBJ_REF_COUNT_STACKINIT); again: - if (--(((NMDedupMultiObj *) obj)->_ref_count) <= 0) { - if (obj->_multi_idx) { - /* restore the ref-count to 1 and release the object first - * from the index. Then, retry again to unref. */ - ((NMDedupMultiObj *) obj)->_ref_count++; - nm_dedup_multi_index_obj_release (obj->_multi_idx, obj); - nm_assert (obj->_ref_count == 1); - nm_assert (!obj->_multi_idx); - goto again; - } - - obj->klass->obj_destroy ((NMDedupMultiObj *) obj); - } - } + if (--(((NMDedupMultiObj *) obj)->_ref_count) <= 0) { + if (obj->_multi_idx) { + /* restore the ref-count to 1 and release the object first + * from the index. Then, retry again to unref. */ + ((NMDedupMultiObj *) obj)->_ref_count++; + nm_dedup_multi_index_obj_release(obj->_multi_idx, obj); + nm_assert(obj->_ref_count == 1); + nm_assert(!obj->_multi_idx); + goto again; + } + + obj->klass->obj_destroy((NMDedupMultiObj *) obj); + } + } } gboolean -nm_dedup_multi_obj_needs_clone (const NMDedupMultiObj *obj) +nm_dedup_multi_obj_needs_clone(const NMDedupMultiObj *obj) { - nm_assert (obj); + nm_assert(obj); - if ( obj->_multi_idx - || obj->_ref_count == NM_OBJ_REF_COUNT_STACKINIT) - return TRUE; + if (obj->_multi_idx || obj->_ref_count == NM_OBJ_REF_COUNT_STACKINIT) + return TRUE; - if ( obj->klass->obj_needs_clone - && obj->klass->obj_needs_clone (obj)) - return TRUE; + if (obj->klass->obj_needs_clone && obj->klass->obj_needs_clone(obj)) + return TRUE; - return FALSE; + return FALSE; } const NMDedupMultiObj * -nm_dedup_multi_obj_clone (const NMDedupMultiObj *obj) +nm_dedup_multi_obj_clone(const NMDedupMultiObj *obj) { - const NMDedupMultiObj *o; + const NMDedupMultiObj *o; - nm_assert (obj); + nm_assert(obj); - o = obj->klass->obj_clone (obj); - nm_assert (o); - nm_assert (o->_ref_count == 1); - return o; + o = obj->klass->obj_clone(obj); + nm_assert(o); + nm_assert(o->_ref_count == 1); + return o; } gconstpointer * -nm_dedup_multi_objs_to_array_head (const NMDedupMultiHeadEntry *head_entry, - NMDedupMultiFcnSelectPredicate predicate, - gpointer user_data, - guint *out_len) +nm_dedup_multi_objs_to_array_head(const NMDedupMultiHeadEntry * head_entry, + NMDedupMultiFcnSelectPredicate predicate, + gpointer user_data, + guint * out_len) { - gconstpointer *result; - CList *iter; - guint i; - - if (!head_entry) { - NM_SET_OUT (out_len, 0); - return NULL; - } - - result = g_new (gconstpointer, head_entry->len + 1); - i = 0; - c_list_for_each (iter, &head_entry->lst_entries_head) { - const NMDedupMultiObj *obj = c_list_entry (iter, NMDedupMultiEntry, lst_entries)->obj; - - if ( !predicate - || predicate (obj, user_data)) { - nm_assert (i < head_entry->len); - result[i++] = obj; - } - } - - if (i == 0) { - g_free (result); - NM_SET_OUT (out_len, 0); - return NULL; - } - - nm_assert (i <= head_entry->len); - NM_SET_OUT (out_len, i); - result[i++] = NULL; - return result; + gconstpointer *result; + CList * iter; + guint i; + + if (!head_entry) { + NM_SET_OUT(out_len, 0); + return NULL; + } + + result = g_new(gconstpointer, head_entry->len + 1); + i = 0; + c_list_for_each (iter, &head_entry->lst_entries_head) { + const NMDedupMultiObj *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; + + if (!predicate || predicate(obj, user_data)) { + nm_assert(i < head_entry->len); + result[i++] = obj; + } + } + + if (i == 0) { + g_free(result); + NM_SET_OUT(out_len, 0); + return NULL; + } + + nm_assert(i <= head_entry->len); + NM_SET_OUT(out_len, i); + result[i++] = NULL; + return result; } GPtrArray * -nm_dedup_multi_objs_to_ptr_array_head (const NMDedupMultiHeadEntry *head_entry, - NMDedupMultiFcnSelectPredicate predicate, - gpointer user_data) +nm_dedup_multi_objs_to_ptr_array_head(const NMDedupMultiHeadEntry * head_entry, + NMDedupMultiFcnSelectPredicate predicate, + gpointer user_data) { - GPtrArray *result; - CList *iter; - - if (!head_entry) - return NULL; - - result = g_ptr_array_new_full (head_entry->len, - (GDestroyNotify) nm_dedup_multi_obj_unref); - c_list_for_each (iter, &head_entry->lst_entries_head) { - const NMDedupMultiObj *obj = c_list_entry (iter, NMDedupMultiEntry, lst_entries)->obj; - - if ( !predicate - || predicate (obj, user_data)) - g_ptr_array_add (result, (gpointer) nm_dedup_multi_obj_ref (obj)); - } - - if (result->len == 0) { - g_ptr_array_unref (result); - return NULL; - } - return result; + GPtrArray *result; + CList * iter; + + if (!head_entry) + return NULL; + + result = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nm_dedup_multi_obj_unref); + c_list_for_each (iter, &head_entry->lst_entries_head) { + const NMDedupMultiObj *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; + + if (!predicate || predicate(obj, user_data)) + g_ptr_array_add(result, (gpointer) nm_dedup_multi_obj_ref(obj)); + } + + if (result->len == 0) { + g_ptr_array_unref(result); + return NULL; + } + return result; } /** @@ -981,96 +964,102 @@ nm_dedup_multi_objs_to_ptr_array_head (const NMDedupMultiHeadEntry *head_entry, * right place and nothing was done. */ gboolean -nm_dedup_multi_entry_reorder (const NMDedupMultiEntry *entry, - const NMDedupMultiEntry *entry_order, - gboolean order_after) +nm_dedup_multi_entry_reorder(const NMDedupMultiEntry *entry, + const NMDedupMultiEntry *entry_order, + gboolean order_after) { - nm_assert (entry); - - if (!entry_order) { - const NMDedupMultiHeadEntry *head_entry = entry->head; - - if (order_after) { - if (nm_c_list_move_tail ((CList *) &head_entry->lst_entries_head, (CList *) &entry->lst_entries)) - return TRUE; - } else { - if (nm_c_list_move_front ((CList *) &head_entry->lst_entries_head, (CList *) &entry->lst_entries)) - return TRUE; - } - } else { - if (order_after) { - if (nm_c_list_move_after ((CList *) &entry_order->lst_entries, (CList *) &entry->lst_entries)) - return TRUE; - } else { - if (nm_c_list_move_before ((CList *) &entry_order->lst_entries, (CList *) &entry->lst_entries)) - return TRUE; - } - } - - return FALSE; + nm_assert(entry); + + if (!entry_order) { + const NMDedupMultiHeadEntry *head_entry = entry->head; + + if (order_after) { + if (nm_c_list_move_tail((CList *) &head_entry->lst_entries_head, + (CList *) &entry->lst_entries)) + return TRUE; + } else { + if (nm_c_list_move_front((CList *) &head_entry->lst_entries_head, + (CList *) &entry->lst_entries)) + return TRUE; + } + } else { + if (order_after) { + if (nm_c_list_move_after((CList *) &entry_order->lst_entries, + (CList *) &entry->lst_entries)) + return TRUE; + } else { + if (nm_c_list_move_before((CList *) &entry_order->lst_entries, + (CList *) &entry->lst_entries)) + return TRUE; + } + } + + return FALSE; } /*****************************************************************************/ NMDedupMultiIndex * -nm_dedup_multi_index_new (void) +nm_dedup_multi_index_new(void) { - NMDedupMultiIndex *self; - - self = g_slice_new0 (NMDedupMultiIndex); - self->ref_count = 1; - self->idx_entries = g_hash_table_new ((GHashFunc) _dict_idx_entries_hash, (GEqualFunc) _dict_idx_entries_equal); - self->idx_objs = g_hash_table_new ((GHashFunc) _dict_idx_objs_hash, (GEqualFunc) _dict_idx_objs_equal); - return self; + NMDedupMultiIndex *self; + + self = g_slice_new0(NMDedupMultiIndex); + self->ref_count = 1; + self->idx_entries = + g_hash_table_new((GHashFunc) _dict_idx_entries_hash, (GEqualFunc) _dict_idx_entries_equal); + self->idx_objs = + g_hash_table_new((GHashFunc) _dict_idx_objs_hash, (GEqualFunc) _dict_idx_objs_equal); + return self; } NMDedupMultiIndex * -nm_dedup_multi_index_ref (NMDedupMultiIndex *self) +nm_dedup_multi_index_ref(NMDedupMultiIndex *self) { - g_return_val_if_fail (self, NULL); - g_return_val_if_fail (self->ref_count > 0, NULL); + g_return_val_if_fail(self, NULL); + g_return_val_if_fail(self->ref_count > 0, NULL); - self->ref_count++; - return self; + self->ref_count++; + return self; } NMDedupMultiIndex * -nm_dedup_multi_index_unref (NMDedupMultiIndex *self) +nm_dedup_multi_index_unref(NMDedupMultiIndex *self) { - GHashTableIter iter; - const NMDedupMultiIdxType *idx_type; - NMDedupMultiEntry *entry; - const NMDedupMultiObj *obj; + GHashTableIter iter; + const NMDedupMultiIdxType *idx_type; + NMDedupMultiEntry * entry; + const NMDedupMultiObj * obj; - g_return_val_if_fail (self, NULL); - g_return_val_if_fail (self->ref_count > 0, NULL); + g_return_val_if_fail(self, NULL); + g_return_val_if_fail(self->ref_count > 0, NULL); - if (--self->ref_count > 0) - return NULL; + if (--self->ref_count > 0) + return NULL; more: - g_hash_table_iter_init (&iter, self->idx_entries); - while (g_hash_table_iter_next (&iter, (gpointer *) &entry, NULL)) { - if (entry->is_head) - idx_type = ((NMDedupMultiHeadEntry *) entry)->idx_type; - else - idx_type = entry->head->idx_type; - _remove_idx_entry (self, (NMDedupMultiIdxType *) idx_type, TRUE, FALSE); - goto more; - } - - nm_assert (g_hash_table_size (self->idx_entries) == 0); - - g_hash_table_iter_init (&iter, self->idx_objs); - while (g_hash_table_iter_next (&iter, (gpointer *) &obj, NULL)) { - nm_assert (obj->_multi_idx == self); - ((NMDedupMultiObj * )obj)->_multi_idx = NULL; - } - g_hash_table_remove_all (self->idx_objs); - - g_hash_table_unref (self->idx_entries); - g_hash_table_unref (self->idx_objs); - - g_slice_free (NMDedupMultiIndex, self); - return NULL; + g_hash_table_iter_init(&iter, self->idx_entries); + while (g_hash_table_iter_next(&iter, (gpointer *) &entry, NULL)) { + if (entry->is_head) + idx_type = ((NMDedupMultiHeadEntry *) entry)->idx_type; + else + idx_type = entry->head->idx_type; + _remove_idx_entry(self, (NMDedupMultiIdxType *) idx_type, TRUE, FALSE); + goto more; + } + + nm_assert(g_hash_table_size(self->idx_entries) == 0); + + g_hash_table_iter_init(&iter, self->idx_objs); + while (g_hash_table_iter_next(&iter, (gpointer *) &obj, NULL)) { + nm_assert(obj->_multi_idx == self); + ((NMDedupMultiObj *) obj)->_multi_idx = NULL; + } + g_hash_table_remove_all(self->idx_objs); + + g_hash_table_unref(self->idx_entries); + g_hash_table_unref(self->idx_objs); + + g_slice_free(NMDedupMultiIndex, self); + return NULL; } |