All cases mutate, so R/W lock is redundant and complicates things

This commit is contained in:
comp500 2019-06-01 12:37:01 +01:00
parent f76a3d2d62
commit 86c2349fd3

View File

@ -8,6 +8,7 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
@ -19,14 +20,14 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
private final ZipInputStream zis; private final ZipInputStream zis;
private final Map<URI, byte[]> readFiles = new HashMap<URI, byte[]>(); private final Map<URI, byte[]> readFiles = new HashMap<URI, byte[]>();
// Write lock implies access to ZipInputStream - only 1 thread must read at a time! // Write lock implies access to ZipInputStream - only 1 thread must read at a time!
final ReentrantReadWriteLock filesLock = new ReentrantReadWriteLock(); final ReentrantLock filesLock = new ReentrantLock();
private ZipEntry entry; private ZipEntry entry;
public ZipReader(InputStream zip) { public ZipReader(InputStream zip) {
zis = new ZipInputStream(zip); zis = new ZipInputStream(zip);
} }
// File write lock must be obtained before calling this function // File lock must be obtained before calling this function
private byte[] readCurrFile() throws IOException { private byte[] readCurrFile() throws IOException {
byte[] bytes = new byte[(int) entry.getSize()]; byte[] bytes = new byte[(int) entry.getSize()];
DataInputStream dis = new DataInputStream(zis); DataInputStream dis = new DataInputStream(zis);
@ -34,7 +35,7 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
return bytes; return bytes;
} }
// File write lock must be obtained before calling this function // File lock must be obtained before calling this function
private byte[] findFile(URI loc) throws IOException, URISyntaxException { private byte[] findFile(URI loc) throws IOException, URISyntaxException {
while (true) { while (true) {
entry = zis.getNextEntry(); entry = zis.getNextEntry();
@ -51,28 +52,16 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
} }
public InputStream getFileInputStream(URI loc) throws Exception { public InputStream getFileInputStream(URI loc) throws Exception {
filesLock.readLock().lock(); filesLock.lock();
byte[] file = readFiles.get(loc); // Assume files are only read once, allow GC by removing
filesLock.readLock().unlock(); byte[] file = readFiles.remove(loc);
if (file != null) { if (file != null) {
// Assume files are only read once, allow GC filesLock.unlock();
filesLock.writeLock().lock();
readFiles.remove(loc);
filesLock.writeLock().unlock();
return new ByteArrayInputStream(file);
}
filesLock.writeLock().lock();
// Test again after receiving write lock
file = readFiles.get(loc);
if (file != null) {
// Assume files are only read once, allow GC
readFiles.remove(loc);
filesLock.writeLock().unlock();
return new ByteArrayInputStream(file); return new ByteArrayInputStream(file);
} }
file = findFile(loc); file = findFile(loc);
filesLock.writeLock().unlock(); filesLock.unlock();
if (file != null) { if (file != null) {
return new ByteArrayInputStream(file); return new ByteArrayInputStream(file);
} }