diff --git a/src/util/hash.c b/src/util/hash.c index 665bcce1d5..ff86f163f6 100644 --- a/src/util/hash.c +++ b/src/util/hash.c @@ -663,3 +663,49 @@ virHashKeyValuePairPtr virHashGetItems(virHashTablePtr table, return iter.sortArray; } + +struct virHashEqualData +{ + bool equal; + const virHashTablePtr table2; + virHashValueComparator compar; +}; + +static int virHashEqualSearcher(const void *payload, const void *name, + const void *data) +{ + struct virHashEqualData *vhed = (void *)data; + const void *value; + + value = virHashLookup(vhed->table2, name); + if (!value || + vhed->compar(value, payload) != 0) { + /* key is missing in 2nd table or values are different */ + vhed->equal = false; + /* stop 'iteration' */ + return 1; + } + return 0; +} + +bool virHashEqual(const virHashTablePtr table1, + const virHashTablePtr table2, + virHashValueComparator compar) +{ + struct virHashEqualData data = { + .equal = true, + .table2 = table2, + .compar = compar, + }; + + if (table1 == table2) + return true; + + if (!table1 || !table2 || + virHashSize(table1) != virHashSize(table2)) + return false; + + virHashSearch(table1, virHashEqualSearcher, &data); + + return data.equal; +} diff --git a/src/util/hash.h b/src/util/hash.h index 1ba12b91d3..9da2da5f87 100644 --- a/src/util/hash.h +++ b/src/util/hash.h @@ -153,6 +153,18 @@ typedef int (*virHashKeyComparator)(const virHashKeyValuePairPtr, virHashKeyValuePairPtr virHashGetItems(virHashTablePtr table, virHashKeyComparator compar); +/* + * Compare two tables for equality: the lookup of a key's value in + * both tables must result in an equivalent value. + * The caller must pass in a comparator function for comparing the values + * of two keys. + */ +typedef int (*virHashValueComparator)(const void *value1, const void *value2); +bool virHashEqual(const virHashTablePtr table1, + const virHashTablePtr table2, + virHashValueComparator compar); + + /* * Iterators */