package pt.ist.fenixframework.core.adt.bplustree;
import java.io.Serializable;
// import java.util.concurrent.atomic.AtomicInteger;
import java.util.Map;
import java.util.TreeMap;
import pt.ist.fenixframework.FenixFramework;
import pt.ist.fenixframework.core.AbstractDomainObject;
import pt.ist.fenixframework.core.Externalization;
/** The keys comparison function should be consistent with equals. */
public abstract class AbstractNode<T extends AbstractDomainObject> extends AbstractNode_Base implements Iterable {
/* Node Interface */
/** Inserts the given key-value pair and returns the (possibly new) root node */
abstract AbstractNode insert(Comparable key, T value);
/** Removes the element with the given key */
abstract AbstractNode remove(Comparable key);
/** Returns the value to which the specified key is mapped, or <code>null</code> if this map contains no mapping for the key. */
abstract T get(Comparable key);
/** Returns the value at the given index
* @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= size()) */
abstract T getIndex(int index);
/** Returns the value that was removed from the given index
* @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= size()) */
abstract AbstractNode removeIndex(int index);
/** Returns <code>true</code> if this map contains a mapping for the specified key. */
abstract boolean containsKey(Comparable key);
/** Returns the number os key-value mappings in this map */
abstract int size();
abstract String dump(int level, boolean dumpKeysOnly, boolean dumpNodeIds);
/* **** Uncomment the following to support pretty printing of nodes **** */
// static final AtomicInteger GLOBAL_COUNTER = new AtomicInteger(0);
// protected int counter = GLOBAL_COUNTER.getAndIncrement();
// public String toString() {
// return "" + counter;
// }
/* *********** */
public AbstractNode() {
super();
}
AbstractNode getRoot() {
InnerNode thisParent = this.getParent();
return thisParent == null ? this : thisParent.getRoot();
}
abstract Map.Entry<Comparable,T> removeBiggestKeyValue();
abstract Map.Entry<Comparable,T> removeSmallestKeyValue();
abstract Comparable getSmallestKey();
abstract void addKeyValue(Map.Entry keyValue);
// merge elements from the left node into this node. smf: maybe LeafNode can be a subclass of InnerNode
abstract void mergeWithLeftNode(AbstractNode leftNode, Comparable splitKey);
// the number of _elements_ in this node (not counting sub-nodes)
abstract int shallowSize();
public static Serializable /*byte[]*/ externalizeTreeMap(TreeMap treeMap) {
// return Externalization.externalizeObject(new TreeMapExternalization(treeMap));
return new TreeMapExternalization(treeMap);
// return treeMap;
}
public static TreeMap internalizeTreeMap(Serializable/*byte[]*/ externalizedTreeMap) {
// TreeMapExternalization treeMapExternalization = Externalization.internalizeObject(externalizedTreeMap);
return ((TreeMapExternalization)externalizedTreeMap).toTreeMap();
// return (TreeMap)externalizedTreeMap;
}
private static class TreeMapExternalization implements Serializable {
private static final long serialVersionUID = 1L;
private byte[] serializedTreeMap;
TreeMapExternalization(TreeMap<Comparable,? extends Serializable> treeMap) {
this.serializedTreeMap = Externalization.externalizeSerializable(treeMap);
}
TreeMap toTreeMap() {
return (TreeMap)Externalization.internalizeSerializable(serializedTreeMap);
}
}
///////////////////////////////////////////////////////////////////////
// Buggy implementation because not all Comparables are OIDs. In the InnerNode instances the
// last is an instance of LAST_KEY.
// private static class TreeMapExternalization implements Serializable {
// private static final long serialVersionUID = 1L;
// private Comparable[] keyOids;
// TreeMapExternalization(TreeMap<Comparable,? extends AbstractDomainObject> treeMap) {
// int size = treeMap.size();
// this.keyOids = new Comparable[size];
// int i = 0;
// for (Map.Entry<Comparable,? extends AbstractDomainObject> entry : treeMap.entrySet()) {
// this.keyOids[i] = entry.getKey();
// i++;
// }
// }
// TreeMap toTreeMap() {
// TreeMap treeMap = new TreeMap(BPlusTree.COMPARATOR_SUPPORTING_LAST_KEY);
// for (int i = 0; i < this.keyOids.length; i++) {
// Comparable key = this.keyOids[i];
// treeMap.put(key, FenixFramework.getConfig().getBackEnd().fromOid(key));
// }
// return treeMap;
// }
// }
}