diff --git a/scm-core/src/main/java/sonia/scm/repository/work/NoneCachingWorkingCopyPool.java b/scm-core/src/main/java/sonia/scm/repository/work/NoneCachingWorkingCopyPool.java index 9e9859d27f..e5faa4935e 100644 --- a/scm-core/src/main/java/sonia/scm/repository/work/NoneCachingWorkingCopyPool.java +++ b/scm-core/src/main/java/sonia/scm/repository/work/NoneCachingWorkingCopyPool.java @@ -29,6 +29,12 @@ import sonia.scm.util.IOUtil; import javax.inject.Inject; import java.io.File; +/** + * This is the default implementation for the {@link WorkingCopyPool}. For each requested {@link WorkingCopy} with + * {@link #getWorkingCopy(SimpleWorkingCopyFactory.WorkingCopyContext)}, a new directory is requested from the + * {@link WorkdirProvider}. This directory is deleted immediately when the context is closed with + * {@link #contextClosed(SimpleWorkingCopyFactory.WorkingCopyContext, File)}. + */ public class NoneCachingWorkingCopyPool implements WorkingCopyPool { private final WorkdirProvider workdirProvider; diff --git a/scm-core/src/main/java/sonia/scm/repository/work/CachingAllWorkingCopyPool.java b/scm-core/src/main/java/sonia/scm/repository/work/SimpleCachingWorkingCopyPool.java similarity index 64% rename from scm-core/src/main/java/sonia/scm/repository/work/CachingAllWorkingCopyPool.java rename to scm-core/src/main/java/sonia/scm/repository/work/SimpleCachingWorkingCopyPool.java index 190a7bb58a..7033d59772 100644 --- a/scm-core/src/main/java/sonia/scm/repository/work/CachingAllWorkingCopyPool.java +++ b/scm-core/src/main/java/sonia/scm/repository/work/SimpleCachingWorkingCopyPool.java @@ -34,16 +34,45 @@ import java.io.File; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -public class CachingAllWorkingCopyPool implements WorkingCopyPool { +/** + * This class is a simple implementation of the {@link WorkingCopyPool} to demonstrate, + * how caching can work in the simplest way. For the first time a {@link WorkingCopy} is + * requested for a repository with {@link #getWorkingCopy(SimpleWorkingCopyFactory.WorkingCopyContext)}, + * this implementation fetches a new directory from the {@link WorkdirProvider}. + * On {@link #contextClosed(SimpleWorkingCopyFactory.WorkingCopyContext, File)}, + * the directory is not deleted, buy put into a map with the repository id as key. + * When a working copy is requested with {@link #getWorkingCopy(SimpleWorkingCopyFactory.WorkingCopyContext)} + * for a repository with such an existing directory, it is taken from the map, reclaimed and + * returned as {@link WorkingCopy}. + * If for one repository a working copy is requested, while another is in use already, + * a second directory is requested from the {@link WorkdirProvider} for the second one. + * If a context is closed with {@link #contextClosed(SimpleWorkingCopyFactory.WorkingCopyContext, File)} + * and there already is a directory stored in the map for the repository, + * the directory from the closed context simply is deleted. + *
+ * In general, this implementation should speed up things a bit, but one has to take into + * account, that there is no monitoring of diskspace. So you have to make sure, that + * there is enough space for a clone of each repository in the working dir. + *
+ * Possible enhancements: + * + */ +public class SimpleCachingWorkingCopyPool implements WorkingCopyPool { - private static final Logger LOG = LoggerFactory.getLogger(CachingAllWorkingCopyPool.class); + private static final Logger LOG = LoggerFactory.getLogger(SimpleCachingWorkingCopyPool.class); private final Map workdirs = new ConcurrentHashMap<>(); private final WorkdirProvider workdirProvider; @Inject - public CachingAllWorkingCopyPool(WorkdirProvider workdirProvider) { + public SimpleCachingWorkingCopyPool(WorkdirProvider workdirProvider) { this.workdirProvider = workdirProvider; } diff --git a/scm-core/src/test/java/sonia/scm/repository/work/CachingAllWorkingCopyPoolTest.java b/scm-core/src/test/java/sonia/scm/repository/work/SimpleCachingWorkingCopyPoolTest.java similarity index 82% rename from scm-core/src/test/java/sonia/scm/repository/work/CachingAllWorkingCopyPoolTest.java rename to scm-core/src/test/java/sonia/scm/repository/work/SimpleCachingWorkingCopyPoolTest.java index 65c9d02a83..cc45936bb7 100644 --- a/scm-core/src/test/java/sonia/scm/repository/work/CachingAllWorkingCopyPoolTest.java +++ b/scm-core/src/test/java/sonia/scm/repository/work/SimpleCachingWorkingCopyPoolTest.java @@ -44,14 +44,14 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @ExtendWith({MockitoExtension.class}) -class CachingAllWorkingCopyPoolTest { +class SimpleCachingWorkingCopyPoolTest { private static final Repository REPOSITORY = new Repository("1", "git", "space", "X"); @Mock WorkdirProvider workdirProvider; @InjectMocks - CachingAllWorkingCopyPool cachingAllWorkingCopyPool; + SimpleCachingWorkingCopyPool simpleCachingWorkingCopyPool; @Mock SimpleWorkingCopyFactory.WorkingCopyContext workingCopyContext; @@ -70,7 +70,7 @@ class CachingAllWorkingCopyPoolTest { when(workingCopyContext.getScmRepository()).thenReturn(REPOSITORY); when(workdirProvider.createNewWorkdir()).thenReturn(temp.toFile()); - WorkingCopy workdir = cachingAllWorkingCopyPool.getWorkingCopy(workingCopyContext); + WorkingCopy workdir = simpleCachingWorkingCopyPool.getWorkingCopy(workingCopyContext); verify(workingCopyContext).initialize(temp.toFile()); } @@ -80,9 +80,9 @@ class CachingAllWorkingCopyPoolTest { when(workingCopyContext.getScmRepository()).thenReturn(REPOSITORY); when(workdirProvider.createNewWorkdir()).thenReturn(temp.toFile()); - WorkingCopy firstWorkdir = cachingAllWorkingCopyPool.getWorkingCopy(workingCopyContext); - cachingAllWorkingCopyPool.contextClosed(workingCopyContext, firstWorkdir.getDirectory()); - WorkingCopy secondWorkdir = cachingAllWorkingCopyPool.getWorkingCopy(workingCopyContext); + WorkingCopy firstWorkdir = simpleCachingWorkingCopyPool.getWorkingCopy(workingCopyContext); + simpleCachingWorkingCopyPool.contextClosed(workingCopyContext, firstWorkdir.getDirectory()); + WorkingCopy secondWorkdir = simpleCachingWorkingCopyPool.getWorkingCopy(workingCopyContext); verify(workingCopyContext).initialize(temp.toFile()); verify(workingCopyContext).reclaim(temp.toFile()); @@ -100,10 +100,10 @@ class CachingAllWorkingCopyPoolTest { firstDirectory, secondDirectory); - WorkingCopy firstWorkdir = cachingAllWorkingCopyPool.getWorkingCopy(workingCopyContext); - WorkingCopy secondWorkdir = cachingAllWorkingCopyPool.getWorkingCopy(workingCopyContext); - cachingAllWorkingCopyPool.contextClosed(workingCopyContext, firstWorkdir.getDirectory()); - cachingAllWorkingCopyPool.contextClosed(workingCopyContext, secondWorkdir.getDirectory()); + WorkingCopy firstWorkdir = simpleCachingWorkingCopyPool.getWorkingCopy(workingCopyContext); + WorkingCopy secondWorkdir = simpleCachingWorkingCopyPool.getWorkingCopy(workingCopyContext); + simpleCachingWorkingCopyPool.contextClosed(workingCopyContext, firstWorkdir.getDirectory()); + simpleCachingWorkingCopyPool.contextClosed(workingCopyContext, secondWorkdir.getDirectory()); verify(workingCopyContext, never()).reclaim(any()); verify(workingCopyContext).initialize(firstDirectory); diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/SimpleHgWorkingCopyFactoryTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/SimpleHgWorkingCopyFactoryTest.java index 779b847087..8a8164e072 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/SimpleHgWorkingCopyFactoryTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/SimpleHgWorkingCopyFactoryTest.java @@ -32,7 +32,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import sonia.scm.repository.HgHookManager; import sonia.scm.repository.HgTestUtil; -import sonia.scm.repository.work.CachingAllWorkingCopyPool; +import sonia.scm.repository.work.SimpleCachingWorkingCopyPool; import sonia.scm.repository.work.WorkdirProvider; import sonia.scm.repository.work.WorkingCopy; import sonia.scm.web.HgRepositoryEnvironmentBuilder; @@ -59,7 +59,7 @@ public class SimpleHgWorkingCopyFactoryTest extends AbstractHgCommandTestBase { workdirProvider = new WorkdirProvider(temporaryFolder.newFolder()); HgHookManager hookManager = HgTestUtil.createHookManager(); HgRepositoryEnvironmentBuilder environmentBuilder = new HgRepositoryEnvironmentBuilder(handler, hookManager); - workingCopyFactory = new SimpleHgWorkingCopyFactory(Providers.of(environmentBuilder), new CachingAllWorkingCopyPool(workdirProvider)) { + workingCopyFactory = new SimpleHgWorkingCopyFactory(Providers.of(environmentBuilder), new SimpleCachingWorkingCopyPool(workdirProvider)) { @Override public void configure(com.aragost.javahg.commands.PullCommand pullCommand) { // we do not want to configure http hooks in this unit test diff --git a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SimpleSvnWorkingCopyFactoryTest.java b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SimpleSvnWorkingCopyFactoryTest.java index d5fc3c70fe..1d7fcf2b54 100644 --- a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SimpleSvnWorkingCopyFactoryTest.java +++ b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SimpleSvnWorkingCopyFactoryTest.java @@ -29,7 +29,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.tmatesoft.svn.core.SVNException; -import sonia.scm.repository.work.CachingAllWorkingCopyPool; +import sonia.scm.repository.work.SimpleCachingWorkingCopyPool; import sonia.scm.repository.work.NoneCachingWorkingCopyPool; import sonia.scm.repository.work.WorkdirProvider; import sonia.scm.repository.work.WorkingCopy; @@ -95,7 +95,7 @@ public class SimpleSvnWorkingCopyFactoryTest extends AbstractSvnCommandTestBase @Test public void shouldDeleteUntrackedFileOnReclaim() throws IOException { - SimpleSvnWorkingCopyFactory factory = new SimpleSvnWorkingCopyFactory(new CachingAllWorkingCopyPool(workdirProvider)); + SimpleSvnWorkingCopyFactory factory = new SimpleSvnWorkingCopyFactory(new SimpleCachingWorkingCopyPool(workdirProvider)); WorkingCopy workingCopy = factory.createWorkingCopy(createContext(), null); File directory = workingCopy.getWorkingRepository(); @@ -113,7 +113,7 @@ public class SimpleSvnWorkingCopyFactoryTest extends AbstractSvnCommandTestBase @Test public void shouldRestoreDeletedFileOnReclaim() throws IOException { - SimpleSvnWorkingCopyFactory factory = new SimpleSvnWorkingCopyFactory(new CachingAllWorkingCopyPool(workdirProvider)); + SimpleSvnWorkingCopyFactory factory = new SimpleSvnWorkingCopyFactory(new SimpleCachingWorkingCopyPool(workdirProvider)); WorkingCopy workingCopy = factory.createWorkingCopy(createContext(), null); File directory = workingCopy.getWorkingRepository();