Improve the use of the file-index for combined file-access

This commit is contained in:
Blue (Lukas Rieger) 2020-08-30 15:47:53 +02:00
parent fd6da092ab
commit 0559df9730

View File

@ -34,25 +34,37 @@
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class CombinedFileAccess implements FileAccess { public class CombinedFileAccess implements FileAccess {
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
public List<FileAccess> sources; public List<FileAccess> sources;
private Map<String, FileAccess> sourceMap; private Map<String, FileAccess> sourceMap;
private Set<String> allFiles;
public CombinedFileAccess() { public CombinedFileAccess() {
sources = new ArrayList<>(); sources = new ArrayList<>();
sourceMap = new HashMap<>(); sourceMap = new HashMap<>();
allFiles = new HashSet<>();
} }
public void addFileAccess(FileAccess source) { public void addFileAccess(FileAccess source) {
synchronized (sources) { rwLock.writeLock().lock();
try {
sources.add(source); sources.add(source);
}
synchronized (sourceMap) { Collection<String> sourceFiles = source.listFiles("", true);
for (String path : source.listFiles("", true)) { for (String path : sourceFiles) {
sourceMap.put(FileAccess.normalize(path), source); sourceMap.put(FileAccess.normalize(path), source);
} }
allFiles.addAll(sourceFiles);
} finally {
rwLock.writeLock().unlock();
} }
} }
@ -63,9 +75,12 @@ public String getName() {
@Override @Override
public InputStream readFile(String path) throws FileNotFoundException, IOException { public InputStream readFile(String path) throws FileNotFoundException, IOException {
synchronized (sourceMap) { rwLock.readLock().lock();
try {
FileAccess source = sourceMap.get(FileAccess.normalize(path)); FileAccess source = sourceMap.get(FileAccess.normalize(path));
if (source != null) return source.readFile(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!"); 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 @Override
public Collection<String> listFiles(String path, boolean recursive) { public Collection<String> listFiles(String path, boolean recursive) {
Set<String> files = new HashSet<>(); path = normalizeFolderPath(path);
Collection<String> files = new ArrayList<String>();
synchronized (sources) {
for (int i = 0; i < sources.size(); i++) { rwLock.readLock().lock();
files.addAll(sources.get(i).listFiles(path, recursive)); 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; 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<String> listFiles(String path, boolean recursive) {
Set<String> 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 @Override
public Collection<String> listFolders(String path) { public Collection<String> listFolders(String path) {
Set<String> folders = new HashSet<>(); Set<String> folders = new HashSet<>();
synchronized (sources) { rwLock.readLock().lock();
try {
for (int i = 0; i < sources.size(); i++) { for (int i = 0; i < sources.size(); i++) {
folders.addAll(sources.get(i).listFolders(path)); folders.addAll(sources.get(i).listFolders(path));
} }
} finally {
rwLock.readLock().unlock();
} }
return folders; return folders;
@ -101,7 +161,8 @@ public Collection<String> listFolders(String path) {
public void close() throws IOException { public void close() throws IOException {
IOException exception = null; IOException exception = null;
synchronized (sources) { rwLock.writeLock().lock();
try {
for (FileAccess source : sources) { for (FileAccess source : sources) {
try { try {
source.close(); source.close();
@ -110,6 +171,8 @@ public void close() throws IOException {
else exception.addSuppressed(ex); else exception.addSuppressed(ex);
} }
} }
} finally {
rwLock.writeLock().unlock();
} }
if (exception != null) throw exception; if (exception != null) throw exception;