use of com.arjuna.ats.arjuna.state.InputObjectState in project narayana by jbosstm.
the class LogStore method truncateLog.
/*
* Return true if the log needs to be deleted.
*/
private final boolean truncateLog(final LogInstance log, boolean force) throws ObjectStoreException {
boolean delete = false;
synchronized (_lock) {
File fd = new File(genPathName(log.getName(), log.getTypeName(), StateStatus.OS_COMMITTED));
try {
/*
* Create a list of ObjectState entries.
*/
ArrayList<InputObjectState> objectStates = scanLog(log.getName(), log.getTypeName());
if ((objectStates != null) && (objectStates.size() > 0)) {
/*
* If we are terminating then we can truncate the log to the
* real size needed to contain the existing entries since we
* will not use it again within another VM except for
* recovery purposes.
*/
String fname = genPathName(log.getName(), log.getTypeName(), StateStatus.OS_UNCOMMITTED);
File fd2 = openAndLock(fname, FileLock.F_WRLCK, true);
RandomAccessFile oFile = new RandomAccessFile(fd2, FILE_MODE);
int size = 0;
oFile.setLength(_maxFileSize);
for (int i = 0; i < objectStates.size(); i++) {
byte[] uidString = objectStates.get(i).stateUid().stringForm().getBytes(StandardCharsets.UTF_8);
int buffSize = _redzone.length + uidString.length + objectStates.get(i).buffer().length + 8;
java.nio.ByteBuffer buff = java.nio.ByteBuffer.allocate(buffSize);
size += buffSize;
try {
buff.put(_redzone);
buff.putInt(uidString.length);
buff.put(uidString);
buff.putInt(objectStates.get(i).buffer().length);
buff.put(objectStates.get(i).buffer(), 0, objectStates.get(i).buffer().length);
} catch (final Exception ex) {
ex.printStackTrace();
// TODO log
fd2.delete();
unlockAndClose(fd2, oFile);
throw new ObjectStoreException(ex.toString(), ex);
}
}
try {
if (force) {
oFile.setLength(size);
log.freeze();
}
fd2.renameTo(fd);
} catch (final Exception ex) {
ex.printStackTrace();
throw new ObjectStoreException(ex.toString(), ex);
} finally {
unlockAndClose(fd2, oFile);
}
} else {
/*
* Delete the log if there are no states in it. We could
* keep the file around and reuse it, but the advantage of
* this is small compared to having to cope with reusing old
* log instances.
*/
fd.delete();
/*
* Remember to remove the information from the memory cache.
*/
delete = true;
}
} catch (final ObjectStoreException ex) {
ex.printStackTrace();
throw ex;
} catch (final Exception ex) {
ex.printStackTrace();
throw new ObjectStoreException(ex.toString(), ex);
}
}
return delete;
}
use of com.arjuna.ats.arjuna.state.InputObjectState in project narayana by jbosstm.
the class LogStore method scanLog.
private final ArrayList<InputObjectState> scanLog(final Uid logName, final String typeName) throws ObjectStoreException {
synchronized (_lock) {
try {
String fname = genPathName(logName, typeName, StateStatus.OS_COMMITTED);
File fd = openAndLock(fname, FileLock.F_WRLCK, true);
RandomAccessFile iFile = new RandomAccessFile(fd, FILE_MODE);
try {
/*
* Create a list of ObjectState entries.
*/
ArrayList<InputObjectState> objectStates = new ArrayList<InputObjectState>();
// make sure we're at the start
iFile.seek(0);
while (iFile.getFilePointer() < iFile.length()) {
byte[] buff = new byte[_redzone.length];
iFile.read(buff);
if (!redzoneProtected(buff)) {
break;
/*
* TODO add an end-of-log entry and check for that. Currently just assume
* that no RZ means end, rather than corruption.
*/
} else {
int uidSize = iFile.readInt();
byte[] uidString = new byte[uidSize];
iFile.read(uidString);
Uid txId = new Uid(new String(uidString, StandardCharsets.UTF_8));
int imageSize = iFile.readInt();
byte[] imageState = new byte[imageSize];
iFile.read(imageState);
try {
InputObjectState state = new InputObjectState(txId, "", imageState);
objectStates.add(state);
} catch (final Exception ex) {
ex.printStackTrace();
throw new ObjectStoreException(ex.toString(), ex);
}
}
}
unlockAndClose(fd, iFile);
iFile = null;
/*
* At this stage we now have a list of ObjectState entries.
* Now we need to go through and prune the list. This is
* complicated by the fact that there can be 1.. entries for
* a specific transaction since we continually update the
* log as we drive recovery. If an entry hasn't been deleted
* then we will keep the latest one we find.
*/
/*
* First search for those entries that have been deleted.
*/
ArrayList<InputObjectState> deletedLogs = new ArrayList<InputObjectState>();
for (int i = 0; i < objectStates.size(); i++) {
InputObjectState curr = objectStates.get(i);
try {
if (Arrays.equals(curr.unpackBytes(), _removedState)) {
deletedLogs.add(curr);
} else
// don't forget to reset the read pointer!
curr.reread();
} catch (final Exception ex) {
// if not a delete record then the first entry won't
// be an the defined byte array.
// don't forget to reset the read pointer!
curr.reread();
}
}
if (deletedLogs.size() > 0) {
/*
* make sure we remove them from the first list to save time.
*/
objectStates.removeAll(deletedLogs);
deleteEntries(objectStates, deletedLogs);
/*
* At this stage we should only have entries that refer
* to in-flight transactions. Go through the list and
* remove N-1 references for each transaction id.
*/
pruneEntries(objectStates);
return objectStates;
} else
return objectStates;
} finally {
if (iFile != null)
unlockAndClose(fd, iFile);
}
} catch (final ObjectStoreException ex) {
ex.printStackTrace();
throw ex;
} catch (final Exception ex) {
ex.printStackTrace();
throw new ObjectStoreException(ex.toString(), ex);
}
}
}
use of com.arjuna.ats.arjuna.state.InputObjectState in project narayana by jbosstm.
the class ObjectStateWrapper method getIOS.
public InputObjectState getIOS() {
if (getBuff() == null || getBuff().length == 0)
return null;
Uid u = getNewUid() == null ? Uid.nullUid() : getNewUid();
String t = gettName() == null ? "" : gettName();
byte[] b = getBuff() == null ? new byte[0] : getBuff();
return new InputObjectState(u, t, b);
}
use of com.arjuna.ats.arjuna.state.InputObjectState in project narayana by jbosstm.
the class RecoveryStoreBean method allTypes.
public ObjectStateWrapper allTypes() throws ObjectStoreException {
InputObjectState ios = new InputObjectState();
boolean ok = rs.allTypes(ios);
return new ObjectStateWrapper(ios, ok);
}
use of com.arjuna.ats.arjuna.state.InputObjectState in project narayana by jbosstm.
the class RecoveryStoreBean method allObjUids.
public ObjectStateWrapper allObjUids(String type) throws ObjectStoreException {
InputObjectState ios = new InputObjectState();
boolean ok = rs.allObjUids(type, ios);
return new ObjectStateWrapper(ios, ok);
}
Aggregations