/* 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.vLengthBPlusTree; import java.util.Iterator; import xxl.core.cursors.Cursor; import xxl.core.cursors.filters.Filter; import xxl.core.functions.Function; import xxl.core.indexStructures.Separator; import xxl.core.predicates.AbstractPredicate; /** * Skeleton class which provides basic functionality for implementing own split strategies for @see {@link VariableLengthBPlusTree} * * @param <D> Type of the data which is going to be stored in leaf nodes of B+Tree * @param <K> Type of key objects */ public abstract class SplitStrategy<D,K> implements Splitter { /** * function for computing the entry size */ protected Function<D, Integer> getEntrySize; /** * function for computing separator size */ protected Function<Separator, Integer> getSeparatorSize; /** * factory function for creating separtors */ protected Function<K, Separator> createSeparator; /** * function for extracting keys from objects */ protected Function<D, K> createKey; /** * size of the intern id of the back end container where the nodes of B+tree are stored */ protected int containerIdSize; /** * empty constructor. The strategy is parameterized and initialized through @see {@link #initialize(Function, Function, Function, Function, int)} method */ public SplitStrategy(){ } /** * * @param getEntrySize * @param getSeparatorSize * @param createKey * @param createSeparator * @return */ public SplitStrategy initialize(Function<D, Integer> getEntrySize, Function<Separator, Integer> getSeparatorSize, Function<D, K> createKey, Function<K, Separator> createSeparator, int containerIdSize){ this.getEntrySize = getEntrySize; this.getSeparatorSize = getSeparatorSize; this.createSeparator = createSeparator; this.createKey = createKey; this.containerIdSize = containerIdSize; return this; } /** * * @param dataObject * @return */ public K getKey(D dataObject){ return this.createKey.invoke(dataObject); } /** * * @param separator * @return */ public Separator createSeparator(K keyOfdataObject){ return this.createSeparator.invoke(keyOfdataObject); } /** * * @param dataObject * @return */ public int getObjectSize(D dataObject){ return this.getEntrySize.invoke(dataObject); } /** * * @param separator * @return */ public int getSeparatorSize(Separator separator){ return this.getSeparatorSize.invoke(separator); } /** * * @return */ public Cursor<Separator> filterRange(Iterator<Separator> entries, final int minLoad, final int maxLoad){ return new Filter<Separator>(entries, new AbstractPredicate<Separator>(){ /** * */ int accLoad; public boolean invoke(Separator separator){ accLoad += getSeparatorSize.invoke(separator); return accLoad > minLoad && accLoad < maxLoad; } } ); } }