/*
 * 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.carbondata.core.indexstore.blockletindex;

/**
 * holder for blocklet info indexes in a Index row
 */
public interface BlockletIndexRowIndexes {

  // Each IndexRow Indexes for blocklet and block index
  int MIN_VALUES_INDEX = 0;

  int MAX_VALUES_INDEX = 1;

  int ROW_COUNT_INDEX = 2;

  int FILE_PATH_INDEX = 3;

  int VERSION_INDEX = 4;

  int SCHEMA_UPDATED_TIME_INDEX = 5;

  int BLOCK_FOOTER_OFFSET = 6;

  int LOCATIONS = 7;

  int BLOCK_LENGTH = 8;

  int BLOCK_MIN_MAX_FLAG = 9;

  // below variables are specific for blocklet index
  int BLOCKLET_INFO_INDEX = 10;

  int BLOCKLET_PAGE_COUNT_INDEX = 11;

  int BLOCKLET_ID_INDEX = 12;

  // Summary row indexes
  int TASK_ROW_COUNT = 0;

  int TASK_MIN_VALUES_INDEX = 1;

  int TASK_MAX_VALUES_INDEX = 2;

  int SUMMARY_INDEX_FILE_NAME = 3;

  int SUMMARY_SEGMENT_ID = 4;

  int TASK_MIN_MAX_FLAG = 5;

  int SUMMARY_INDEX_PATH = 6;
}
