All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.druid.query.rowsandcols.RowsAndColumns Maven / Gradle / Ivy

There is a newer version: 30.0.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.druid.query.rowsandcols;

import org.apache.druid.error.DruidException;
import org.apache.druid.query.rowsandcols.column.Column;
import org.apache.druid.query.rowsandcols.semantic.AppendableRowsAndColumns;
import org.apache.druid.query.rowsandcols.semantic.FramedOnHeapAggregatable;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * An interface representing a chunk of RowsAndColumns.  Essentially a RowsAndColumns is just a batch of rows
 * with columns.
 * 

* This interface has very little prescriptively defined about what *must* be implemented. This is intentional * as there are lots of different possible representations of batch of rows each with their own unique positives * and negatives when it comes to processing. So, any explicit definition of what a RowsAndColumns is will actually, * by definition, end up as optimal for one specific configuration and sub-optimal for others. Instead of trying to * explicitly expand the interface to cover all the different possible ways that someone could want to interace * with a Rows and columns, we rely on semantic interfaces using the {@link RowsAndColumns#as} method instead. *

* That is, the expectation is that anything that works with a RowsAndColumns will tend to first ask the RowsAndColumns * object to become some other interface, for example, a {@link FramedOnHeapAggregatable}. If a RowsAndColumns knows * how to do a good job as the requested interface, it can return its own concrete implementation of the interface and * run the necessary logic in its own optimized fashion. If the RowsAndColumns instance does not know how to implement * the semantic interface, it is expected that a default implementation of the interface can be instantiated on top of * the default column access mechanisms that the RowsAndColumns provides. Such default implementations should be * functionally correct, but are not believed to be optimal. *

* The "default column access mechanisms" here amount to using {@link #findColumn} to load a Column * and then using {@link Column#toAccessor} to access the individual cells of the column. There is also a * {@link Column#as} method which a default implementation might attempt to use to create a more optimal runtime. *

* It is intended that this interface can be used by Frames, Segments and even normal on-heap JVM data structures to * participate in query operations. */ public interface RowsAndColumns { @Nonnull static AppendableRowsAndColumns expectAppendable(RowsAndColumns input) { if (input instanceof AppendableRowsAndColumns) { return (AppendableRowsAndColumns) input; } AppendableRowsAndColumns retVal = input.as(AppendableRowsAndColumns.class); if (retVal == null) { retVal = new AppendableMapOfColumns(input); } return retVal; } static Map, Function> makeAsMap(Class clazz) { Map, Function> retVal = new HashMap<>(); for (Method method : clazz.getMethods()) { if (method.isAnnotationPresent(SemanticCreator.class)) { if (method.getParameterCount() != 0) { throw DruidException.defensive("Method [%s] annotated with SemanticCreator was not 0-argument.", method); } retVal.put(method.getReturnType(), arg -> { try { return method.invoke(arg); } catch (InvocationTargetException | IllegalAccessException e) { throw DruidException.defensive().build(e, "Problem invoking method [%s]", method); } }); } } return retVal; } /** * The set of column names available from the RowsAndColumns * * @return The set of column names available from the RowsAndColumns */ @SuppressWarnings("unreachable") Collection getColumnNames(); /** * The number of rows in the RowsAndColumns object * * @return the integer number of rows */ int numRows(); /** * Finds a column by name. null is returned if the column is not found. The RowsAndColumns object should not * attempt to default not-found columns to pretend as if they exist, instead the user of the RowsAndColumns object * should decide the correct semantic interpretation of a column that does not exist. It is expected that most * locations will choose to believe that the column does exist and is always null, but there are often optimizations * that can effect this same assumption without doing a lot of extra work if the calling code knows that it does not * exist. * * @param name the name of the column to find * @return the Column, if found. null if not found. */ @Nullable Column findColumn(String name); /** * Asks the RowsAndColumns to return itself as a concrete implementation of a specific interface. The interface * asked for will tend to be a semantically-meaningful interface. This method allows the calling code to interrogate * the RowsAndColumns object about whether it can offer a meaningful optimization of the semantic interface. If a * RowsAndColumns cannot do anything specifically optimal for the interface requested, it should return null instead * of trying to come up with its own default implementation. * * @param clazz A class object representing the interface that the calling code wants a concrete implementation of * @param The interface that the calling code wants a concrete implementation of * @return A concrete implementation of the interface, or null if there is no meaningful optimization to be had * through a local implementation of the interface. */ @Nullable T as(Class clazz); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy