/**
 * 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.hadoop.hbase.regionserver;

import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hadoop.hbase.util.Bytes;

import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;

/**
 * A chunk of memory out of which allocations are sliced.
 */
@InterfaceAudience.Private
public abstract class Chunk {
  /** Actual underlying data */
  protected ByteBuffer data;

  protected static final int UNINITIALIZED = -1;
  protected static final int OOM = -2;
  /**
   * Offset for the next allocation, or the sentinel value -1 which implies that the chunk is still
   * uninitialized.
   */
  protected AtomicInteger nextFreeOffset = new AtomicInteger(UNINITIALIZED);

  /** Total number of allocations satisfied from this buffer */
  protected AtomicInteger allocCount = new AtomicInteger();

  /** Size of chunk in bytes */
  protected final int size;

  // The unique id associated with the chunk.
  private final int id;

  // indicates if the chunk is formed by ChunkCreator#MemstorePool
  private final boolean fromPool;

  /**
   * Create an uninitialized chunk. Note that memory is not allocated yet, so
   * this is cheap.
   * @param size in bytes
   * @param id the chunk id
   */
  public Chunk(int size, int id) {
    this(size, id, false);
  }

  /**
   * Create an uninitialized chunk. Note that memory is not allocated yet, so
   * this is cheap.
   * @param size in bytes
   * @param id the chunk id
   * @param fromPool if the chunk is formed by pool
   */
  public Chunk(int size, int id, boolean fromPool) {
    this.size = size;
    this.id = id;
    this.fromPool = fromPool;
  }

  int getId() {
    return this.id;
  }

  boolean isFromPool() {
    return this.fromPool;
  }

  boolean isJumbo() {
    return size > ChunkCreator.getInstance().getChunkSize();
  }

  boolean isIndexChunk() {
    return size == ChunkCreator.getInstance().getChunkSize(ChunkCreator.ChunkType.INDEX_CHUNK);
  }

  /**
   * Actually claim the memory for this chunk. This should only be called from the thread that
   * constructed the chunk. It is thread-safe against other threads calling alloc(), who will block
   * until the allocation is complete.
   */
  public void init() {
    assert nextFreeOffset.get() == UNINITIALIZED;
    try {
      allocateDataBuffer();
    } catch (OutOfMemoryError e) {
      boolean failInit = nextFreeOffset.compareAndSet(UNINITIALIZED, OOM);
      assert failInit; // should be true.
      throw e;
    }
    // Mark that it's ready for use
    // Move 4 bytes since the first 4 bytes are having the chunkid in it
    boolean initted = nextFreeOffset.compareAndSet(UNINITIALIZED, Bytes.SIZEOF_INT);
    // We should always succeed the above CAS since only one thread
    // calls init()!
    Preconditions.checkState(initted, "Multiple threads tried to init same chunk");
  }

  abstract void allocateDataBuffer();

  /**
   * Reset the offset to UNINITIALIZED before before reusing an old chunk
   */
  void reset() {
    if (nextFreeOffset.get() != UNINITIALIZED) {
      nextFreeOffset.set(UNINITIALIZED);
      allocCount.set(0);
    }
  }

  /**
   * Try to allocate <code>size</code> bytes from the chunk.
   * If a chunk is tried to get allocated before init() call, the thread doing the allocation
   * will be in busy-wait state as it will keep looping till the nextFreeOffset is set.
   * @return the offset of the successful allocation, or -1 to indicate not-enough-space
   */
  public int alloc(int size) {
    while (true) {
      int oldOffset = nextFreeOffset.get();
      if (oldOffset == UNINITIALIZED) {
        // The chunk doesn't have its data allocated yet.
        // Since we found this in curChunk, we know that whoever
        // CAS-ed it there is allocating it right now. So spin-loop
        // shouldn't spin long!
        Thread.yield();
        continue;
      }
      if (oldOffset == OOM) {
        // doh we ran out of ram. return -1 to chuck this away.
        return -1;
      }

      if (oldOffset + size > data.capacity()) {
        return -1; // alloc doesn't fit
      }
      // TODO : If seqID is to be written add 8 bytes here for nextFreeOFfset
      // Try to atomically claim this chunk
      if (nextFreeOffset.compareAndSet(oldOffset, oldOffset + size)) {
        // we got the alloc
        allocCount.incrementAndGet();
        return oldOffset;
      }
      // we raced and lost alloc, try again
    }
  }

  /**
   * @return This chunk's backing data.
   */
  ByteBuffer getData() {
    return this.data;
  }

  @Override
  public String toString() {
    return "Chunk@" + System.identityHashCode(this) + " allocs=" + allocCount.get() + "waste="
        + (data.capacity() - nextFreeOffset.get());
  }

  @VisibleForTesting
  int getNextFreeOffset() {
    return this.nextFreeOffset.get();
  }
}
