Bug 17941 avoid scanning the full cartesian product
authorFrancesco Rivetti <oha@oha.it>
Tue, 14 Feb 2017 10:13:51 +0000 (11:13 +0100)
committerKyle M Hall <kyle@bywatersolutions.com>
Fri, 3 Mar 2017 16:50:26 +0000 (16:50 +0000)
when a item match a borrower, there is no point in checking the
other borrowers

Signed-off-by: Mark Tompsett <mtompset@hotmail.com>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
C4/Circulation.pm

index e2cd626..b6ca23d 100644 (file)
@@ -2677,24 +2677,23 @@ sub CanBookBeRenewed {
             # can be filled with available items. We can get the union of the sets simply
             # by pushing all the elements onto an array and removing the duplicates.
             my @reservable;
-            foreach my $b (@borrowernumbers) {
-                my ($borr) = C4::Members::GetMember( borrowernumber => $b);
-                foreach my $i (@itemnumbers) {
-                    my $item = GetItem($i);
-                    if (  !IsItemOnHoldAndFound($i)
-                        && IsAvailableForItemLevelRequest( $item, $borr )
-                        && CanItemBeReserved( $b, $i ) )
-                    {
-                        push( @reservable, $i );
+            my %borrowers;
+            ITEM: foreach my $i (@itemnumbers) {
+                my $item = GetItem($i);
+                next if IsItemOnHoldAndFound($i);
+                for my $b (@borrowernumbers) {
+                    my $borr = $borrowers{$b}//= C4::Members::GetMember(borrowernumber => $b);
+                    next unless IsAvailableForItemLevelRequest($item, $borr);
+                    next unless CanItemBeReserved($b,$i);
+
+                    push @reservable, $i;
+                    if (@reservable >= @borrowernumbers) {
+                        $resfound = 0;
+                        last ITEM;
                     }
+                    last;
                 }
             }
-
-            @reservable = uniq(@reservable);
-
-            if ( @reservable >= @borrowernumbers ) {
-                $resfound = 0;
-            }
         }
     }
     return ( 0, "on_reserve" ) if $resfound;    # '' when no hold was found