Skip to content

Commit

Permalink
Slightly change semantics of (-) on QuantHashes
Browse files Browse the repository at this point in the history
If the left-hand side of the (-) (also known as ∖) is mutable, then the
resulting QuantHash object will also be mutable.  If it is immutable,
it will stay immutable as before.

This should allow us to better optimize things like:

    my %h is BagHash = a => 42, b => 666;
    my %i is Bag = b => 13, c => 22;
    %h (-)= %i;

This requires quite a few spectest changes.  But all of these tests where
added after Christmas, so we should be good in that respect.

Instigated by https://stackoverflow.com/questions/51580534/does-baggy-add-work-on-mixhash-weights
  • Loading branch information
lizmat committed Jul 31, 2018
1 parent 3a6c119 commit b826a07
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 22 deletions.
14 changes: 7 additions & 7 deletions src/core/Rakudo/QuantHash.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -955,19 +955,19 @@ my class Rakudo::QuantHash {
(my $araw := a.RAW-HASH) && nqp::elems($araw),
nqp::if(
(my $braw := b.RAW-HASH) && nqp::elems($braw),
nqp::create(Bag).SET-SELF(
nqp::create(a.WHAT).SET-SELF(
nqp::if(
nqp::istype(b,Setty),
self.SUB-SETTY-FROM-BAG($araw, $braw),
self.SUB-BAGGY-FROM-BAG($araw, $braw)
)
),
a.Bag
a
),
nqp::if(
nqp::istype(b,Failure),
b.throw,
bag()
a
)
)
}
Expand Down Expand Up @@ -1600,10 +1600,10 @@ my class Rakudo::QuantHash {
(my $araw := a.RAW-HASH) && nqp::elems($araw),
nqp::if(
(my $braw := b.RAW-HASH) && nqp::elems($braw),
nqp::create(Mix).SET-SELF(
nqp::create(a.WHAT).SET-SELF(
self.SUB-QUANTHASH-FROM-MIX($araw, $braw, nqp::istype(b,Setty)),
),
a.Mix
a
),
nqp::if(
nqp::istype(b,Failure),
Expand All @@ -1626,9 +1626,9 @@ my class Rakudo::QuantHash {
)
)
),
nqp::create(Mix).SET-SELF($elems)
nqp::create(a.WHAT).SET-SELF($elems)
),
mix()
a
)
)
)
Expand Down
40 changes: 25 additions & 15 deletions src/core/set_difference.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,26 @@ multi sub infix:<(-)>(Any $a) { $a.Set } # also for Iterable/Map

