/*
 * 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.datastore.chunk.store.impl.unsafe;

import org.apache.carbondata.core.constants.CarbonCommonConstants;
import org.apache.carbondata.core.datastore.chunk.store.DimensionDataChunkStore;
import org.apache.carbondata.core.memory.CarbonUnsafe;
import org.apache.carbondata.core.memory.MemoryBlock;
import org.apache.carbondata.core.memory.UnsafeMemoryManager;
import org.apache.carbondata.core.scan.result.vector.CarbonColumnVector;
import org.apache.carbondata.core.scan.result.vector.ColumnVectorInfo;
import org.apache.carbondata.core.util.ThreadLocalTaskInfo;

/**
 * Responsibility is to store dimension data in memory. storage can be on heap
 * or offheap.
 */
public abstract class UnsafeAbstractDimensionDataChunkStore implements DimensionDataChunkStore {

  /**
   * memory block for data page
   */
  protected MemoryBlock dataPageMemoryBlock;

  /**
   * to check whether dimension column was explicitly sorted or not
   */
  protected boolean isExplicitSorted;

  /**
   * is memory released
   */
  protected boolean isMemoryReleased;

  /**
   * length of the actual data
   */
  protected int dataLength;

  /**
   * offset of the inverted index reverse
   */
  protected long invertedIndexReverseOffset;

  /**
   * to validate whether data is already kept in memory or not
   */
  protected boolean isMemoryOccupied;

  private final String taskId = ThreadLocalTaskInfo.getCarbonTaskInfo().getTaskId();

  /**
   * Constructor
   *
   * @param totalSize      total size of the data to be kept
   * @param isInvertedIdex is inverted index present
   * @param numberOfRows   total number of rows
   */
  public UnsafeAbstractDimensionDataChunkStore(long totalSize, boolean isInvertedIdex,
      int numberOfRows, int dataLength) {
    // allocating the data page
    this.dataPageMemoryBlock = UnsafeMemoryManager.allocateMemoryWithRetry(taskId, totalSize);

    this.dataLength = dataLength;
    this.isExplicitSorted = isInvertedIdex;
  }

  /**
   * Below method will be used to put the rows and its metadata in offheap
   *
   * @param invertedIndex        inverted index to be stored
   * @param invertedIndexReverse inverted index reverse to be stored
   * @param data                 data to be stored
   */
  @Override
  public void putArray(final int[] invertedIndex, final int[] invertedIndexReverse,
      final byte[] data) {
    assert (!isMemoryOccupied);
    this.invertedIndexReverseOffset = dataLength;
    if (isExplicitSorted) {
      this.invertedIndexReverseOffset +=
          invertedIndex.length * CarbonCommonConstants.INT_SIZE_IN_BYTE;
    }
    // copy the data to memory
    CarbonUnsafe.getUnsafe()
        .copyMemory(data, CarbonUnsafe.BYTE_ARRAY_OFFSET, dataPageMemoryBlock.getBaseObject(),
            dataPageMemoryBlock.getBaseOffset(), this.dataLength);
    // if inverted index is present then copy the inverted index
    // and reverse inverted index to memory
    if (isExplicitSorted) {
      CarbonUnsafe.getUnsafe().copyMemory(invertedIndex, CarbonUnsafe.INT_ARRAY_OFFSET,
          dataPageMemoryBlock.getBaseObject(), dataPageMemoryBlock.getBaseOffset() + dataLength,
          invertedIndex.length * CarbonCommonConstants.INT_SIZE_IN_BYTE);
      CarbonUnsafe.getUnsafe().copyMemory(invertedIndexReverse, CarbonUnsafe.INT_ARRAY_OFFSET,
          dataPageMemoryBlock.getBaseObject(),
          dataPageMemoryBlock.getBaseOffset() + this.invertedIndexReverseOffset,
          invertedIndexReverse.length * CarbonCommonConstants.INT_SIZE_IN_BYTE);
    }
  }

  @Override
  public void fillVector(int[] invertedIndex, int[] invertedIndexReverse, byte[] data,
      ColumnVectorInfo vectorInfo) {
    throw new UnsupportedOperationException("This method not supposed to be called here");
  }

  /**
   * Below method will be used to free the memory occupied by the column chunk
   */
  @Override
  public void freeMemory() {
    if (isMemoryReleased) {
      return;
    }
    // free data page memory
    UnsafeMemoryManager.INSTANCE.freeMemory(taskId, dataPageMemoryBlock);
    isMemoryReleased = true;
    this.dataPageMemoryBlock = null;
    this.isMemoryOccupied = false;
  }

  /**
   * Below method will be used to get the inverted index
   *
   * @param rowId row id
   * @return inverted index based on row id passed
   */
  @Override
  public int getInvertedIndex(int rowId) {
    return CarbonUnsafe.getUnsafe().getInt(dataPageMemoryBlock.getBaseObject(),
        dataPageMemoryBlock.getBaseOffset() + dataLength + ((long)rowId
            * CarbonCommonConstants.INT_SIZE_IN_BYTE));
  }

  /**
   * Below method will be used to get the reverse inverted index
   *
   * @param rowId row id
   * @return inverted index based on row id passed
   */
  @Override
  public int getInvertedReverseIndex(int rowId) {
    return CarbonUnsafe.getUnsafe().getInt(dataPageMemoryBlock.getBaseObject(),
        dataPageMemoryBlock.getBaseOffset() + this.invertedIndexReverseOffset + ((long)rowId
            * CarbonCommonConstants.INT_SIZE_IN_BYTE));
  }

  /**
   * Below method will be used to get the surrogate key of the based on the row
   * id passed
   *
   * @param rowId row id
   * @return surrogate key
   */
  @Override
  public int getSurrogate(int rowId) {
    throw new UnsupportedOperationException("Operation not supported");
  }

  /**
   * @return size of each column value
   */
  @Override
  public int getColumnValueSize() {
    throw new UnsupportedOperationException("Operation not supported");
  }

  /**
   * @return whether column was explicitly sorted or not
   */
  @Override
  public boolean isExplicitSorted() {
    return isExplicitSorted;
  }

  /**
   * Below method will be used to fill the row values to data array
   *
   * @param rowId  row id of the data to be filled
   * @param data   buffer in which data will be filled
   * @param offset off the of the buffer
   */
  @Override
  public void fillRow(int rowId, byte[] data, int offset) {
    throw new UnsupportedOperationException("Operation not supported");
  }

  @Override
  public void fillRow(int rowId, CarbonColumnVector vector, int vectorRow) {
    throw new UnsupportedOperationException("Operation not supported");
  }
}
