Add a new package PVE::HashTools to provide helpers for common operations done on hashes.
These initial helper subroutines implement basic set operations done on hash sets, i.e. hashes with elements set to a true value, e.g. 1. Signed-off-by: Daniel Kral <d.k...@proxmox.com> --- changes since v1: - moved from pve-ha-manager PVE::HA::Tools to pve-common as PVE::HashTools - improved implementations - added documentation src/Makefile | 1 + src/PVE/HashTools.pm | 101 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 src/PVE/HashTools.pm diff --git a/src/Makefile b/src/Makefile index 2d8bdc4..ee114d1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -17,6 +17,7 @@ LIB_SOURCES = \ Daemon.pm \ Exception.pm \ Format.pm \ + HashTools.pm \ INotify.pm \ JSONSchema.pm \ Job/Registry.pm \ diff --git a/src/PVE/HashTools.pm b/src/PVE/HashTools.pm new file mode 100644 index 0000000..463fe7c --- /dev/null +++ b/src/PVE/HashTools.pm @@ -0,0 +1,101 @@ +package PVE::HashTools; + +use strict; +use warnings; + +=head1 NAME + +PVE::HashTools - Helpers for Hashes + +=head1 DESCRIPTION + +This packages provides helpers for common operations on hashes. + +Even though these operations' implementation are often one-liners, they are +meant to improve code readability by stating a operation name instead of the +more verbose implementation. + +=cut + +=head1 FUNCTIONS + +=cut + +=head3 set_intersect($hash1, $hash2) + +Returns a hash set of the intersection of the hash sets C<$hash1> and +C<$hash2>, i.e. the elements that are both in C<$hash1> and C<$hash2>. + +The hashes C<$hash1> and C<$hash2> are expected to be hash sets, i.e. +key-value pairs are always set to C<1> or another truthy value. + +=cut + +sub set_intersect : prototype($$) { + my ($hash1, $hash2) = @_; + + my $result = { map { $hash1->{$_} && $hash2->{$_} ? ($_ => 1) : () } keys %$hash1 }; + + return $result; +} + +=head3 set_difference($hash1, $hash2) + +Returns a hash set of the set difference between the hash sets C<$hash1> and +C<$hash2>, i.e. the elements that are in C<$hash1> without the elements that +are in C<$hash2>. + +The hashes C<$hash1> and C<$hash2> are expected to be hash sets, i.e. +key-value pairs are always set to C<1> or another truthy value. + +=cut + +sub set_difference : prototype($$) { + my ($hash1, $hash2) = @_; + + my $result = { map { $hash2->{$_} ? () : ($_ => 1) } keys %$hash1 }; + + return $result; +} + +=head3 set_union($hash1, $hash2) + +Returns a hash set of the union of the hash sets C<$hash1> and C<$hash2>, i.e. +the elements that are in either C<$hash1> or C<$hash2>. + +The hashes C<$hash1> and C<$hash2> are expected to be hash sets, i.e. +key-value pairs are always set to C<1> or another truthy value. + +=cut + +sub set_union : prototype($$) { + my ($hash1, $hash2) = @_; + + my $result = { map { $_ => 1 } keys %$hash1, keys %$hash2 }; + + return $result; +} + +=head3 sets_are_disjoint($hash1, $hash2) + +Checks whether the two given hash sets C<$hash1> and C<$hash2> are disjoint, +i.e. have no common element in both of them. + +The hashes C<$hash1> and C<$hash2> are expected to be hash sets, i.e. +key-value pairs are always set to C<1> or another truthy value. + +Returns C<1> if they are disjoint, C<0> otherwise. + +=cut + +sub sets_are_disjoint : prototype($$) { + my ($hash1, $hash2) = @_; + + for my $key (keys %$hash1) { + return 0 if $hash2->{$key}; + } + + return 1; +} + +1; -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel