diff options
author | Kaushik Lingarkar <quic_kaushikl@quicinc.com> | 2023-02-27 15:29:00 -0800 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2023-03-30 22:25:53 +0200 |
commit | 33c00f3347738b73d5b09a2a882ec9a9aac5a6af (patch) | |
tree | 1097508b2f9a2ecfc8d65ab61291c4f2f3326921 /org.eclipse.jgit.test/tst/org/eclipse | |
parent | d7400517bf2744937746ac2912c93eb8d172ed28 (diff) | |
download | jgit-33c00f3347738b73d5b09a2a882ec9a9aac5a6af.tar.gz jgit-33c00f3347738b73d5b09a2a882ec9a9aac5a6af.zip |
Implement a snapshotting RefDirectory for use in request scope
Introduce a SnapshottingRefDirectory class which allows users to get
a snapshot of the ref database and use it in a request scope (for
example a Gerrit query) instead of having to re-read packed-refs
several times in a request.
This can potentially be further improved to avoid scanning/reading a
loose ref several times in a request. This would especially help
repeated lookups of a packed ref, where we check for the existence of
a loose ref each time.
Change-Id: I634b92877f819f8bf36a3b9586bbc1815108189a
Signed-off-by: Kaushik Lingarkar <quic_kaushikl@quicinc.com>
Diffstat (limited to 'org.eclipse.jgit.test/tst/org/eclipse')
2 files changed, 102 insertions, 14 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java index f2b4b484b6..619e585a90 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java @@ -58,13 +58,13 @@ import org.junit.Test; public class RefDirectoryTest extends LocalDiskRepositoryTestCase { private Repository diskRepo; - private TestRepository<Repository> repo; + TestRepository<Repository> repo; - private RefDirectory refdir; + RefDirectory refdir; - private RevCommit A; + RevCommit A; - private RevCommit B; + RevCommit B; private RevTag v1_0; @@ -1349,25 +1349,25 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase { assertEquals(Storage.LOOSE, ref.getStorage()); } - private void writeLooseRef(String name, AnyObjectId id) throws IOException { - writeLooseRef(name, id.name() + "\n"); - } - - private void writeLooseRef(String name, String content) throws IOException { - write(new File(diskRepo.getDirectory(), name), content); - } - - private void writePackedRef(String name, AnyObjectId id) throws IOException { + void writePackedRef(String name, AnyObjectId id) throws IOException { writePackedRefs(id.name() + " " + name + "\n"); } - private void writePackedRefs(String content) throws IOException { + void writePackedRefs(String content) throws IOException { File pr = new File(diskRepo.getDirectory(), "packed-refs"); write(pr, content); FS fs = diskRepo.getFS(); fs.setLastModified(pr.toPath(), Instant.now().minusSeconds(3600)); } + private void writeLooseRef(String name, AnyObjectId id) throws IOException { + writeLooseRef(name, id.name() + "\n"); + } + + private void writeLooseRef(String name, String content) throws IOException { + write(new File(diskRepo.getDirectory(), name), content); + } + private void deleteLooseRef(String name) { File path = new File(diskRepo.getDirectory(), name); assertTrue("deleted " + name, path.delete()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectoryTest.java new file mode 100644 index 0000000000..c3dafe4aa2 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectoryTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package org.eclipse.jgit.internal.storage.file; + +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.transport.ReceiveCommand; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class SnapshottingRefDirectoryTest extends RefDirectoryTest { + private RefDirectory originalRefDirectory; + + /** {@inheritDoc} */ + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + originalRefDirectory = refdir; + refdir = refdir.createSnapshottingRefDirectory(); + } + + @Test + public void testSnapshot_CannotSeeExternalPackedRefsUpdates() + throws IOException { + String refName = "refs/heads/new"; + + writePackedRef(refName, A); + assertEquals(A, originalRefDirectory.exactRef(refName).getObjectId()); + assertEquals(A, refdir.exactRef(refName).getObjectId()); + + writePackedRef(refName, B); + assertEquals(B, originalRefDirectory.exactRef(refName).getObjectId()); + assertEquals(A, refdir.exactRef(refName).getObjectId()); + } + + @Test + public void testSnapshot_WriteThrough() throws IOException { + String refName = "refs/heads/new"; + + writePackedRef(refName, A); + assertEquals(A, originalRefDirectory.exactRef(refName).getObjectId()); + assertEquals(A, refdir.exactRef(refName).getObjectId()); + + PackedBatchRefUpdate update = refdir.newBatchUpdate(); + update.addCommand(new ReceiveCommand(A, B, refName)); + update.execute(repo.getRevWalk(), NullProgressMonitor.INSTANCE); + + assertEquals(B, originalRefDirectory.exactRef(refName).getObjectId()); + assertEquals(B, refdir.exactRef(refName).getObjectId()); + } + + @Test + public void testSnapshot_IncludeExternalPackedRefsUpdatesWithWrites() + throws IOException { + String refA = "refs/heads/refA"; + String refB = "refs/heads/refB"; + writePackedRefs("" + // + A.name() + " " + refA + "\n" + // + A.name() + " " + refB + "\n"); + assertEquals(A, refdir.exactRef(refA).getObjectId()); + assertEquals(A, refdir.exactRef(refB).getObjectId()); + + writePackedRefs("" + // + B.name() + " " + refA + "\n" + // + A.name() + " " + refB + "\n"); + PackedBatchRefUpdate update = refdir.newBatchUpdate(); + update.addCommand(new ReceiveCommand(A, B, refB)); + update.execute(repo.getRevWalk(), NullProgressMonitor.INSTANCE); + + assertEquals(B, originalRefDirectory.exactRef(refA).getObjectId()); + assertEquals(B, refdir.exactRef(refA).getObjectId()); + assertEquals(B, originalRefDirectory.exactRef(refB).getObjectId()); + assertEquals(B, refdir.exactRef(refB).getObjectId()); + } +} |