diff --git a/src/main/java/nl/tudelft/ewi/gitolite/repositories/PathRepositoriesManager.java b/src/main/java/nl/tudelft/ewi/gitolite/repositories/PathRepositoriesManager.java index 9d4a778..101bcbd 100644 --- a/src/main/java/nl/tudelft/ewi/gitolite/repositories/PathRepositoriesManager.java +++ b/src/main/java/nl/tudelft/ewi/gitolite/repositories/PathRepositoriesManager.java @@ -1,6 +1,5 @@ package nl.tudelft.ewi.gitolite.repositories; -import com.google.common.collect.Maps; import lombok.EqualsAndHashCode; import lombok.SneakyThrows; import lombok.Value; @@ -12,7 +11,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; -import java.util.Map; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -30,46 +29,27 @@ public class PathRepositoriesManager implements RepositoriesManager { */ private final Path root; - /** - * Map that contains the repositories. - */ - private final Map repositories; - /** * {@link RepositoriesManager} implementation based on {@code Path}. * @param root Folder that contains the repositories. */ public PathRepositoriesManager(final File root) { this.root = root.toPath(); - this.repositories = Maps.newHashMap(); - scan(); - } - - /** - * Scan for repositories. - */ - public void scan() { - repositories.clear(); - directoriesAsStream(root).forEach(path -> { - PathRepositoryImpl pathRepository = new PathRepositoryImpl(path); - repositories.put(pathRepository.getURI(), pathRepository); - }); } @Override public Collection getRepositories() { - scan(); - return repositories.values(); + return directoriesAsStream(root) + .map(PathRepositoryImpl::new) + .collect(Collectors.toList()); } @Override public PathRepositoryImpl getRepository(URI uri) throws RepositoryNotFoundException { - scan(); - PathRepositoryImpl pathRepository = repositories.get(uri); - if(pathRepository == null) { - throw new RepositoryNotFoundException(); - } - return pathRepository; + return directoriesAsStream(root) + .map(PathRepositoryImpl::new) + .filter(pathRepository -> pathRepository.getURI().equals(uri)) + .findAny().orElseThrow(RepositoryNotFoundException::new); } @SneakyThrows @@ -102,7 +82,6 @@ public URI getURI() { @Override public void delete() throws IOException { FileUtils.deleteDirectory(path.toFile()); - repositories.remove(getURI(), this); } @Override diff --git a/src/test/java/PathRepositoryManagerTest.java b/src/test/java/PathRepositoryManagerTest.java index 6393e26..71f1f87 100644 --- a/src/test/java/PathRepositoryManagerTest.java +++ b/src/test/java/PathRepositoryManagerTest.java @@ -1,19 +1,33 @@ import com.google.common.io.Files; import nl.tudelft.ewi.gitolite.repositories.PathRepositoriesManager; +import nl.tudelft.ewi.gitolite.repositories.PathRepositoriesManager.PathRepositoryImpl; +import nl.tudelft.ewi.gitolite.repositories.Repository; import org.apache.commons.io.FileUtils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; +import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.mockito.Mockito; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; - +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.stream.IntStream; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.hamcrest.Matchers.emptyArray; @@ -66,6 +80,20 @@ public void testRemoveRepository() throws URISyntaxException, IOException { ); } + @Test + public void testConcurrentAccess() throws ExecutionException, InterruptedException { + int numThreads = 20; + ExecutorService executorService = Executors.newFixedThreadPool(4); + + final Callable getRepository = () -> pathRepositoriesManager.getRepository(new URI(TEST_01_GIT)); + + IntStream.range(0, numThreads) + .mapToObj(count -> executorService.submit(getRepository)) + .forEach(Assert::assertNotNull); + + executorService.shutdownNow(); + } + private File setUpBareRepository(String name) throws GitAPIException { File repoFolder = new File(temporaryFolder.getRoot(), name + ".git"); Git.init()