package pt.ist.fenixframework.adt.bplustree; import java.io.Serializable; // import java.util.concurrent.atomic.AtomicInteger; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import pt.ist.fenixframework.FenixFramework; import pt.ist.fenixframework.core.Externalization; /** The keys comparison function should be consistent with equals. */ public abstract class AbstractNode<T extends Serializable> 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(); /** Returns the keys mapped in this map */ abstract Collection<? extends Comparable> getKeys(); 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(); abstract Iterator<? extends Comparable> keysIterator(); /* * We need to ensure that no DomainObjects escape in the serialization. This would be a problem * if 'someone' (e.g. Infinispan in clustered mode) needed to internalize a D.O. (hidden in a * treemap entry) while the FenixFramework was still running its static initialization code. So * we convert the TreeMap to/from a byte[] every time it is externalized/internalize by the FF. * We wrap it in a Serializable class (TreeMapExternalization) ,because some backends (e.g. OGM) * don't deal well with byte[] yet. */ 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); } } }