import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
+import org.simantics.acorn.FileCache;
import org.simantics.acorn.FileIO;
import org.simantics.acorn.Persistable;
+import org.simantics.acorn.exception.AcornAccessVerificationException;
+import org.simantics.acorn.exception.IllegalAcornStateException;
import org.simantics.utils.datastructures.Pair;
+import org.slf4j.Logger;
public abstract class LRUObject<MapKey, MapValue extends LRUObject<MapKey, MapValue>> implements Persistable {
-
+
+ public abstract Logger getLogger();
public static boolean VERIFY = true;
// Final stuff
final protected LRU<MapKey, MapValue> LRU;
+ final protected FileCache fileCache;
final private Semaphore mutex = new Semaphore(1);
final private MapKey key;
final private String fileName;
private Thread mutexOwner;
// for loading
- public LRUObject(LRU<MapKey, MapValue> LRU, MapKey key, Path readDirectory, String fileName, int offset, int length, boolean dirty, boolean resident) {
+ public LRUObject(LRU<MapKey, MapValue> LRU, FileCache fileCache, MapKey key, Path readDirectory, String fileName, int offset, int length, boolean dirty, boolean resident) {
this.LRU = LRU;
+ this.fileCache = fileCache;
this.key = key;
this.fileName = fileName;
this.offset = offset;
}
// for creating
- public LRUObject(LRU<MapKey, MapValue> LRU, MapKey key, Path readDirectory, String fileName, boolean dirty, boolean resident) {
- this(LRU, key, readDirectory, fileName, -1, -1, dirty, resident);
+ public LRUObject(LRU<MapKey, MapValue> LRU, FileCache fileCache, MapKey key, Path readDirectory, String fileName, boolean dirty, boolean resident) {
+ this(LRU, fileCache, key, readDirectory, fileName, -1, -1, dirty, resident);
}
/*
return key;
}
- public void acquireMutex() {
-
+ public void acquireMutex() throws IllegalAcornStateException {
try {
-
while(!mutex.tryAcquire(3, TimeUnit.SECONDS)) {
- System.err.println("Mutex is taking a long time to acquire - owner is " + mutexOwner);
+ getLogger().info("Mutex is taking a long time to acquire - owner is " + mutexOwner);
}
if(VERIFY)
mutexOwner = Thread.currentThread();
} catch (InterruptedException e) {
- throw new IllegalStateException(e);
+ throw new IllegalAcornStateException(e);
}
}
@Override
public void toFile(Path bytes) throws IOException {
- if(VERIFY) verifyAccess();
- Pair<byte[],Integer> pair = toBytes();
- byte[] data = pair.first;
- int length = pair.second;
- FileIO fio = FileIO.get(bytes);
- int offset = fio.saveBytes(data, length, overwrite());
- setPosition(offset, length);
- }
+ if(VERIFY) {
+ try {
+ verifyAccess();
+ } catch (AcornAccessVerificationException e) {
+ throw new IOException("Exception occured during toFile for file " + fileName, e);
+ }
+ }
+ try {
+ Pair<byte[], Integer> pair = toBytes();
+ byte[] data = pair.first;
+ int length = pair.second;
+ FileIO fio = fileCache.get(bytes);
+ int offset = fio.saveBytes(data, length, overwrite());
+ setPosition(offset, length);
+ } catch (AcornAccessVerificationException | IllegalAcornStateException e) {
+ throw new IOException("Exception occured during toFile for file " + fileName, e);
+ }
+ }
- public int makeResident() {
+ public int makeResident() throws AcornAccessVerificationException, IllegalAcornStateException {
if(VERIFY) verifyAccess();
return LRU.makeResident(this, false);
}
- public int makeResident(boolean keepResident) {
+ public int makeResident(boolean keepResident) throws AcornAccessVerificationException, IllegalAcornStateException {
if(VERIFY) verifyAccess();
return LRU.makeResident(this, true);
}
abstract void release();
abstract String getExtension();
- String getStateKey() {
+ String getStateKey() throws IllegalAcornStateException, AcornAccessVerificationException {
String result = getKey().toString() + "#" + getDirectory().getFileName() + "#" + getOffset() + "#" + getLength();
if(offset == -1)
- throw new IllegalStateException(result);
+ throw new IllegalAcornStateException(result);
return result;
}
- long getLastAccessTime() {
+ long getLastAccessTime() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
return accessTime;
}
- void accessed() {
+ void accessed() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
accessTime = AccessTime.getInstance().getAccessTime();
}
- boolean persist() {
+ boolean persist() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
if(LRU.persist(this)) {
readDirectory = LRU.getDirectory();
}
}
- void setForceResident(boolean value) {
+ void setForceResident(boolean value) throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
forceResident = value;
// isForceResidentSetAfterLastGet = true;
}
- boolean canBePersisted() {
+ boolean canBePersisted() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
// isForceResidentSetAfterLastGet = false;
return !forceResident;
}
- boolean isDirty() {
+ boolean isDirty() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
return dirty;
}
- boolean isResident() {
+ boolean isResident() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
return resident;
}
- String getFileName() {
+ String getFileName() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
return fileName;
}
- void setResident(boolean value) {
+ void setResident(boolean value) throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
resident = value;
}
- void setDirty(boolean value) {
+ void setDirty(boolean value) throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
dirty = value;
}
- byte[] readFile() throws IOException {
+ byte[] readFile() throws IOException, AcornAccessVerificationException {
if(VERIFY) verifyAccess();
Path dir = getDirectory();
Path f = dir.resolve(getFileName());
- FileIO fio = FileIO.get(f);
+ FileIO fio = fileCache.get(f);
return fio.readBytes(getOffset(), getLength());
}
abstract protected boolean overwrite();
- abstract protected Pair<byte[],Integer> toBytes();
+ abstract protected Pair<byte[],Integer> toBytes() throws IllegalAcornStateException;
- protected void setDirty() {
+ protected void setDirty() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
dirty = true;
}
- protected void verifyAccess() {
- assert(mutex.availablePermits() == 0);
+ protected void verifyAccess() throws AcornAccessVerificationException {
+ if (mutex.availablePermits() != 0)
+ throw new AcornAccessVerificationException("fileName=" + fileName + " mutex has " + mutex.availablePermits() + " available permits, should be 0! Current mutexOwner is " + mutexOwner);
}
- protected synchronized void cancelForceResident() {
+ protected synchronized void cancelForceResident() throws AcornAccessVerificationException {
setForceResident(false);
}
* Private implementation details
*/
- private int getOffset() {
+ private int getOffset() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
return offset;
}
- private int getLength() {
+ private int getLength() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
return length;
}
- private void setPosition(int offset, int length) {
+ private void setPosition(int offset, int length) throws AcornAccessVerificationException, IllegalAcornStateException {
if(VERIFY) verifyAccess();
if(offset == -1)
- throw new IllegalStateException();
+ throw new IllegalAcornStateException("offset == -1 for " + fileName + " in " + readDirectory.toAbsolutePath() + ", dirty=" + dirty + ", resident=" + resident + ", forceResident=" + forceResident);
this.offset = offset;
this.length = length;
if(overwrite() && offset > 0)
- throw new IllegalStateException();
+ throw new IllegalAcornStateException("overwrite() == true && offset > 0 for " + fileName + " in " + readDirectory.toAbsolutePath() + ", dirty=" + dirty + ", resident=" + resident + ", forceResident=" + forceResident);
}
- private Path getDirectory() {
+ private Path getDirectory() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
return readDirectory;
}
+
+ public void moveTo(Path path) {
+ readDirectory = path;
+ }
}
\ No newline at end of file