all: extend hash functions with an NMHashState argument
We often want to cascade hashing, meaning, to combine the outcome of various hash functions in a larger hash. Instead of having each hash function return a guint hash value, accept a hash state argument. This saves the overhead of initializing and completing the intermediate hash states. It also avoids loosing entropy when we reduce the larger hash state into the intermediate guint hash value.
This commit is contained in:
@@ -55,9 +55,9 @@ ASSERT_idx_type (const NMDedupMultiIdxType *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);
|
||||
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 == !!idx_type->klass->idx_obj_partition_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
|
||||
}
|
||||
@@ -181,13 +181,13 @@ _dict_idx_entries_hash (const NMDedupMultiEntry *entry)
|
||||
_entry_unpack (entry, &idx_type, &obj, &lookup_head);
|
||||
|
||||
nm_hash_init (&h, 1914869417u);
|
||||
if (idx_type->klass->idx_obj_partition_hash) {
|
||||
if (idx_type->klass->idx_obj_partition_hash_update) {
|
||||
nm_assert (obj);
|
||||
nm_hash_update_val (&h, idx_type->klass->idx_obj_partition_hash (idx_type, obj));
|
||||
idx_type->klass->idx_obj_partition_hash_update (idx_type, obj, &h);
|
||||
}
|
||||
|
||||
if (!lookup_head)
|
||||
nm_hash_update_val (&h, idx_type->klass->idx_obj_id_hash (idx_type, obj));
|
||||
idx_type->klass->idx_obj_id_hash_update (idx_type, obj, &h);
|
||||
|
||||
nm_hash_update_val (&h, idx_type);
|
||||
return nm_hash_complete (&h);
|
||||
@@ -797,7 +797,11 @@ nm_dedup_multi_index_dirty_remove_idx (NMDedupMultiIndex *self,
|
||||
static guint
|
||||
_dict_idx_objs_hash (const NMDedupMultiObj *obj)
|
||||
{
|
||||
return obj->klass->obj_full_hash (obj);
|
||||
NMHashState h;
|
||||
|
||||
nm_hash_init (&h, 1748638583u);
|
||||
obj->klass->obj_full_hash_update (obj, &h);
|
||||
return nm_hash_complete (&h);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NMHashState;
|
||||
|
||||
typedef struct _NMDedupMultiObj NMDedupMultiObj;
|
||||
typedef struct _NMDedupMultiObjClass NMDedupMultiObjClass;
|
||||
typedef struct _NMDedupMultiIdxType NMDedupMultiIdxType;
|
||||
@@ -69,9 +71,10 @@ struct _NMDedupMultiObjClass {
|
||||
|
||||
void (*obj_destroy) (NMDedupMultiObj *obj);
|
||||
|
||||
/* the NMDedupMultiObj can be deduplicated. For that the obj_full_hash()
|
||||
/* the NMDedupMultiObj can be deduplicated. For that the obj_full_hash_update()
|
||||
* and obj_full_equal() compare *all* fields of the object, even minor ones. */
|
||||
guint (*obj_full_hash) (const NMDedupMultiObj *obj);
|
||||
void (*obj_full_hash_update) (const NMDedupMultiObj *obj,
|
||||
struct _NMHashState *h);
|
||||
gboolean (*obj_full_equal) (const NMDedupMultiObj *obj_a,
|
||||
const NMDedupMultiObj *obj_b);
|
||||
};
|
||||
@@ -152,8 +155,9 @@ void nm_dedup_multi_idx_type_init (NMDedupMultiIdxType *idx_type,
|
||||
struct _NMDedupMultiIdxTypeClass {
|
||||
NMObjBaseClass parent;
|
||||
|
||||
guint (*idx_obj_id_hash) (const NMDedupMultiIdxType *idx_type,
|
||||
const NMDedupMultiObj *obj);
|
||||
void (*idx_obj_id_hash_update) (const NMDedupMultiIdxType *idx_type,
|
||||
const NMDedupMultiObj *obj,
|
||||
struct _NMHashState *h);
|
||||
gboolean (*idx_obj_id_equal) (const NMDedupMultiIdxType *idx_type,
|
||||
const NMDedupMultiObj *obj_a,
|
||||
const NMDedupMultiObj *obj_b);
|
||||
@@ -167,8 +171,9 @@ struct _NMDedupMultiIdxTypeClass {
|
||||
* object is not partitionable, it is never added to the NMDedupMultiIndex. */
|
||||
gboolean (*idx_obj_partitionable) (const NMDedupMultiIdxType *idx_type,
|
||||
const NMDedupMultiObj *obj);
|
||||
guint (*idx_obj_partition_hash) (const NMDedupMultiIdxType *idx_type,
|
||||
const NMDedupMultiObj *obj);
|
||||
void (*idx_obj_partition_hash_update) (const NMDedupMultiIdxType *idx_type,
|
||||
const NMDedupMultiObj *obj,
|
||||
struct _NMHashState *h);
|
||||
gboolean (*idx_obj_partition_equal) (const NMDedupMultiIdxType *idx_type,
|
||||
const NMDedupMultiObj *obj_a,
|
||||
const NMDedupMultiObj *obj_b);
|
||||
|
Reference in New Issue
Block a user