/* 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.util.Map;
import xxl.core.collections.bags.Bag;
import xxl.core.collections.queues.Queue;
import xxl.core.cursors.Cursor;
import xxl.core.cursors.MetaDataCursor;
import xxl.core.functions.Function;
import xxl.core.relational.metaData.ResultSetMetaDatas;
import xxl.core.relational.tuples.Tuple;
import xxl.core.util.metaData.CompositeMetaData;
/**
* A nested-loops grouper is an implementation of the group operator. It is
* based on {@link xxl.core.cursors.groupers.NestedLoopsGrouper} and
* additionally forwards the metadata.
*
* <p>A call to the <code>next</code> method returns a cursor containing all
* elements of a group.</p>
*
* <p>Usually, an {@link xxl.core.relational.cursors.Aggregator} is applied on
* the output of a grouper.</p>
*/
public class NestedLoopsGrouper extends xxl.core.cursors.groupers.NestedLoopsGrouper<Tuple> implements MetaDataCursor<Cursor<Tuple>, CompositeMetaData<Object, Object>> {
/**
* An internal variable used for storing the metadata information of this
* group operator.
*/
protected CompositeMetaData<Object, Object> globalMetaData;
/**
* Constructs an instance of the nested-loops grouper operator. Determines
* the maximum number of keys that can be stored in the main memory map
* <pre>
* ((memSize - objectSize) / keySize) - 1
* </pre>
* This formula is based on the assumption that only the keys, i.e., the
* map, is stored in main memory whereas the bags storing the input
* cursor's elements are located in external memory.
*
* @param cursor the metadata cursor containing input elements.
* @param mapping an unary mapping function returning a key to a given
* value.
* @param map the map which is used for storing the keys in main memory.
* @param memSize the maximum amount of available main memory (bytes) for
* the map.
* @param objectSize the size (bytes) needed to store one element.
* @param keySize the size (bytes) a key needs in main memory.
* @param newBag a parameterless function returning an empty bag.
* @param newQueue a parameterless function returning an empty queue.
* @throws IllegalArgumentException if not enough main memory is available.
*/
public NestedLoopsGrouper(MetaDataCursor<? extends Tuple, CompositeMetaData<Object, Object>> cursor, Function<? super Tuple, ? extends Object> mapping, Map<Object, Bag<Tuple>> map, int memSize, int objectSize, int keySize, Function<?, ? extends Bag<Tuple>> newBag, Function<?, ? extends Queue<Tuple>> newQueue) {
super(cursor, mapping, map, memSize, objectSize, keySize, newBag, newQueue);
globalMetaData = new CompositeMetaData<Object, Object>();
globalMetaData.add(ResultSetMetaDatas.RESULTSET_METADATA_TYPE, ResultSetMetaDatas.getResultSetMetaData(cursor));
}
/**
* Constructs an instance of the nested-loops grouper operator. Determines
* the maximum number of keys that can be stored in the main memory map
* <pre>
* ((memSize - objectSize) / keySize) - 1
* </pre>
* This formula is based on the assumption that only the keys, i.e., the
* map, is stored in main memory whereas the bags storing the input
* cursor's elements are located in external memory. Uses default factory
* methods for list-bags and array-queues.
*
* @param cursor the metadata cursor containing input elements.
* @param mapping an unary mapping function returning a key to a given
* value.
* @param map the map which is used for storing the keys in main memory.
* @param memSize the maximum amount of available main memory (bytes) for
* the map.
* @param objectSize the size (bytes) needed to store one element.
* @param keySize the size (bytes) a key needs in main memory.
* @throws IllegalArgumentException if not enough main memory is available.
*/
public NestedLoopsGrouper(MetaDataCursor<? extends Tuple, CompositeMetaData<Object, Object>> cursor, Function<? super Tuple, ? extends Object> mapping, Map<Object, Bag<Tuple>> map, int memSize, int objectSize, int keySize) {
super(cursor, mapping, map, memSize, objectSize, keySize);
globalMetaData = new CompositeMetaData<Object, Object>();
globalMetaData.add(ResultSetMetaDatas.RESULTSET_METADATA_TYPE, ResultSetMetaDatas.getResultSetMetaData(cursor));
}
/**
* Constructs an instance of the nested-loops grouper operator. Determines
* the maximum number of keys that can be stored in the main memory map
* <pre>
* ((memSize - objectSize) / keySize) - 1
* </pre>
* This formula is based on the assumption that only the keys, i.e., the
* map, is stored in main memory whereas the bags storing the input
* result set's elements are located in external memory.
*
* @param resultSet the result set containing input elements.
* @param mapping an unary mapping function returning a key to a given
* value.
* @param map the map which is used for storing the keys in main memory.
* @param memSize the maximum amount of available main memory (bytes) for
* the map.
* @param objectSize the size (bytes) needed to store one element.
* @param keySize the size (bytes) a key needs in main memory.
* @param newBag a parameterless function returning an empty bag.
* @param newQueue a parameterless function returning an empty queue.
* @throws IllegalArgumentException if not enough main memory is available.
*/
public NestedLoopsGrouper(ResultSet resultSet, Function<? super Tuple, ? extends Object> mapping, Map<Object, Bag<Tuple>> map, int memSize, int objectSize, int keySize, Function<?, ? extends Bag<Tuple>> newBag, Function<?, ? extends Queue<Tuple>> newQueue) {
this(new ResultSetMetaDataCursor(resultSet), mapping, map, memSize, objectSize, keySize, newBag, newQueue);
}
/**
* Constructs an instance of the nested-loops grouper operator. Determines
* the maximum number of keys that can be stored in the main memory map
* <pre>
* ((memSize - objectSize) / keySize) - 1
* </pre>
* This formula is based on the assumption that only the keys, i.e., the
* map, is stored in main memory whereas the bags storing the input
* result set's elements are located in external memory. Uses default
* factory methods for list-bags and array-queues.
*
* @param resultSet the result set containing input elements.
* @param mapping an unary mapping function returning a key to a given
* value.
* @param map the map which is used for storing the keys in main memory.
* @param memSize the maximum amount of available main memory (bytes) for
* the map.
* @param objectSize the size (bytes) needed to store one element.
* @param keySize the size (bytes) a key needs in main memory.
* @throws IllegalArgumentException if not enough main memory is available.
*/
public NestedLoopsGrouper(ResultSet resultSet, Function<? super Tuple, ? extends Object> mapping, Map<Object, Bag<Tuple>> map, int memSize, int objectSize, int keySize) {
this(new ResultSetMetaDataCursor(resultSet), mapping, map, memSize, objectSize, keySize);
}
/**
* 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;
}
}