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
1 changed files with 76 additions and 13 deletions

View File

@ -34,25 +34,37 @@ import java.util.HashSet;
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<FileAccess> sources;
private Map<String, FileAccess> sourceMap;
private Set<String> 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<String> 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 class CombinedFileAccess implements FileAccess {
@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 class CombinedFileAccess implements FileAccess {
@Override
public Collection<String> listFiles(String path, boolean recursive) {
Set<String> 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<String> files = new ArrayList<String>();
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<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
public Collection<String> listFolders(String path) {
Set<String> 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 class CombinedFileAccess implements FileAccess {
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 class CombinedFileAccess implements FileAccess {
else exception.addSuppressed(ex);
}
}
} finally {
rwLock.writeLock().unlock();
}
if (exception != null) throw exception;