Skip to content

Commit 984b4a6

Browse files
committed
Simplify and fix deleteLast and shift
1 parent 2beafa5 commit 984b4a6

File tree

1 file changed

+25
-56
lines changed

1 file changed

+25
-56
lines changed

src/main/java/org/truffleruby/core/hash/library/CompactHashStore.java

Lines changed: 25 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -222,37 +222,37 @@ Object delete(RubyHash hash, Object key,
222222
@ExportMessage
223223
Object deleteLast(RubyHash hash, Object key,
224224
@Cached @Shared HashingNodes.ToHash hashFunction,
225-
@Cached @Shared GetHashPosForKeyAtKvPosNode getHashPos,
225+
@Cached @Shared GetIndexPosFromKeyPosNode getIndexPosFromKeyPosNode,
226226
@Cached @Exclusive InlinedLoopConditionProfile nonNullKeyNotYetFound,
227227
@Bind("$node") Node node) {
228228
assert hash.size > 0;
229-
int lastKeyPos = firstNonNullKeyPosFromEnd(nonNullKeyNotYetFound, node);
230-
Object lastKey = kvStore[lastKeyPos];
229+
int keyPos = firstNonNullKeyPosFromEnd(nonNullKeyNotYetFound, node);
230+
Object lastKey = kvStore[keyPos];
231231
if (key != lastKey) {
232232
CompilerDirectives.transferToInterpreterAndInvalidate();
233233
throw CompilerDirectives
234234
.shouldNotReachHere("The last key was not " + key + " as expected but was " + lastKey);
235235
}
236236

237237
int keyHash = hashFunction.execute(key, hash.compareByIdentity);
238-
int indexPos = getHashPos.execute(keyHash, lastKeyPos, index);
238+
int indexPos = getIndexPosFromKeyPosNode.execute(keyHash, keyPos, index);
239239

240-
return deleteKvAndGetV(hash, indexPos, lastKeyPos);
240+
return deleteKvAndGetV(hash, indexPos, keyPos);
241241
}
242242

243243
@ExportMessage
244244
RubyArray shift(RubyHash hash,
245245
@Cached @Shared HashingNodes.ToHash hashFunction,
246-
@Cached @Shared GetHashPosForKeyAtKvPosNode getHashPos,
246+
@Cached @Shared GetIndexPosFromKeyPosNode getIndexPosFromKeyPosNode,
247247
@Cached @Exclusive InlinedLoopConditionProfile nonNullKeyNotYetFound,
248248
@Bind("$node") Node node) {
249249
assert hash.size > 0;
250-
int firstKeyPos = firstNonNullKeyPosFromBeginning(nonNullKeyNotYetFound, node);
250+
int keyPos = firstNonNullKeyPosFromBeginning(nonNullKeyNotYetFound, node);
251251

252-
Object key = kvStore[firstKeyPos];
252+
Object key = kvStore[keyPos];
253253
int keyHash = hashFunction.execute(key, hash.compareByIdentity);
254-
int indexPos = getHashPos.execute(keyHash, firstKeyPos, index);
255-
Object val = deleteKvAndGetV(hash, indexPos, firstKeyPos);
254+
int indexPos = getIndexPosFromKeyPosNode.execute(keyHash, keyPos, index);
255+
Object val = deleteKvAndGetV(hash, indexPos, keyPos);
256256

257257
return ArrayHelpers.createArray(RubyContext.get(node), RubyLanguage.get(node), new Object[]{ key, val });
258258
}
@@ -503,59 +503,28 @@ int findIndexPos(Object key, int hash, boolean compareByIdentity, int[] index, O
503503
}
504504

505505
@GenerateUncached
506-
abstract static class GetHashNextPosInIndexNode extends RubyBaseNode {
507-
508-
public abstract int execute(int startingFromPos, int hash, int[] index, int stop);
509-
510-
@Specialization
511-
int getHashNextPos(int startingFromPos, int hash, int[] index, int stop,
512-
@Cached @Exclusive InlinedConditionProfile slotIsUnused,
513-
@Cached @Exclusive InlinedConditionProfile hashFound,
514-
@Cached @Exclusive InlinedLoopConditionProfile stopNotYetReached,
515-
@Bind("$node") Node node) {
516-
int nextHashPos = startingFromPos;
517-
518-
do {
519-
if (slotIsUnused.profile(node, index[nextHashPos + 1] == INDEX_SLOT_UNUSED)) {
520-
return HASH_NOT_FOUND;
521-
}
522-
523-
if (hashFound.profile(node, index[nextHashPos] == hash)) {
524-
return nextHashPos;
525-
}
526-
527-
nextHashPos = incrementIndexPos(nextHashPos, index.length);
528-
} while (stopNotYetReached.profile(node, nextHashPos != stop));
529-
530-
return HASH_NOT_FOUND;
531-
}
532-
}
533-
534-
@GenerateUncached
535-
abstract static class GetHashPosForKeyAtKvPosNode extends RubyBaseNode {
506+
abstract static class GetIndexPosFromKeyPosNode extends RubyBaseNode {
536507

537-
public abstract int execute(int hash, int kvPos, int[] index);
508+
public abstract int execute(int hash, int keyPos, int[] index);
538509

539510
@Specialization
540-
int getHashPos(int hash, int kvPos, int[] index,
541-
@Cached @Exclusive InlinedConditionProfile keyFound,
542-
@Cached @Exclusive InlinedLoopConditionProfile keyHashFound,
543-
@Cached GetHashNextPosInIndexNode getNextHashPos,
511+
int findIndexPos(int hash, int keyPos, int[] index,
512+
@Cached @Exclusive InlinedConditionProfile unused,
513+
@Cached @Exclusive InlinedConditionProfile found,
544514
@Bind("$node") Node node) {
515+
int valuePosToSearch = keyPos + 1;
545516
int startPos = indexPosFromHashCode(hash, index.length);
546-
int nextPos = getNextHashPos.execute(startPos, hash, index, startPos);
547-
548-
while (keyHashFound.profile(node, nextPos != HASH_NOT_FOUND)) {
549-
int kvPosition = indexPosToKeyPos(index, nextPos);
550-
551-
if (keyFound.profile(node, kvPos == kvPosition)) {
552-
return nextPos;
517+
int indexPos = startPos;
518+
while (true) {
519+
int valuePos = indexPosToValuePos(index, indexPos);
520+
if (unused.profile(node, valuePos == INDEX_SLOT_UNUSED)) {
521+
// Keep going, this means the hash of the key changed
522+
} else if (found.profile(node, valuePos == valuePosToSearch)) {
523+
return indexPos;
553524
}
554-
555-
int next = incrementIndexPos(nextPos, index.length);
556-
nextPos = getNextHashPos.execute(next, hash, index, startPos);
525+
indexPos = incrementIndexPos(indexPos, index.length);
526+
assert indexPos != startPos;
557527
}
558-
return HASH_NOT_FOUND;
559528
}
560529
}
561530

0 commit comments

Comments
 (0)