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

org.apache.druid.frame.read.FrameReader Maven / Gradle / Ivy

There is a newer version: 31.0.0
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.frame.read;

import com.google.common.base.Preconditions;
import org.apache.druid.frame.Frame;
import org.apache.druid.frame.field.FieldReader;
import org.apache.druid.frame.field.FieldReaders;
import org.apache.druid.frame.key.FrameComparisonWidget;
import org.apache.druid.frame.key.FrameComparisonWidgetImpl;
import org.apache.druid.frame.key.KeyColumn;
import org.apache.druid.frame.read.columnar.FrameColumnReader;
import org.apache.druid.frame.read.columnar.FrameColumnReaders;
import org.apache.druid.frame.segment.row.FrameCursorFactory;
import org.apache.druid.frame.write.FrameWriterUtils;
import org.apache.druid.java.util.common.IAE;
import org.apache.druid.java.util.common.ISE;
import org.apache.druid.segment.CursorFactory;
import org.apache.druid.segment.column.ColumnCapabilities;
import org.apache.druid.segment.column.ColumnType;
import org.apache.druid.segment.column.RowSignature;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Embeds the logic to read frames with a given {@link RowSignature}.
 *
 * Stateless and immutable.
 */
public class FrameReader
{
  private final RowSignature signature;

  // Column readers, for columnar frames.
  private final List columnReaders;

  // Field readers, for row-based frames.
  private final List fieldReaders;

  private FrameReader(
      final RowSignature signature,
      final List columnReaders,
      final List fieldReaders
  )
  {
    this.signature = signature;
    this.columnReaders = columnReaders;
    this.fieldReaders = fieldReaders;
  }

  /**
   * Create a reader for frames with a given {@link RowSignature}. The signature must exactly match the frames to be
   * read, or else behavior is undefined.
   * If the columnType is null, we store the data as {@link ColumnType#NESTED_DATA}. This can be done if we know that
   * the data that we receive can be serded generically using the nested data. It is currently used in the brokers to
   * store the data with unknown types into frames.
   *
   * @param signature signature used to generate the reader
   */
  public static FrameReader create(final RowSignature signature)
  {
    // Double-check that the frame does not have any disallowed field names. Generally, we expect this to be
    // caught on the write side, but we do it again here for safety.
    final Set disallowedFieldNames = FrameWriterUtils.findDisallowedFieldNames(signature);
    if (!disallowedFieldNames.isEmpty()) {
      throw new IAE("Disallowed field names: %s", disallowedFieldNames);
    }

    final List columnReaders = new ArrayList<>(signature.size());
    final List fieldReaders = new ArrayList<>(signature.size());

    for (int columnNumber = 0; columnNumber < signature.size(); columnNumber++) {
      final ColumnType columnType =
          Preconditions.checkNotNull(
              signature.getColumnType(columnNumber).orElse(null),
              "Type for column [%s]",
              signature.getColumnName(columnNumber)
          );

      fieldReaders.add(FieldReaders.create(signature.getColumnName(columnNumber), columnType));
      columnReaders.add(FrameColumnReaders.create(signature.getColumnName(columnNumber), columnNumber, columnType));
    }

    return new FrameReader(signature, columnReaders, fieldReaders);
  }

  public RowSignature signature()
  {
    return signature;
  }

  /**
   * Returns capabilities for a particular column in a particular frame.
   * 

* Preferred over {@link RowSignature#getColumnCapabilities(String)} when reading a particular frame, because this * method has more insight into what's actually going on with that specific frame (nulls, multivalue, etc). The * RowSignature version is based solely on type. */ @Nullable public ColumnCapabilities columnCapabilities(final Frame frame, final String columnName) { final int columnNumber = signature.indexOf(columnName); if (columnNumber < 0) { return null; } else { switch (frame.type()) { case COLUMNAR: // Better than frameReader.frameSignature().getColumnCapabilities(columnName), because this method has more // insight into what's actually going on with this column (nulls, multivalue, etc). return columnReaders.get(columnNumber).readColumn(frame).getCapabilities(); default: return signature.getColumnCapabilities(columnName); } } } /** * Create a {@link CursorFactory} for the given frame. */ public CursorFactory makeCursorFactory(final Frame frame) { switch (frame.type()) { case COLUMNAR: return new org.apache.druid.frame.segment.columnar.FrameCursorFactory(frame, signature, columnReaders); case ROW_BASED: return new FrameCursorFactory(frame, this, fieldReaders); default: throw new ISE("Unrecognized frame type [%s]", frame.type()); } } /** * Create a {@link FrameComparisonWidget} for the given frame. *

* Only possible for frames of type {@link org.apache.druid.frame.FrameType#ROW_BASED}. The provided * sortColumns must be a prefix of {@link #signature()}. */ public FrameComparisonWidget makeComparisonWidget(final Frame frame, final List keyColumns) { FrameWriterUtils.verifySortColumns(keyColumns, signature); return FrameComparisonWidgetImpl.create(frame, signature, keyColumns, fieldReaders.subList(0, keyColumns.size())); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy