content: /*
   * 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.arrow.memory;
  
  /**
   * ReferenceManager is the reference count for one or more allocations.
   *
   * <p>In order to integrate with the core {@link BufferAllocator} implementation, the allocation
   * itself should be represented by an {@link AllocationManager}, though this is not required by the
   * API.
   */
  public interface ReferenceManager {
  
    /**
     * Return the reference count.
     *
     * @return reference count
     */
    int getRefCount();
  
    /**
     * Decrement this reference manager's reference count by 1 for the associated underlying memory.
     * If the reference count drops to 0, it implies that ArrowBufs managed by this reference manager
     * no longer need access to the underlying memory
     *
     * @return true if ref count has dropped to 0, false otherwise
     */
    boolean release();
  
    /**
     * Decrement this reference manager's reference count for the associated underlying memory. If the
     * reference count drops to 0, it implies that ArrowBufs managed by this reference manager no
     * longer need access to the underlying memory
     *
     * @param decrement the count to decrease the reference count by
     * @return the new reference count
     */
    boolean release(int decrement);
  
    /**
     * Increment this reference manager's reference count by 1 for the associated underlying memory.
     */
    void retain();
  
    /**
     * Increment this reference manager's reference count by a given amount for the associated
     * underlying memory.
     *
     * @param increment the count to increase the reference count by
     */
    void retain(int increment);
  
    /**
     * Create a new ArrowBuf that is associated with an alternative allocator for the purposes of
     * memory ownership and accounting. This has no impact on the reference counting for the current
     * ArrowBuf except in the situation where the passed in Allocator is the same as the current
     * buffer. This operation has no impact on the reference count of this ArrowBuf. The newly created
     * ArrowBuf with either have a reference count of 1 (in the case that this is the first time this
     * memory is being associated with the target allocator or in other words allocation manager
     * currently doesn't hold a mapping for the target allocator) or the current value of the
     * reference count for the target allocator-reference manager combination + 1 in the case that the
     * provided allocator already had an association to this underlying memory.
     *
     * <p>The underlying allocation ({@link AllocationManager}) will not be copied.
     *
     * @param srcBuffer source ArrowBuf
     * @param targetAllocator The target allocator to create an association with.
     * @return A new ArrowBuf which shares the same underlying memory as this ArrowBuf.
     */
    ArrowBuf retain(ArrowBuf srcBuffer, BufferAllocator targetAllocator);
  
    /**
     * Derive a new ArrowBuf from a given source ArrowBuf. The new derived ArrowBuf will share the
     * same reference count as rest of the ArrowBufs associated with this reference manager.
     *
     * @param sourceBuffer source ArrowBuf
     * @param index index (relative to source ArrowBuf) new ArrowBuf should be derived from
     * @param length length (bytes) of data in underlying memory that derived buffer will have access
     *     to in underlying memory
     * @return derived buffer
     */
    ArrowBuf deriveBuffer(ArrowBuf sourceBuffer, long index, long length);
  
    /**
     * Duplicate the memory accounting ownership of the backing allocation of the given ArrowBuf in
     * another allocator. This will generate a new ArrowBuf that carries an association with the same
     * underlying memory ({@link AllocationManager}s) as the given ArrowBuf.
     *
     * @param sourceBuffer source ArrowBuf
     * @param targetAllocator The target allocator to create an association with
     * @return {@link OwnershipTransferResult} with info on transfer result and new buffer
     */
    OwnershipTransferResult transferOwnership(ArrowBuf sourceBuffer, BufferAllocator targetAllocator);
  
    /**
     * Get the buffer allocator associated with this reference manager.
     *
     * @return buffer allocator.
     */
    BufferAllocator getAllocator();
  
    /**
     * Total size (in bytes) of memory underlying this reference manager.
     *
     * @return Size (in bytes) of the memory chunk.
     */
    long getSize();
  
    /**
     * Get the total accounted size (in bytes).
     *
     * @return accounted size.
     */
    long getAccountedSize();
  
    String NO_OP_ERROR_MESSAGE = "Operation not supported on NO_OP Reference Manager";
  
    // currently used for empty ArrowBufs
    ReferenceManager NO_OP =
        new ReferenceManager() {
          @Override
          public int getRefCount() {
            return 1;
          }
  
          @Override
          public boolean release() {
            return false;
          }
  
          @Override
          public boolean release(int decrement) {
            return false;
          }
  
          @Override
          public void retain() {}
  
          @Override
          public void retain(int increment) {}
  
          @Override
          public ArrowBuf retain(ArrowBuf srcBuffer, BufferAllocator targetAllocator) {
            return srcBuffer;
          }
  
          @Override
          public ArrowBuf deriveBuffer(ArrowBuf sourceBuffer, long index, long length) {
            return sourceBuffer;
          }
  
          @Override
          public OwnershipTransferResult transferOwnership(
              ArrowBuf sourceBuffer, BufferAllocator targetAllocator) {
            return new OwnershipTransferNOOP(sourceBuffer);
          }
  
          @Override
          public BufferAllocator getAllocator() {
            return new RootAllocator(0);
          }
  
          @Override
          public long getSize() {
            return 0L;
          }
  
          @Override
          public long getAccountedSize() {
            return 0L;
          }
        };
  }
  