/*
 * 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.iotdb.db.queryengine.execution.operator.process.join.merge;

import org.apache.iotdb.tsfile.read.common.block.TsBlock;
import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
import org.apache.iotdb.tsfile.read.common.block.column.TimeColumnBuilder;

/** used to merge columns belonging to same series into one column. */
public interface ColumnMerger {

  /**
   * judge whether TsBlock at tsBlockIndex is empty.
   *
   * @param tsBlockIndex index
   * @param inputTsBlocks input TsBlock array
   * @param inputIndex current index for each input TsBlock and size of it is equal to inputTsBlocks
   * @return true if TsBlock at tsBlockIndex is null or its current read index is larger than its
   *     size
   */
  static boolean empty(int tsBlockIndex, TsBlock[] inputTsBlocks, int[] inputIndex) {
    return inputTsBlocks[tsBlockIndex] == null
        || inputTsBlocks[tsBlockIndex].getPositionCount() == inputIndex[tsBlockIndex];
  }

  /**
   * merge columns belonging to same series into one column, merge until each input column's time is
   * larger than currentEndTime.
   *
   * @param inputTsBlocks all source TsBlocks, some of which will contain source column
   * @param inputIndex start index for each source TsBlock and size of it is equal to inputTsBlocks,
   *     we should only read from this array and not update it because others will use the start
   *     index value in inputIndex array
   * @param updatedInputIndex current index for each source TsBlock after merging
   * @param timeBuilder result time column, which is already generated and used to indicate each
   *     row's timestamp
   * @param currentEndTime merge until each input column's time is larger than currentEndTime
   * @param columnBuilder used to write merged value into
   */
  void mergeColumn(
      TsBlock[] inputTsBlocks,
      int[] inputIndex,
      int[] updatedInputIndex,
      TimeColumnBuilder timeBuilder,
      long currentEndTime,
      ColumnBuilder columnBuilder);

  /**
   * merge columns belonging to same series into one column, merge just one row whose time is equal
   * to currentTime.
   *
   * @param inputTsBlocks all source TsBlocks, some of which will contain source column
   * @param inputIndex start index for each source TsBlock and size of it is equal to inputTsBlocks,
   *     we should only read from this array and not update it because others will use the start
   *     index value in inputIndex array
   * @param updatedInputIndex current index for each source TsBlock after merging
   * @param currentTime merge just one row whose time is equal to currentTime
   * @param columnBuilder used to write merged value into
   */
  void mergeColumn(
      TsBlock[] inputTsBlocks,
      int[] inputIndex,
      int[] updatedInputIndex,
      long currentTime,
      ColumnBuilder columnBuilder);
}
