Skip to content

Commit 2a0d922

Browse files
author
Nicolas Laurent
committed
[GR-21660] Fix rope hash calculation.
PullRequest: truffleruby/2076
2 parents c2f5cc7 + 3887a3b commit 2a0d922

File tree

2 files changed

+17
-29
lines changed

2 files changed

+17
-29
lines changed

spec/truffle/ropes/complex_structure_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
[(('ab'*4)+'0123456789')[1..-2]+'cd', 'bababab012345678cd']
2121
].each_with_index do |(a, b), i|
2222
it format('%d: %s', i, b) do
23+
a.hash.should == b.hash
2324
a.should == b
2425
end
2526
end

src/main/java/org/truffleruby/core/rope/RopeOperations.java

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -544,20 +544,18 @@ class Params {
544544
final int offset;
545545
final int length;
546546
final boolean readResult;
547-
final int repeatCount;
548547

549-
Params(Rope rope, int startingHashCode, int offset, int length, boolean readResult, int repeatCount) {
548+
Params(Rope rope, int startingHashCode, int offset, int length, boolean readResult) {
550549
this.rope = rope;
551550
this.startingHashCode = startingHashCode;
552551
this.offset = offset;
553552
this.length = length;
554553
this.readResult = readResult;
555-
this.repeatCount = repeatCount;
556554
}
557555
}
558556

559557
final Deque<Params> workStack = new ArrayDeque<>();
560-
workStack.push(new Params(rope, startingHashCode, offset, length, false, -1));
558+
workStack.push(new Params(rope, startingHashCode, offset, length, false));
561559
int resultHash = 0;
562560

563561
while (!workStack.isEmpty()) {
@@ -572,14 +570,9 @@ class Params {
572570
resultHash = Hashing.stringHash(bytes, startingHashCode, offset, length);
573571
} else if (rope instanceof SubstringRope) {
574572
final SubstringRope substringRope = (SubstringRope) rope;
575-
workStack.push(
576-
new Params(
577-
substringRope.getChild(),
578-
startingHashCode,
579-
offset + substringRope.getByteOffset(),
580-
length,
581-
false,
582-
-1));
573+
final Rope child = substringRope.getChild();
574+
final int newOffset = offset + substringRope.getByteOffset();
575+
workStack.push(new Params(child, startingHashCode, newOffset, length, false));
583576
} else if (rope instanceof ConcatRope) {
584577
final ConcatRope concatRope = (ConcatRope) rope;
585578
final Rope left = concatRope.getLeft();
@@ -588,41 +581,35 @@ class Params {
588581

589582
if (offset >= leftLength) {
590583
// range fully contained in right child
591-
workStack.push(new Params(right, startingHashCode, offset - leftLength, length, false, -1));
584+
workStack.push(new Params(right, startingHashCode, offset - leftLength, length, false));
592585
} else if (offset + length <= leftLength) {
593586
// range fully contained in left child
594-
workStack.push(new Params(left, startingHashCode, offset, length, false, -1));
587+
workStack.push(new Params(left, startingHashCode, offset, length, false));
595588
} else {
596589
final int coveredByLeft = leftLength - offset;
597590
// push right node first, starting hash is the result from the left node
598-
workStack.push(new Params(right, 0, 0, length - coveredByLeft, true, -1));
599-
workStack.push(new Params(left, startingHashCode, offset, coveredByLeft, false, -1));
591+
workStack.push(new Params(right, 0, 0, length - coveredByLeft, true));
592+
workStack.push(new Params(left, startingHashCode, offset, coveredByLeft, false));
600593
}
601594
} else if (rope instanceof RepeatingRope) {
602595
final RepeatingRope repeatingRope = (RepeatingRope) rope;
603596
final Rope child = repeatingRope.getChild();
604597
final int patternLength = child.byteLength();
605598

606-
int count = params.repeatCount;
607-
assert count != 0;
608-
if (count < 0) {
609-
offset %= patternLength; // the offset is always 0 when count > 0
610-
count = computeLoopCount(offset, repeatingRope.getTimes(), length, patternLength);
611-
}
612-
613-
if (count > 1) {
599+
offset %= patternLength;
600+
if (length > patternLength - offset) { // bytes to hash > bytes available in current repetition of child
614601
// loop - 1 iteration, reset offset to 0, starting hash is the result from previous iteration
615-
workStack.push(new Params(rope, 0, 0, length - patternLength, true, count - 1));
602+
workStack.push(new Params(rope, 0, 0, length - (patternLength - offset), true));
603+
length = patternLength - offset;
616604
}
605+
617606
// one iteration
618-
final int bytesToHashThisPass = length + offset > patternLength
619-
? patternLength - offset
620-
: length;
621-
workStack.push(new Params(child, startingHashCode, offset, bytesToHashThisPass, false, -1));
607+
workStack.push(new Params(child, startingHashCode, offset, length, false));
622608
} else {
623609
resultHash = Hashing.stringHash(rope.getBytes(), startingHashCode, offset, length);
624610
}
625611
}
612+
626613
return resultHash;
627614
}
628615

0 commit comments

Comments
 (0)