/* 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.classindex;
import com.db4o.foundation.*;
import com.db4o.internal.*;
import com.db4o.internal.btree.*;
import com.db4o.internal.references.*;
/**
* @exclude
*/
public class BTreeClassIndexStrategy extends AbstractClassIndexStrategy {
private BTree _btreeIndex;
public BTreeClassIndexStrategy(ClassMetadata classMetadata) {
super(classMetadata);
}
public BTree btree() {
return _btreeIndex;
}
public int entryCount(Transaction ta) {
return _btreeIndex != null
? _btreeIndex.size(ta)
: 0;
}
public void initialize(ObjectContainerBase stream) {
createBTreeIndex(stream, 0);
}
public void purge() {
}
public void read(ObjectContainerBase stream, int indexID) {
readBTreeIndex(stream, indexID);
}
public int write(Transaction trans) {
if (_btreeIndex == null){
return 0;
}
_btreeIndex.write(trans);
return _btreeIndex.getID();
}
public void traverseIds(Transaction ta, Visitor4 command) {
if(_btreeIndex!=null) {
_btreeIndex.traverseKeys(ta,command);
}
}
private void createBTreeIndex(final ObjectContainerBase stream, int btreeID){
if (stream.isClient()) {
return;
}
_btreeIndex = ((LocalObjectContainer)stream).createBTreeClassIndex(btreeID);
_btreeIndex.setRemoveListener(new Visitor4() {
public void visit(Object obj) {
removeId((TransactionContext)obj);
}
});
}
private void removeId(TransactionContext context) {
ReferenceSystem referenceSystem = context._transaction.referenceSystem();
ObjectReference reference = referenceSystem.referenceForId((Integer)context._object);
if(reference != null){
referenceSystem.removeReference(reference);
}
}
private void readBTreeIndex(ObjectContainerBase stream, int indexId) {
if(! stream.isClient() && _btreeIndex == null){
createBTreeIndex(stream, indexId);
}
}
protected void internalAdd(Transaction trans, int id) {
_btreeIndex.add(trans, new Integer(id));
}
protected void internalRemove(Transaction ta, int id) {
_btreeIndex.remove(ta, new Integer(id));
}
public void dontDelete(Transaction transaction, int id) {
}
public void defragReference(ClassMetadata classMetadata, DefragmentContextImpl context,int classIndexID) {
int newID = -classIndexID;
context.writeInt(newID);
}
public int id() {
return _btreeIndex.getID();
}
public Iterator4 allSlotIDs(Transaction trans) {
return _btreeIndex.allNodeIds(trans);
}
public void defragIndex(DefragmentContextImpl context) {
_btreeIndex.defragIndex(context);
}
public static BTree btree(ClassMetadata clazz) {
ClassIndexStrategy index = clazz.index();
if(! (index instanceof BTreeClassIndexStrategy)){
throw new IllegalStateException();
}
return ((BTreeClassIndexStrategy)index).btree();
}
public static Iterator4 iterate(ClassMetadata clazz, Transaction trans) {
return btree(clazz).asRange(trans).keys();
}
public IntVisitable idVisitable(final Transaction trans){
return new IntVisitable() {
public void traverse(final IntVisitor visitor) {
traverseIds(trans, new Visitor4<Integer>() {
public void visit(Integer i) {
visitor.visit(i);
}
});
}
};
}
}