}
private void applyTransaction0(JODBSession session, ITranslatedDataSorce translatedDataSorce , long transactionOffset, IOTicket writeTicket ) throws IOException{
if(!_transactionLock.isWriteLockedByCurrentThread()){
throw new JodbIOException("Transaction without holding write lock");
}
IRandomAccessDataBuffer mainDataBuffer = writeTicket.getRandomAccessBuffer();
IRandomAccessDataBuffer newDataBuffer = translatedDataSorce.getTransactionNewDataFile();
IRandomAccessDataBuffer replacementsDataBuffer = translatedDataSorce.getTransactionReplacementsDataFile();
IRandomAccessDataBuffer rollbackDataBuffer = translatedDataSorce.getRollbackDataFile();
long dataBlockIncrease = newDataBuffer.length();
_substitutions.backupPendingSubstitutions();
DataEntry entry = _entries.lastElement();
if(_substitutions.hasPendingSubstitutionTables()){
translatedDataSorce.resetTransactionBufferToEnd();
//writing substitution table
replacementsDataBuffer.resetToEnd();
SubstTable substTable = entry.getLiteralSubstTable();
replacementsDataBuffer.write(TransactionAssembler.TRANSACTION_REPLACEMENT_ENTRY_TYPE_STATIC);
replacementsDataBuffer.writeLong(substTable._tableOffset);//offset of table in main file
long lengthEntryOffset = replacementsDataBuffer.getCursorOffset();
replacementsDataBuffer.writeLong(0);//reserved space for length
substTable.writePendingRecords(mainDataBuffer, replacementsDataBuffer);
//replacement length
long substTableLen = replacementsDataBuffer.getCursorOffset() - lengthEntryOffset - 8;//8 bytes for len of entry
replacementsDataBuffer.seek(lengthEntryOffset);
replacementsDataBuffer.writeLong(substTableLen);
}
DataEntry pendingDataEntry = null;
if(_substitutions.hasPendingSubstitutionTables()){//last entry didn't accept all substitutions, seel current entry and create new one
replacementsDataBuffer.resetToEnd();
pendingDataEntry = new DataEntry();
newDataBuffer.resetToEnd();
pendingDataEntry.writeWithAllSubstitutionRecords(newDataBuffer, null, 0, transactionOffset);
}
if (dataBlockIncrease>0) {
//write replacement for data entry length
replacementsDataBuffer.resetToEnd();
replacementsDataBuffer.writeByte(TransactionAssembler.TRANSACTION_REPLACEMENT_ENTRY_TYPE_STATIC);
replacementsDataBuffer.writeLong(entry._tableOffset);
long lengthEntryOffset = replacementsDataBuffer.getCursorOffset();
replacementsDataBuffer.writeLong(0);//reserved space for length
entry.write(replacementsDataBuffer, entry._dataBlockLength + dataBlockIncrease, pendingDataEntry != null);//write as sealed if pending data entry exists
long len = replacementsDataBuffer.getCursorOffset() - lengthEntryOffset - 8;//8 bytes for len of entry
//replacement length
replacementsDataBuffer.seek(lengthEntryOffset);
replacementsDataBuffer.writeLong(len);
//..
}
translatedDataSorce.resetTransactionBufferToStart();
if(JODBConfig.DEBUG){
_logger.info("File size prior transaction="+mainDataBuffer.length());
_logger.info("Transaction state offset="+transactionOffset+" new data len="+newDataBuffer.length()+" replacement data="+replacementsDataBuffer.length()+" rollback data"+rollbackDataBuffer.length());
}
long transactionDataEnd = transactionOffset+newDataBuffer.length();
_header.setDataTransactionState(mainDataBuffer, transactionOffset, transactionDataEnd);
mainDataBuffer.seek(transactionOffset);
long toTransfer = newDataBuffer.length();
long transfered = mainDataBuffer.transferFrom(newDataBuffer.getChannel(), transactionOffset, toTransfer);
if(toTransfer!=transfered){
throw new JodbIOException("unable to transfer transaction data "+transfered+"<>"+toTransfer);
}
mainDataBuffer.seek(mainDataBuffer.getCursorOffset()+transfered);
long rollbackTransactionStartOffset = mainDataBuffer.getCursorOffset();
long backupEnd = backup(mainDataBuffer, rollbackTransactionStartOffset, replacementsDataBuffer);
_header.setRollbackTransactionState(mainDataBuffer, rollbackTransactionStartOffset, backupEnd);
_header.setTransactionInProgressState(mainDataBuffer);
translatedDataSorce.resetTransactionBufferToStart();
while(replacementsDataBuffer.getCursorOffset()<replacementsDataBuffer.length()){
byte replacementType = replacementsDataBuffer.readByte();
long targetOffset = replacementsDataBuffer.readLong();
switch (replacementType) {
case TransactionAssembler.TRANSACTION_REPLACEMENT_ENTRY_TYPE_STATIC:
long dataLength = replacementsDataBuffer.readLong();
transfered = mainDataBuffer.transferFrom(replacementsDataBuffer.getChannel(), targetOffset, dataLength);
if(transfered!=dataLength){
throw new JodbIOException("unable to transfer rollback data "+transfered+"<>"+toTransfer);
}
break;
case TransactionAssembler.TRANSACTION_REPLACEMENT_ENTRY_TYPE_REDIRECTOR:
mainDataBuffer.seek(targetOffset);
short id = mainDataBuffer.readShort();