multi sub infix:<(-)>(Setty:D $a, Setty:D $b) {
nqp::if(
(my $araw := $a.RAW-HASH) && nqp::elems($araw),
nqp::if( # elems in $a
(my $braw := $b.RAW-HASH) && nqp::elems($braw),
nqp::create(Set).SET-SELF( # both have elems
Rakudo::QuantHash.SUB-SET-FROM-SET($araw, $braw)
),
$a.Set, # no elems in $b
(my $araw := $a.RAW-HASH) && nqp::elems($araw)
&& (my $braw := $b.RAW-HASH) && nqp::elems($braw),
nqp::create($a.Setty).SET-SELF( # both have elems
Rakudo::QuantHash.SUB-SET-FROM-SET($araw, $braw)
),
set() # no elems in $a
$a # no elems in $a or $b
)
}
multi sub infix:<(-)>(Setty:D $a, Map:D $b) {
nqp::if(
(my $araw := $a.RAW-HASH) && nqp::elems($araw),
nqp::create(Set).SET-SELF( # elems in $a
nqp::create($a.Setty).SET-SELF( # elems in $a
nqp::if(
(my $braw := nqp::getattr(nqp::decont($b),Map,'$!storage'))
&& nqp::elems($braw),
Rakudo::QuantHash.SUB-MAP-FROM-SET($araw, $b), # both have elems
nqp::clone($araw) # no elems in $b
)
),
set() # no elems in $a
$a # no elems in $a
)
}
multi sub infix:<(-)>(Setty:D $a, Iterable:D $b) {
Expand All @@ -43,10 +40,10 @@ multi sub infix:<(-)>(Setty:D $a, Iterable:D $b) {
Failure.new(X::Cannot::Lazy.new(:action('difference'),:what<set>)),
nqp::if(
(my $raw := $a.RAW-HASH) && nqp::elems($raw),
nqp::create(Set).SET-SELF(
nqp::create($a.Setty).SET-SELF( # elems in $b
Rakudo::QuantHash.SUB-PAIRS-FROM-SET($raw, $iterator)
),
set()
$a # no elems in $b
)
)
}
Expand All @@ -57,7 +54,7 @@ multi sub infix:<(-)>(Mixy:D $a, QuantHash:D $b) {
Rakudo::QuantHash.DIFFERENCE-MIXY-QUANTHASH($a, $b)
}
multi sub infix:<(-)>(QuantHash:D $a, Mixy:D $b) {
Rakudo::QuantHash.DIFFERENCE-MIXY-QUANTHASH($a.Mix, $b)
Rakudo::QuantHash.DIFFERENCE-MIXY-QUANTHASH($a.Mixy, $b)
}
multi sub infix:<(-)>(Mixy:D $a, Map:D $b) {
Rakudo::QuantHash.DIFFERENCE-MIXY-QUANTHASH($a, $b.Set)
Expand All @@ -69,7 +66,7 @@ multi sub infix:<(-)>(Any:D $a, Mixy:D $b) {
Rakudo::QuantHash.DIFFERENCE-MIXY-QUANTHASH($a.Mix, $b)
}
multi sub infix:<(-)>(Baggy:D $a, Mixy:D $b) { # needed as tie-breaker
Rakudo::QuantHash.DIFFERENCE-MIXY-QUANTHASH($a.Mix, $b)
Rakudo::QuantHash.DIFFERENCE-MIXY-QUANTHASH($a.Mixy, $b)
}
multi sub infix:<(-)>(Baggy:D $a, Baggy:D $b) { # needed as tie-breaker
Rakudo::QuantHash.DIFFERENCE-BAGGY-QUANTHASH($a, $b)
Expand All @@ -78,7 +75,7 @@ multi sub infix:<(-)>(Baggy:D $a, QuantHash:D $b) {
Rakudo::QuantHash.DIFFERENCE-BAGGY-QUANTHASH($a, $b)
}
multi sub infix:<(-)>(QuantHash:D $a, Baggy:D $b) {
Rakudo::QuantHash.DIFFERENCE-BAGGY-QUANTHASH($a.Bag, $b)
Rakudo::QuantHash.DIFFERENCE-BAGGY-QUANTHASH($a.Baggy, $b)
}
multi sub infix:<(-)>(Baggy:D $a, Map:D $b) {
Rakudo::QuantHash.DIFFERENCE-BAGGY-QUANTHASH($a, $b.Bag)
Expand Down Expand Up @@ -133,6 +130,11 @@ multi sub infix:<(-)>(**@p) {
Mix,
nqp::if(nqp::istype($p,Baggy),Bag,Set)
)),
(my $mutable :=
nqp::eqaddr($p.WHAT,MixHash)
|| nqp::eqaddr($p.WHAT,BagHash)
|| nqp::eqaddr($p.WHAT,SetHash)
),
(my $elems := nqp::if(
nqp::istype($p,Baggy),
nqp::if( # already have a Baggy, clone
Expand Down Expand Up @@ -215,6 +217,14 @@ multi sub infix:<(-)>(**@p) {
)
)
),
nqp::if( # set to mutable if so started
$mutable,
$type := nqp::if(
nqp::eqaddr($type,Mix),
MixHash,
nqp::if(nqp::eqaddr($type,Bag),BagHash,SetHash)
)
),
nqp::create($type).SET-SELF($elems)
)
)
Expand Down

0 comments on commit b826a07

Please sign in to comment.