/* 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.relational.cursors; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import xxl.core.collections.bags.Bag; import xxl.core.cursors.MetaDataCursor; import xxl.core.functions.Function; import xxl.core.predicates.Equal; import xxl.core.predicates.Predicate; import xxl.core.relational.metaData.ResultSetMetaDatas; import xxl.core.relational.tuples.Tuple; import xxl.core.util.metaData.CompositeMetaData; import xxl.core.util.metaData.MetaDataException; /** * Operator computing the difference of two metadata cursors. This class uses * the algorithm of {@link xxl.core.cursors.differences.NestedLoopsDifference} * and additionally computes the metadata. The metadata are checked whether * they fit. * * <p>Caution: the runtime is quadratic!</p> */ public class NestedLoopsDifference extends xxl.core.cursors.differences.NestedLoopsDifference<Tuple> implements MetaDataCursor<Tuple, CompositeMetaData<Object, Object>> { /** * An internal variable used for storing the metadata information of this * difference operator. */ protected CompositeMetaData<Object, Object> globalMetaData; /** * Constructs a nested-loops difference operator (metadata cursor) that * computes the difference between two input metadata cursors (R-S). The * parameters are the same compared to * {@link xxl.core.cursors.differences.NestedLoopsDifference}. * * <p>Determines the maximum number of elements that can be stored in the * bag used for the temporal storage of the elements of <code>input1</code> * in main memory: * <pre> * maxTuples = memSize / objectSize - 1 * </pre>.</p> * * @param input1 the first input relation R (metadata cursor) * @param input2 the second input relation S (metadata cursor) containing * the elements that become substracted. This cursor has to support * <code>reset</code>. * @param memSize the maximum amount of available main memory that can be * used for the bag. * @param objectSize the size (bytes) needed to store one object of an * input cursor. * @param newBag a parameterless function delivering an empty bag on * demand. This bag is used to store the elements of the metadata * cursor <code>input1</code>. * @param predicate a binaray predicate that has to determine a match * between an element of <code>input1</code> and an element of * <code>input2</code>. * @param all mode of the difference operation. If the mode is * <code>true</code>, all tuples of the first relation, which have a * counterpart in the second relation, are removed. If the mode is * <code>false</code>, for each tuple of the second relation, only * one tuple of the first relation is removed at most. * @throws IllegalArgumentException if not enough main memory is available. */ public NestedLoopsDifference(MetaDataCursor<Tuple, CompositeMetaData<Object, Object>> input1, MetaDataCursor<? extends Tuple, CompositeMetaData<Object, Object>> input2, int memSize, int objectSize, Function<?, ? extends Bag<Tuple>> newBag, Predicate<? super Tuple> predicate, boolean all) { super(input1, input2, memSize, objectSize, newBag, predicate, all); ResultSetMetaData metaData1 = ResultSetMetaDatas.getResultSetMetaData(input1); ResultSetMetaData metaData2 = ResultSetMetaDatas.getResultSetMetaData(input2); if (ResultSetMetaDatas.RESULTSET_METADATA_COMPARATOR.compare(metaData1, metaData2) != 0) throw new MetaDataException("the difference of the given cursors cannot be computed because they differ in their relational metadata"); globalMetaData = new CompositeMetaData<Object, Object>(); globalMetaData.add(ResultSetMetaDatas.RESULTSET_METADATA_TYPE, metaData1); } /** * Constructs a nested-loops difference operator (metadata cursor) that * computes the difference between two input metadata cursors (R-S). The * parameters are the same compared to * {@link xxl.core.cursors.differences.NestedLoopsDifference}. * * <p>Determines the maximum number of elements that can be stored in the * bag used for the temporal storage of the elements of <code>input1</code> * in main memory: * <pre> * maxTuples = memSize / objectSize - 1 * </pre>.</p> * * <p>This constructor uses the Equal.DEFAULT_INSTANCE predicate to * determine if two objects are equal.</p> * * @param input1 the first input relation R (metadata cursor) * @param input2 the second input relation S (metadata cursor) containing * the elements that become substracted. This cursor has to support * <code>reset</code>. * @param memSize the maximum amount of available main memory that can be * used for the bag. * @param objectSize the size (bytes) needed to store one object of an * input cursor. * @param newBag a parameterless function delivering an empty bag on * demand. This bag is used to store the elements of the metadata * cursor <code>input1</code>. * @param all mode of the difference operation. If the mode is * <code>true</code>, all tuples of the first relation, which have a * counterpart in the second relation, are removed. If the mode is * <code>false</code>, for each tuple of the second relation, only * one tuple of the first relation is removed at most. * @throws IllegalArgumentException if not enough main memory is available. */ public NestedLoopsDifference(MetaDataCursor<Tuple, CompositeMetaData<Object, Object>> input1, MetaDataCursor<? extends Tuple, CompositeMetaData<Object, Object>> input2, int memSize, int objectSize, Function<?, ? extends Bag<Tuple>> newBag, boolean all) { this(input1, input2, memSize, objectSize, newBag, Equal.DEFAULT_INSTANCE, all); } /** * Constructs a nested-loops difference operator (metadata cursor) that * computes the difference between two input result sets (R-S). The * parameters are the same compared to * {@link xxl.core.cursors.differences.NestedLoopsDifference}. * * <p>Determines the maximum number of elements that can be stored in the * bag used for the temporal storage of the elements of <code>input1</code> * in main memory: * <pre> * maxTuples = memSize / objectSize - 1 * </pre>.</p> * * @param input1 the first input relation R (result set) * @param input2 the second input relation S (result set) containing the * elements that become substracted. This cursor has to support * <code>reset</code>. * @param memSize the maximum amount of available main memory that can be * used for the bag. * @param objectSize the size (bytes) needed to store one object of an * input result set. * @param newBag a parameterless function delivering an empty bag on * demand. This bag is used to store the elements of the result set * <code>input1</code>. * @param predicate a binaray predicate that has to determine a match * between an element of <code>input1</code> and an element of * <code>input2</code>. * @param all mode of the difference operation. If the mode is * <code>true</code>, all tuples of the first relation, which have a * counterpart in the second relation, are removed. If the mode is * <code>false</code>, for each tuple of the second relation, only * one tuple of the first relation is removed at most. * @throws IllegalArgumentException if not enough main memory is available. */ public NestedLoopsDifference(ResultSet input1, ResultSet input2, int memSize, int objectSize, Function<?, ? extends Bag<Tuple>> newBag, Predicate<? super Tuple> predicate, boolean all) { this(new ResultSetMetaDataCursor(input1), new ResultSetMetaDataCursor(input2), memSize, objectSize, newBag, predicate, all); } /** * Constructs a nested-loops difference operator (metadata cursor) that * computes the difference between two input result sets (R-S). The * parameters are the same compared to * {@link xxl.core.cursors.differences.NestedLoopsDifference}. * * <p>Determines the maximum number of elements that can be stored in the * bag used for the temporal storage of the elements of <code>input1</code> * in main memory: * <pre> * maxTuples = memSize / objectSize - 1 * </pre>.</p> * * <p>This constructor uses the Equal.DEFAULT_INSTANCE predicate to * determine if two objects are equal.</p> * * @param input1 the first input relation R (result set) * @param input2 the second input relation S (result set) containing the * elements that become substracted. This cursor has to support * <code>reset</code>. * @param memSize the maximum amount of available main memory that can be * used for the bag. * @param objectSize the size (bytes) needed to store one object of an * input result set. * @param newBag a parameterless function delivering an empty bag on * demand. This bag is used to store the elements of the result set * <code>input1</code>. * @param all mode of the difference operation. If the mode is * <code>true</code>, all tuples of the first relation, which have a * counterpart in the second relation, are removed. If the mode is * <code>false</code>, for each tuple of the second relation, only * one tuple of the first relation is removed at most. * @throws IllegalArgumentException if not enough main memory is available. */ public NestedLoopsDifference(ResultSet input1, ResultSet input2, int memSize, int objectSize, Function<?, ? extends Bag<Tuple>> newBag, boolean all) { this(new ResultSetMetaDataCursor(input1), new ResultSetMetaDataCursor(input2), memSize, objectSize, newBag, Equal.DEFAULT_INSTANCE, all); } /** * Returns the metadata information for this metadata-cursor as a composite * metadata ({@link CompositeMetaData}). * * @return the metadata information for this metadata-cursor as a composite * metadata ({@link CompositeMetaData}). */ public CompositeMetaData<Object, Object> getMetaData() { return globalMetaData; } }