/* 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;
import com.db4o.*;
import com.db4o.foundation.*;
import com.db4o.internal.delete.*;
import com.db4o.internal.marshall.*;
import com.db4o.internal.slots.*;
/**
* @exclude
*/
class WriteUpdateProcessor {
private final LocalTransaction _transaction;
private final int _id;
private final ClassMetadata _clazz;
private final ArrayType _typeInfo;
private int _cascade = 0;
public WriteUpdateProcessor(LocalTransaction transaction,
int id,
ClassMetadata clazz,
ArrayType typeInfo) {
_transaction = transaction;
_id = id;
_clazz = clazz;
_typeInfo = typeInfo;
}
public void run(){
_transaction.checkSynchronization();
if(DTrace.enabled){
DTrace.WRITE_UPDATE_ADJUST_INDEXES.log(_id);
}
if(alreadyHandled()){
return;
}
// TODO: Try to get rid of getting the slot here because it
// will invoke reading a pointer from the file system.
// It may be possible to figure out the readd case
// by asking the IdSystem in a smarter way.
Slot slot = _transaction.idSystem().currentSlot(_id);
if(handledAsReAdd(slot)){
return;
}
if(_clazz.canUpdateFast()){
return;
}
StatefulBuffer objectBytes = container().readStatefulBufferBySlot(_transaction, _id, slot);
deleteMembers(objectBytes);
}
private LocalObjectContainer container() {
return _transaction.localContainer();
}
private void deleteMembers(StatefulBuffer objectBytes) {
ObjectHeader oh = new ObjectHeader(_clazz, objectBytes);
DeleteInfo info = (DeleteInfo)TreeInt.find(_transaction._delete, _id);
if(info != null){
if(info._cascade > _cascade){
_cascade = info._cascade;
}
}
objectBytes.setCascadeDeletes(_cascade);
DeleteContextImpl context = new DeleteContextImpl(objectBytes, oh, _clazz.classReflector(), null);
_clazz.deleteMembers(context, _typeInfo, true);
}
private boolean handledAsReAdd(Slot slot) {
if(! Slot.isNull(slot)){
return false;
}
_clazz.addToIndex(_transaction, _id);
return true;
}
private boolean alreadyHandled() {
TreeInt newNode = new TreeInt(_id);
_transaction._writtenUpdateAdjustedIndexes = Tree.add(_transaction._writtenUpdateAdjustedIndexes, newNode);
return ! newNode.wasAddedToTree();
}
}