/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.indexStructures; import java.util.Comparator; /** * This class describes the known separtors of the B+ tree. A <tt>Separtor</tt> is * a simple key (for example an Integer). The <tt>Separator</tt> of a query is * a closed intervall [min, max]. With the contructors of the class Separator Separators of * every type can be created. * This class uses the interface {@link java.lang.Comparable} as a key class. Since * the interface {@link java.lang.Comparable} does not support the method clone() we have * to let {@link Separator#clone() clone()} abstract here. * To use this class you only have to extend it to a concret class and implement the abstract method * {@link Separator#clone()}. * For Example: * <pre><code> public class IntSeparator extends BPlusTree.Separator { public IntSeparator(Integer key) { super(key); } public Object clone() { return new IntSeparator(new Integer(((Integer)sepValue).intValue())); } } </code></pre> * * @see Descriptor * @see Comparable */ public abstract class Separator implements Descriptor, Comparable { /** This is the default Comparator for <tt>Separators</tt>. It is used to implement the method * {@link Separator#compareTo(Object)}. */ public static final Comparator DEFAULT_COMPARATOR= new Comparator() { /** Compares two <tt>Separators</tt>. If a <tt>Separator</tt> is indefinite it is treated as a minimum. * * @return a integer value which indicates how the both <tt>Separators</tt> lie to each other. * The result is as follows: * <ul> * <li> 0 if both <tt>Separators</tt> are indefinite or both are definite and the separation values are * equals.</li> * <li> -1 if only the first <tt>Separator</tt> is indefinite or both are definite and the separation value of the * first <tt>Separator</tt> is smaller than the separation value of the second one. </li> * <li> 1 if only the second <tt>Separator</tt> is indefinite or both are definite and the separation value of the * first <tt>Separator</tt> is bigger than the separation value of the second one.</li> * <ul> */ public int compare(Object o1, Object o2) { Separator sep1=(Separator) o1; Separator sep2=(Separator) o2; if(!sep1.isDefinite()&& !sep2.isDefinite()) return 0; if(!sep1.isDefinite()) return -1; if(!sep2.isDefinite()) return 1; return sep1.sepValue.compareTo(sep2.sepValue); } }; /**The separation value. */ protected Comparable sepValue; /** Creates a new <tt>Separator</tt> with a given separation value. * * @param sepValue the separation value of the new <tt>Separator</tt> */ public Separator(Comparable sepValue) { this.sepValue=sepValue; } /** Gives the separation value of this <tt>Separator</tt>. * * @return the separation value of this <tt>Separator</tt> */ public Comparable sepValue() { return sepValue; } /** Updates the old separation value of this <tt>Separator</tt> by a new separation value. * * @param newSepValue the new separation value */ public void updateSepValue(Comparable newSepValue) { this.sepValue=newSepValue; } /** Checks whether a given key has to be on the left or right side of this <tt>Separator</tt>. * * @param key the key whose position has to be determined * @return <tt>false</tt> if this <tt>Separator</tt> is definite and its separation value is smaller than the given key, <tt>true</tt> * otherwise */ public boolean isRightOf(Comparable key) { if(!isDefinite()) return false; return sepValue.compareTo(key)>=0; } /** Checks whether the separation value of this <tt>Separator</tt> is definite (not null). * * @return <tt>true</tt> if the separation value is not <tt>null</tt>, <tt>false</tt> otherwise. */ public boolean isDefinite() { return sepValue!=null; } /** Compares the current <tt>Separator</tt> with another one by using the default <tt>Comparator</tt> * of this class. * * @return a integer value which indicates how the both <tt>Separators</tt> lie to each other. * The result is as follows: * <ul> * <li> 0 if both <tt>Separators</tt> are indefinite or both are definite and the separation values are equals.</li> * <li> -1 if only the current <tt>Separator</tt> is indefinite or both are definite and the separation value of the * current <tt>Separator</tt> is smaller than the separation value of the given one. </li> * <li> 1 if only the given <tt>Separator</tt> is indefinite or both are definite and the separation value of the * current <tt>Separator</tt> is bigger than the separation value of the given one.</li> * <ul> * * @param sep separator to compare to * @see #DEFAULT_COMPARATOR */ public int compareTo(Object sep) { return DEFAULT_COMPARATOR.compare(this, sep); } /** Unsupported operation. * * @param descriptor unused * @return never returns * @throws UnsupportedOperationException */ public boolean overlaps(Descriptor descriptor) { throw new UnsupportedOperationException(); } /** Unsupported operation. * * @param descriptor unused * @return never returns * @throws UnsupportedOperationException */ public boolean contains(Descriptor descriptor){ throw new UnsupportedOperationException(); } /** Computes the union of this and a given <tt>Separator</tt>. It sets the separation value of the current * <tt>Separator</tt> to the minimum of both separation values. * * @param descriptor has to be an instance of the class <tt>Separator</tt> */ public void union(Descriptor descriptor) { if(!(descriptor instanceof Separator)|| !isDefinite()) return; Separator sep=(Separator)descriptor; if(!sep.isDefinite()|| sepValue.compareTo(sep.sepValue)>0) this.sepValue=sep.sepValue; } /** Checks whether the current <tt>Separator</tt> equals the given object by using the method * {@link Separator#compareTo(Object)}. * * @param object the object to be compared for equality with this <tt>Seperator</tt> * @return <tt>true</tt> if the method {@link Separator#compareTo(Object)} return 0 and <tt>false</tt> otherwise. */ public boolean equals(Object object) { return compareTo(object)==0; } /* (non-Javadoc) * @see java.lang.Object#toString() */ public String toString() { StringBuffer sb=new StringBuffer("["); if(isDefinite()) sb.append(">="+sepValue); else sb.append("*"); sb.append("]"); return sb.toString(); } /** Creates a physical copy of the current <tt>Separator</tt>. * * @return a physical copy of the current <tt>Separator</tt> * * @see java.lang.Object#clone() */ public abstract Object clone(); }