From 048dbf41735175de77f60dc55dba9ae6c8a65317 Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Fri, 17 Oct 2014 14:17:23 -0700 Subject: [PATCH] Add retainOnReset(RevFlag) to RevWalk to simplify reset usage Applications sometimes use a RevFlag instead of a Set to track boolean state bits about objects being processed. However this requires careful use of the resetRetain() methods to avoid an accidental clearing of the RevFlag bits, effectively clearing the Set the application wanted to track. Simplify that use case by offering retainOnReset, a collection of flags that are never cleared by the RevWalk. Change-Id: I4c05b89b1398e4a4f371eac3a5d1d5edddec838f --- .../src/org/eclipse/jgit/revwalk/RevWalk.java | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index 79cc42d17..d19e467c1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -174,6 +174,7 @@ public class RevWalk implements Iterable { private int delayFreeFlags; + private int retainOnReset; int carryFlags = UNINTERESTING; final ArrayList roots; @@ -1092,6 +1093,47 @@ public void carry(final Collection set) { carry(flag); } + /** + * Preserve a RevFlag during all {@code reset} methods. + *

+ * Calling {@code retainOnReset(flag)} avoids needing to pass the flag + * during each {@code resetRetain()} invocation on this instance. + *

+ * Clearing flags marked retainOnReset requires disposing of the flag with + * {@code #disposeFlag(RevFlag)} or disposing of the entire RevWalk by + * {@code #dispose()}. + * + * @param flag + * the flag to retain during all resets. + * @since 3.6 + */ + public final void retainOnReset(RevFlag flag) { + if ((freeFlags & flag.mask) != 0) + throw new IllegalArgumentException(MessageFormat.format(JGitText.get().flagIsDisposed, flag.name)); + if (flag.walker != this) + throw new IllegalArgumentException(MessageFormat.format(JGitText.get().flagNotFromThis, flag.name)); + retainOnReset |= flag.mask; + } + + /** + * Preserve a set of RevFlags during all {@code reset} methods. + *

+ * Calling {@code retainOnReset(set)} avoids needing to pass the flags + * during each {@code resetRetain()} invocation on this instance. + *

+ * Clearing flags marked retainOnReset requires disposing of the flag with + * {@code #disposeFlag(RevFlag)} or disposing of the entire RevWalk by + * {@code #dispose()}. + * + * @param flags + * the flags to retain during all resets. + * @since 3.6 + */ + public final void retainOnReset(Collection flags) { + for (RevFlag f : flags) + retainOnReset(f); + } + /** * Allow a flag to be recycled for a different use. *

@@ -1110,6 +1152,7 @@ public void disposeFlag(final RevFlag flag) { } void freeFlag(final int mask) { + retainOnReset &= ~mask; if (isNotStarted()) { freeFlags |= mask; carryFlags &= ~mask; @@ -1158,6 +1201,9 @@ public final void resetRetain(final RevFlagSet retainFlags) { * Unlike {@link #dispose()} previously acquired RevObject (and RevCommit) * instances are not invalidated. RevFlag instances are not invalidated, but * are removed from all RevObjects. + *

+ * See {@link #retainOnReset(RevFlag)} for an alternative that does not + * require passing the flags during each reset. * * @param retainFlags * application flags that should not be cleared from @@ -1183,7 +1229,7 @@ public final void resetRetain(final RevFlag... retainFlags) { */ protected void reset(int retainFlags) { finishDelayedFreeFlags(); - retainFlags |= PARSED; + retainFlags |= PARSED | retainOnReset; final int clearFlags = ~retainFlags; final FIFORevQueue q = new FIFORevQueue(); @@ -1227,6 +1273,7 @@ public void dispose() { reader.release(); freeFlags = APP_FLAGS; delayFreeFlags = 0; + retainOnReset = 0; carryFlags = UNINTERESTING; objects.clear(); reader.release();