/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package com.db4o.internal.transactionlog; import com.db4o.foundation.*; import com.db4o.internal.*; import com.db4o.internal.freespace.*; import com.db4o.internal.slots.*; /** * @exclude */ public class EmbeddedTransactionLogHandler extends TransactionLogHandler{ public EmbeddedTransactionLogHandler(LocalObjectContainer container) { super(container); } public void completeInterruptedTransaction(final int transactionId1, final int transactionId2) { if(transactionId1 <= 0 || transactionId1 != transactionId2){ return; } StatefulBuffer bytes = new StatefulBuffer(_container.systemTransaction(), transactionId1, Const4.INT_LENGTH); bytes.read(); int length = bytes.readInt(); if (length > 0) { bytes = new StatefulBuffer(_container.systemTransaction(), transactionId1, length); bytes.read(); bytes.incrementOffset(Const4.INT_LENGTH); readWriteSlotChanges(bytes); } _container.writeTransactionPointer(0); flushDatabaseFile(); } public Slot allocateSlot(boolean appendToFile, int slotChangeCount) { int transactionLogByteCount = transactionLogSlotLength(slotChangeCount); FreespaceManager freespaceManager = _container.freespaceManager(); if(! appendToFile && freespaceManager != null){ Slot slot = freespaceManager.allocateTransactionLogSlot(transactionLogByteCount); if(slot != null){ return slot; } } return _container.appendBytes(transactionLogByteCount); } private void freeSlot(Slot slot){ if(slot == null){ return; } if(_container.freespaceManager() == null){ return; } _container.freespaceManager().freeSafeSlot(slot); } public void applySlotChanges(Visitable<SlotChange> slotChangeTree, int slotChangeCount, Slot reservedSlot) { if(slotChangeCount > 0){ Slot transactionLogSlot = slotLongEnoughForLog(slotChangeCount, reservedSlot) ? reservedSlot : allocateSlot(true, slotChangeCount); final StatefulBuffer buffer = new StatefulBuffer(_container.systemTransaction(), transactionLogSlot); buffer.writeInt(transactionLogSlot.length()); buffer.writeInt(slotChangeCount); appendSlotChanges(buffer, slotChangeTree); buffer.write(); Runnable commitHook = _container.commitHook(); flushDatabaseFile(); _container.writeTransactionPointer(transactionLogSlot.address()); flushDatabaseFile(); if (writeSlots(slotChangeTree)) { flushDatabaseFile(); } _container.writeTransactionPointer(0); commitHook.run(); flushDatabaseFile(); if (transactionLogSlot != reservedSlot) { freeSlot(transactionLogSlot); } } freeSlot(reservedSlot); } private boolean slotLongEnoughForLog(int slotChangeCount, Slot slot){ return slot != null && slot.length() >= transactionLogSlotLength(slotChangeCount); } public void close() { // do nothing } }