From 0559df9730df67ea0aa9baf1bedc020234d59c79 Mon Sep 17 00:00:00 2001 From: "Blue (Lukas Rieger)" Date: Sun, 30 Aug 2020 15:47:53 +0200 Subject: [PATCH] Improve the use of the file-index for combined file-access --- .../fileaccess/CombinedFileAccess.java | 89 ++++++++++++++++--- 1 file changed, 76 insertions(+), 13 deletions(-) diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/fileaccess/CombinedFileAccess.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/fileaccess/CombinedFileAccess.java index e9c3d445..4f87321b 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/fileaccess/CombinedFileAccess.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/fileaccess/CombinedFileAccess.java @@ -34,25 +34,37 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.locks.ReentrantReadWriteLock; public class CombinedFileAccess implements FileAccess { + private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); + public List sources; private Map sourceMap; + private Set allFiles; + public CombinedFileAccess() { sources = new ArrayList<>(); sourceMap = new HashMap<>(); + allFiles = new HashSet<>(); } public void addFileAccess(FileAccess source) { - synchronized (sources) { + rwLock.writeLock().lock(); + + try { sources.add(source); - } - synchronized (sourceMap) { - for (String path : source.listFiles("", true)) { + + Collection sourceFiles = source.listFiles("", true); + for (String path : sourceFiles) { sourceMap.put(FileAccess.normalize(path), source); } + + allFiles.addAll(sourceFiles); + } finally { + rwLock.writeLock().unlock(); } } @@ -63,9 +75,12 @@ public String getName() { @Override public InputStream readFile(String path) throws FileNotFoundException, IOException { - synchronized (sourceMap) { + rwLock.readLock().lock(); + try { FileAccess source = sourceMap.get(FileAccess.normalize(path)); if (source != null) return source.readFile(path); + } finally { + rwLock.readLock().unlock(); } throw new FileNotFoundException("File " + path + " does not exist in any of the sources!"); @@ -73,25 +88,70 @@ public InputStream readFile(String path) throws FileNotFoundException, IOExcepti @Override public Collection listFiles(String path, boolean recursive) { - Set files = new HashSet<>(); - - synchronized (sources) { - for (int i = 0; i < sources.size(); i++) { - files.addAll(sources.get(i).listFiles(path, recursive)); + path = normalizeFolderPath(path); + Collection files = new ArrayList(); + + rwLock.readLock().lock(); + try { + for (String file : allFiles) { + int nameSplit = file.lastIndexOf('/'); + String filePath = ""; + if (nameSplit != -1) { + filePath = file.substring(0, nameSplit); + } + filePath = normalizeFolderPath(filePath); + + if (recursive) { + if (!filePath.startsWith(path) && !path.equals(filePath)) continue; + } else { + if (!path.equals(filePath)) continue; + } + + files.add(file); } + } finally { + rwLock.readLock().unlock(); } return files; } + private String normalizeFolderPath(String path) { + if (path.isEmpty()) return path; + if (path.charAt(path.length() - 1) != '/') path = path + "/"; + if (path.charAt(0) == '/') path = path.substring(1); + return path; + } + + /* + @Override + public Collection listFiles(String path, boolean recursive) { + Set files = new HashSet<>(); + + rwLock.readLock().lock(); + try { + for (int i = 0; i < sources.size(); i++) { + files.addAll(sources.get(i).listFiles(path, recursive)); + } + } finally { + rwLock.readLock().unlock(); + } + + return files; + } + */ + @Override public Collection listFolders(String path) { Set folders = new HashSet<>(); - - synchronized (sources) { + + rwLock.readLock().lock(); + try { for (int i = 0; i < sources.size(); i++) { folders.addAll(sources.get(i).listFolders(path)); } + } finally { + rwLock.readLock().unlock(); } return folders; @@ -101,7 +161,8 @@ public Collection listFolders(String path) { public void close() throws IOException { IOException exception = null; - synchronized (sources) { + rwLock.writeLock().lock(); + try { for (FileAccess source : sources) { try { source.close(); @@ -110,6 +171,8 @@ public void close() throws IOException { else exception.addSuppressed(ex); } } + } finally { + rwLock.writeLock().unlock(); } if (exception != null) throw exception;