summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNasser Grainawi <nasser.grainawi@linaro.org>2023-08-03 17:20:14 -0600
committerNasser Grainawi <nasser.grainawi@linaro.org>2023-08-21 13:18:58 +0000
commitcc7773e0e57410d0a8282d272dc9369491a7b6b2 (patch)
treeca09bf68e3a43cc0abcfb312c22628b6444f893f
parent96f95621d0b90b906e25828fc1a2f2dcbaec6f2b (diff)
TagSet: encapsulate reachability propagation
The TagSet class is challenging to understand, but we can start making it easier and safer to edit by encapsulating some of the logic into the smaller helper classes defined in the same file. This commit moves the logic to walk a commit's ancestors and propagate the commit's reachability information to those ancestors into the TagCommit class. Change-Id: I6333a288dba287ea46162e6d76e066418a8c71d6 Release-Notes: skip
-rw-r--r--java/com/google/gerrit/server/git/TagSet.java68
1 files changed, 39 insertions, 29 deletions
diff --git a/java/com/google/gerrit/server/git/TagSet.java b/java/com/google/gerrit/server/git/TagSet.java
index c54435b66d..bffc479c4f 100644
--- a/java/com/google/gerrit/server/git/TagSet.java
+++ b/java/com/google/gerrit/server/git/TagSet.java
@@ -233,37 +233,10 @@ class TagSet {
}
}
- // Traverse the complete history. Copy any flags from a commit to all of its ancestors. Do not
- // maintain a reference to the flags on non-tag commits after copying their flags to their
- // ancestors. The flag copying automatically updates any Tag object as the TagCommit and the
- // stored Tag object share the same underlying RoaringBitmap.
+ // Traverse the complete history and propagate reachability to parents.
TagCommit c;
while ((c = (TagCommit) rw.next()) != null) {
- RoaringBitmap mine = c.refFlags;
- if (mine != null) {
- boolean canMoveBitmap = false;
- if (!c.has(isTag)) {
- c.refFlags = null;
- canMoveBitmap = true;
- }
- int pCnt = c.getParentCount();
- for (int pIdx = 0; pIdx < pCnt; pIdx++) {
- TagCommit commit = (TagCommit) c.getParent(pIdx);
- RoaringBitmap parentFlags = commit.refFlags;
- if (parentFlags == null) {
- if (canMoveBitmap) {
- // Move non-tag commit's bitmap reference to their first parent with null refFlags
- // in order to reduce cloning overhead
- commit.refFlags = mine;
- canMoveBitmap = false;
- } else {
- commit.refFlags = mine.clone();
- }
- } else {
- parentFlags.or(mine);
- }
- }
- }
+ c.propagateReachabilityToParents(isTag);
}
} catch (IOException e) {
logger.atWarning().withCause(e).log("Error building tags for repository %s", projectName);
@@ -528,5 +501,42 @@ class TagSet {
TagCommit(AnyObjectId id) {
super(id);
}
+
+ /**
+ * Copy any flags from this commit to all of its ancestors.
+ *
+ * <p>Do not maintain a reference to the flags on non-tag commits after copying their flags to
+ * their ancestors. The flag copying automatically updates any Tag object as the TagCommit and
+ * the stored Tag object share the same underlying RoaringBitmap.
+ *
+ * @param isTag {@code RevFlag} indicating if this TagCommit is a tag
+ */
+ void propagateReachabilityToParents(RevFlag isTag) {
+ RoaringBitmap mine = refFlags;
+ if (mine != null) {
+ boolean canMoveBitmap = false;
+ if (!has(isTag)) {
+ refFlags = null;
+ canMoveBitmap = true;
+ }
+ int pCnt = getParentCount();
+ for (int pIdx = 0; pIdx < pCnt; pIdx++) {
+ TagCommit commit = (TagCommit) getParent(pIdx);
+ RoaringBitmap parentFlags = commit.refFlags;
+ if (parentFlags == null) {
+ if (canMoveBitmap) {
+ // This commit is not itself a Tag, so in order to reduce cloning overhead, migrate
+ // its refFlags object to its first parent with null refFlags
+ commit.refFlags = mine;
+ canMoveBitmap = false;
+ } else {
+ commit.refFlags = mine.clone();
+ }
+ } else {
+ parentFlags.or(mine);
+ }
+ }
+ }
+ }
}
}