Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Iterify Baggy.pairs/keys/kv/values/antipairs/kxxv
I have two reasons for doing this:
- to make Bag/BagHash/Mix/MixHash faster
- *if* we don't get VM support for object hashes, this code can be
  put in a role and used for a single hash refactoring of object
  hashes in Perl 6

This refactor also exposed two faulty tests for Baggy.kxxv
  • Loading branch information
lizmat committed Oct 4, 2015
1 parent b6247a8 commit d2da732
Showing 1 changed file with 131 additions and 7 deletions.
138 changes: 131 additions & 7 deletions src/core/Baggy.pm
Expand Up @@ -4,14 +4,138 @@ my role Baggy does QuantHash {
submethod BUILD (:%!elems) { }
method default(--> Int) { 0 }

multi method keys(Baggy:D:) { %!elems.values.map( {.key} ) }
multi method kv(Baggy:D:) { %!elems.values.map( {.key, .value} ) }
multi method values(Baggy:D:) { %!elems.values.map( {.value} ) }
multi method pairs(Baggy:D:) { %!elems.values.map: { (.key => .value) } }
multi method antipairs(Baggy:D:) { %!elems.values.map: { (.value => .key) } }
multi method invert(Baggy:D:) { %!elems.values.map: { (.value => .key) } } # NB value can't be listy
multi method pairs(Baggy:D:) {
Seq.new(class :: does MapIterator {
method pull-one() {
if $!hash-iter {
my \tmp = nqp::iterval(nqp::shift($!hash-iter));
Pair.new(tmp.key, tmp.value)
}
else {
IterationEnd
}
}
method push-all($target) {
while $!hash-iter {
my \tmp = nqp::iterval(nqp::shift($!hash-iter));
$target.push(Pair.new(tmp.key, tmp.value));
}
IterationEnd
}
}.new(%!elems))
}
multi method keys(Baggy:D:) {
Seq.new(class :: does MapIterator {
method pull-one() {
$!hash-iter
?? nqp::iterval(nqp::shift($!hash-iter)).key
!! IterationEnd
}
method push-all($target) {
$target.push(nqp::iterval(nqp::shift($!hash-iter)).key)
while $!hash-iter;
IterationEnd
}
}.new(%!elems))
}
multi method kv(Baggy:D:) {
Seq.new(class :: does MapIterator {
has Mu $!value;

method pull-one() is raw {
if $!value.DEFINITE {
my \tmp = $!value;
$!value := Mu;
tmp
}
elsif $!hash-iter {
my \tmp = nqp::iterval(nqp::shift($!hash-iter));
$!value := tmp.value;
tmp.key
}
else {
IterationEnd
}
}
method push-all($target) {
while $!hash-iter {
my \tmp = nqp::iterval(nqp::shift($!hash-iter));
$target.push(tmp.key);
$target.push(tmp.value);
}
IterationEnd
}
}.new(%!elems))
}
multi method values(Baggy:D:) {
Seq.new(class :: does MapIterator {
method pull-one() is raw {
$!hash-iter
?? nqp::iterval(nqp::shift($!hash-iter)).value
!! IterationEnd
}
method push-all($target) {
$target.push(nqp::iterval(nqp::shift($!hash-iter)).value)
while $!hash-iter;
IterationEnd
}
}.new(%!elems))
}
multi method antipairs(Baggy:D:) {
Seq.new(class :: does MapIterator {
method pull-one() {
if $!hash-iter {
my \tmp = nqp::iterval(nqp::shift($!hash-iter));
Pair.new(tmp.value, tmp.key)
}
else {
IterationEnd
}
}
method push-all($target) {
while $!hash-iter {
my \tmp = nqp::iterval(nqp::shift($!hash-iter));
$target.push(Pair.new(tmp.value, tmp.key));
}
IterationEnd
}
}.new(%!elems))
}
method kxxv(Baggy:D:) {
Seq.new(class :: does MapIterator {
has Mu $!key;
has int $!times;

method kxxv(Baggy:D:) { %!elems.values.map( {.key xx .value} ) }
method pull-one() is raw {
if $!times {
$!times = $!times - 1;
$!key
}
elsif $!hash-iter {
my \tmp = nqp::iterval(nqp::shift($!hash-iter));
$!key = tmp.key;
$!times = tmp.value - 1;
$!key
}
else {
IterationEnd
}
}
method push-all($target) {
while $!hash-iter {
my \tmp = nqp::iterval(nqp::shift($!hash-iter));
$!key = tmp.key;
$!times = tmp.value + 1;
$target.push($!key) while $!times = $!times - 1;
}
IterationEnd
}
}.new(%!elems))
}

multi method invert(Baggy:D:) {
%!elems.values.map: { (.value »=>» .key).cache.Slip }
}
method elems(Baggy:D: --> Int) { %!elems.elems }
method total(--> Int) { [+] self.values }
method Bool(Baggy:D:) { %!elems.Bool }
Expand Down

0 comments on commit d2da732

Please sign in to comment.