From d5cc102e7b9b6104a191be0c64017793432bd9dc Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Thu, 19 Dec 2024 15:14:54 -0800 Subject: http.server/BUILD: expose servlet resources as target JGit has moved to jakarta servlet-api, but gerrit is still in the javax version. This is blocking gerrit to update their jgit code. Gerrit can workaround this rebuilding the jar of jgit-servlet but it is complicated to pass-through the resources. Expose the resources of the servlet as a target, to help gerrit build a javax version of the jgit-servlet. Change-Id: Ifd794e4222ad442f4a538a4d38caa73d58be0f6d (cherry picked from commit 31db36bbea6d081c8714a4c7ed3f5d81112ae8b8) --- org.eclipse.jgit.http.server/BUILD | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit.http.server/BUILD b/org.eclipse.jgit.http.server/BUILD index f8aa44db94..a0dae488b8 100644 --- a/org.eclipse.jgit.http.server/BUILD +++ b/org.eclipse.jgit.http.server/BUILD @@ -2,11 +2,16 @@ load("@rules_java//java:defs.bzl", "java_library") package(default_visibility = ["//visibility:public"]) +filegroup( + name = "jgit-servlet-resources", + srcs = glob(["resources/**"]), +) + java_library( name = "jgit-servlet", srcs = glob(["src/**/*.java"]), resource_strip_prefix = "org.eclipse.jgit.http.server/resources", - resources = glob(["resources/**"]), + resources = [":jgit-servlet-resources"], deps = [ "//lib:servlet-api", # We want these deps to be provided_deps -- cgit v1.2.3 From 51d6c63fe1602a9e812dc3610c10d7e6e31eeafd Mon Sep 17 00:00:00 2001 From: Martin Fick Date: Tue, 17 Dec 2024 17:30:17 -0800 Subject: Pack: separate an open/close accounting lock Previously the open/close accounting code used whole Pack object synchronization for locking. Unfortunately, there are other unrelated methods which use whole Pack object synchronization also, mostly to avoid concurrent loading of these independent indices, and they do not touch or need to coordinate with the open/close accounting data. During heavy load when a new file appears after repacking the readFully() threads could uselessly block on threads reading the reverse index. These threads could have been reading from the Pack file instead of waiting for the reverse index to be read. Use a new lock to make this locking more fine grained to prevent the readFully() calling threads from getting blocked in beginWindowCache() while the reverse index or bitmaps are being loaded. Change-Id: I7ac9067ca10cd6d6be0ab25148d99da3ace7ba36 Signed-off-by: Martin Fick --- .../eclipse/jgit/internal/storage/file/Pack.java | 56 ++++++++++++++-------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java index 8d2a86386f..1a7b5de1d7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java @@ -95,6 +95,9 @@ public class Pack implements Iterable { private RandomAccessFile fd; + /** For managing open/close accounting of {@link #fd}. */ + private final Object activeLock = new Object(); + /** Serializes reads performed against {@link #fd}. */ private final Object readLock = new Object(); @@ -645,37 +648,48 @@ public class Pack implements Iterable { throw new EOFException(); } - private synchronized void beginCopyAsIs() + private void beginCopyAsIs() throws StoredObjectRepresentationNotAvailableException { - if (++activeCopyRawData == 1 && activeWindows == 0) { - try { - doOpen(); - } catch (IOException thisPackNotValid) { - throw new StoredObjectRepresentationNotAvailableException( - thisPackNotValid); + synchronized (activeLock) { + if (++activeCopyRawData == 1 && activeWindows == 0) { + try { + doOpen(); + } catch (IOException thisPackNotValid) { + throw new StoredObjectRepresentationNotAvailableException( + thisPackNotValid); + } } } } - private synchronized void endCopyAsIs() { - if (--activeCopyRawData == 0 && activeWindows == 0) - doClose(); + private void endCopyAsIs() { + synchronized (activeLock) { + if (--activeCopyRawData == 0 && activeWindows == 0) { + doClose(); + } + } } - synchronized boolean beginWindowCache() throws IOException { - if (++activeWindows == 1) { - if (activeCopyRawData == 0) - doOpen(); - return true; + boolean beginWindowCache() throws IOException { + synchronized (activeLock) { + if (++activeWindows == 1) { + if (activeCopyRawData == 0) { + doOpen(); + } + return true; + } + return false; } - return false; } - synchronized boolean endWindowCache() { - final boolean r = --activeWindows == 0; - if (r && activeCopyRawData == 0) - doClose(); - return r; + boolean endWindowCache() { + synchronized (activeLock) { + boolean r = --activeWindows == 0; + if (r && activeCopyRawData == 0) { + doClose(); + } + return r; + } } private void doOpen() throws IOException { -- cgit v1.2.3 From a8efd046fa5f47351f91b5dddd13becb83b9bdc8 Mon Sep 17 00:00:00 2001 From: Martin Fick Date: Wed, 29 Jan 2025 09:47:01 -0800 Subject: RevWalk: Add an isMergedIntoAnyCommit() method RevWalk had a bulk isMergedIntoAny() method, however it worked only for Refs. Add a similar method which works for RevCommits instead. Unfortunately isMergedIntoAny() cannot be overloaded since java does not include the generic types in Collections of method signatures, so the method name needs to be more complicated to differentiate it from the existing method. Change-Id: I4f8f3a83058a186fafe3b37726e21c5074a6b8e1 Signed-off-by: Martin Fick --- .../jgit/revwalk/RevWalkUtilsReachableTest.java | 3 +- org.eclipse.jgit/.settings/.api_filters | 8 ++++ .../src/org/eclipse/jgit/revwalk/RevWalk.java | 56 ++++++++++++++++++---- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java index 0a045c917b..ffc7c96f69 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java @@ -14,6 +14,7 @@ import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import java.util.Collection; +import java.util.HashSet; import java.util.List; import org.eclipse.jgit.api.Git; @@ -121,7 +122,7 @@ public class RevWalkUtilsReachableTest extends RevWalkTestCase { Collection sortedRefs = RefComparator.sort(allRefs); List actual = RevWalkUtils.findBranchesReachableFrom(commit, rw, sortedRefs); - assertEquals(refsThatShouldContainCommit, actual); + assertEquals(new HashSet<>(refsThatShouldContainCommit), new HashSet<>(actual)); } } diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index 94adb25f78..4d7d7d07b7 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -80,6 +80,14 @@ + + + + + + + + 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 76c14e9c26..9714fab325 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -19,9 +19,14 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Optional; +import java.util.Map; +import java.util. +Optional; +import java.util.Set; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; @@ -539,6 +544,27 @@ public class RevWalk implements Iterable, AutoCloseable { NullProgressMonitor.INSTANCE).size() > 0; } + /** + * Determine if a commit is merged into any of the given + * revs. + * + * @param commit + * commit the caller thinks is reachable from revs. + * @param revs + * commits to start iteration from, and which is most likely a + * descendant (child) of commit. + * @return true if commit is merged into any of the revs; false otherwise. + * @throws java.io.IOException + * a pack file or loose object could not be read. + * @since 6.10.1 + */ + public boolean isMergedIntoAnyCommit(RevCommit commit, Collection revs) + throws IOException { + return getCommitsMergedInto(commit, revs, + GetMergedIntoStrategy.RETURN_ON_FIRST_FOUND, + NullProgressMonitor.INSTANCE).size() > 0; + } + /** * Determine if a commit is merged into all of the given * refs. @@ -562,7 +588,26 @@ public class RevWalk implements Iterable, AutoCloseable { private List getMergedInto(RevCommit needle, Collection haystacks, Enum returnStrategy, ProgressMonitor monitor) throws IOException { + Map> refsByCommit = new HashMap<>(); + for (Ref r : haystacks) { + RevObject o = peel(parseAny(r.getObjectId())); + if (!(o instanceof RevCommit)) { + continue; + } + refsByCommit.computeIfAbsent((RevCommit) o, c -> new ArrayList<>()).add(r); + } + monitor.update(1); List result = new ArrayList<>(); + for (RevCommit c : getCommitsMergedInto(needle, refsByCommit.keySet(), + returnStrategy, monitor)) { + result.addAll(refsByCommit.get(c)); + } + return result; + } + + private Set getCommitsMergedInto(RevCommit needle, Collection haystacks, + Enum returnStrategy, ProgressMonitor monitor) throws IOException { + Set result = new HashSet<>(); List uninteresting = new ArrayList<>(); List marked = new ArrayList<>(); RevFilter oldRF = filter; @@ -578,16 +623,11 @@ public class RevWalk implements Iterable, AutoCloseable { needle.parseHeaders(this); } int cutoff = needle.getGeneration(); - for (Ref r : haystacks) { + for (RevCommit c : haystacks) { if (monitor.isCancelled()) { return result; } monitor.update(1); - RevObject o = peel(parseAny(r.getObjectId())); - if (!(o instanceof RevCommit)) { - continue; - } - RevCommit c = (RevCommit) o; reset(UNINTERESTING | TEMP_MARK); markStart(c); boolean commitFound = false; @@ -599,7 +639,7 @@ public class RevWalk implements Iterable, AutoCloseable { } if (References.isSameObject(next, needle) || (next.flags & TEMP_MARK) != 0) { - result.add(r); + result.add(c); if (returnStrategy == GetMergedIntoStrategy.RETURN_ON_FIRST_FOUND) { return result; } -- cgit v1.2.3