File Coverage

blib/lib/Data/Multihash.pm
Criterion Covered Total %
statement 12 40 30.0
branch 0 12 0.0
condition n/a
subroutine 4 12 33.3
pod 8 8 100.0
total 24 72 33.3


line stmt bran cond sub pod time code
1             package Data::Multihash;
2 1     1   20744 use 5.006;
  1         4  
  1         47  
3 1     1   12 use strict;
  1         2  
  1         48  
4 1     1   8 use warnings FATAL => 'all';
  1         6  
  1         59  
5 1     1   982 use Set::Object qw(set);
  1         13865  
  1         540  
6              
7             our $VERSION = '0.03';
8              
9             =head1 NAME
10              
11             Data::Multihash - A hash table that supports multiple values per key.
12              
13             =head1 SYNOPSIS
14              
15             use Data::Multihash;
16              
17             my $multihash = Data::Multihash->new();
18             $multihash->insert(key => 'value', key => 'other_value');
19             $multihash->insert(other_key => 'value');
20              
21             print 'There are ' . $multihash->size . ' elements in the multihash.';
22              
23             =head1 DESCRIPTION
24              
25             This module implements a multihash, which maps keys to sets of values.
26             Multihashes are unordered.
27              
28             =head1 CONSTRUCTORS
29              
30             =head2 new()
31              
32             Create a new empty multihash.
33              
34             =cut
35              
36             sub new {
37 0     0 1   bless {};
38             }
39              
40             =head1 INSTANCE METHODS
41              
42             =head2 insert(%pairs)
43              
44             Insert key-value pairs.
45              
46             =cut
47              
48             sub insert {
49 0     0 1   my ($self, %pairs) = @_;
50 0           while (my ($k, $v) = each %pairs) {
51 0 0         $self->{$k} = set() unless $self->{$k};
52 0           $self->{$k}->insert($v);
53             }
54             }
55              
56             =head2 remove_key(@keys), remove_keys(@keys)
57              
58             Remove all given keys and their values.
59              
60             =cut
61              
62             sub remove_key {
63 0     0 1   my $self = shift;
64 0           delete $self->{$_} for @_;
65             }
66              
67             *remove_keys = \&remove_key;
68              
69             =head2 remove_value(@values), remove_values(@values)
70              
71             Remove all given values from the multihash.
72              
73             =cut
74              
75             sub remove_value {
76 0     0 1   my $self = shift;
77 0           for (keys %$self) {
78 0 0         next unless exists $self->{$_};
79 0           my $set = $self->{$_};
80 0           $set->remove(@_);
81 0 0         delete $self->{$_} unless $set->size;
82             }
83             }
84              
85             *remove_values = \&remove_value;
86              
87             =head2 remove_pair(%pairs), remove_pairs(%pairs)
88              
89             Remove all given (key, value) pairs from the multiset.
90              
91             =cut
92              
93             sub remove_pair {
94 0     0 1   my ($self, %pairs) = @_;
95 0           while (my ($k, $v) = each %pairs) {
96 0 0         next unless exists $self->{$k};
97 0           my $set = $self->{$k};
98 0           $set->remove($v);
99 0 0         delete $self->{$k} unless $set->size;
100             }
101             }
102              
103             *remove_pairs = \&remove_pair;
104              
105             =head2 elements($key)
106              
107             Return all elements associated with a key.
108              
109             =cut
110              
111             sub elements {
112 0     0 1   my ($self, $key) = @_;
113 0 0         $self->{$key} || set();
114             }
115              
116             =head2 values
117              
118             Return all values in the multihash as a list.
119              
120             =cut
121              
122             sub values {
123 0     0 1   my $self = shift;
124 0           my @sets = CORE::values %$self;
125 0           map $_->elements, @sets;
126             }
127              
128             =head2 size
129              
130             Return the number of values in the multihash.
131              
132             =cut
133              
134             sub size {
135 0     0 1   my $self = shift;
136 0           my $result = 0;
137 0           $result += $_->size for (CORE::values %$self);
138 0           $result;
139             }
140              
141             =head1 THREAD SAFETY
142              
143             It is not safe to access a single multihash from multiple threads.
144              
145             =head1 LICENSE
146              
147             Copyright (c) 2014, Radek Slupik
148             All rights reserved.
149              
150             Redistribution and use in source and binary forms, with or without modification,
151             are permitted provided that the following conditions are met:
152              
153             =over
154              
155             =item *
156              
157             Redistributions of source code must retain the above copyright notice, this list
158             of conditions and the following disclaimer.
159              
160             =item *
161              
162             Redistributions in binary form must reproduce the above copyright notice, this
163             list of conditions and the following disclaimer in the documentation and/or
164             other materials provided with the distribution.
165              
166             =item *
167              
168             Neither the name of nor the names of its contributors may be used to endorse
169             or promote products derived from this software without specific prior written
170             permission.
171              
172             =back
173              
174             THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
175             ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
176             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
177             DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
178             ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
179             (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
180             LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
181             ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
182             (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
183             SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
184              
185             =cut
186              
187             1;