All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.parquet.bytes.ReusingByteBufferAllocator Maven / Gradle / Ivy

There is a newer version: 1.15.0
Show newest version
/*
 *  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.parquet.bytes;

import java.nio.ByteBuffer;

/**
 * A special {@link ByteBufferAllocator} implementation that keeps one {@link ByteBuffer} object and reuses it at the
 * next {@link #allocate(int)} call. The {@link #close()} shall be called when this allocator is not needed anymore to
 * really release the one buffer.
 */
public abstract class ReusingByteBufferAllocator implements ByteBufferAllocator, AutoCloseable {

  private final ByteBufferAllocator allocator;
  private final ByteBufferReleaser releaser = new ByteBufferReleaser(this);
  private ByteBuffer buffer;
  private ByteBuffer bufferOut;

  /**
   * Creates a new strict {@link ReusingByteBufferAllocator} object with the specified "parent" allocator to be used for
   * allocating/releasing the one buffer.
   * 

* Strict means it is enforced that {@link #release(ByteBuffer)} is invoked before a new {@link #allocate(int)} can be * called. * * @param allocator the allocator to be used for allocating/releasing the one buffer * @return a new strict {@link ReusingByteBufferAllocator} object */ public static ReusingByteBufferAllocator strict(ByteBufferAllocator allocator) { return new ReusingByteBufferAllocator(allocator) { @Override void allocateCheck(ByteBuffer bufferOut) { if (bufferOut != null) { throw new IllegalStateException("The single buffer is not yet released"); } } }; } /** * Creates a new unsafe {@link ReusingByteBufferAllocator} object with the specified "parent" allocator to be used for * allocating/releasing the one buffer. *

* Unsafe means it is not enforced that {@link #release(ByteBuffer)} is invoked before a new {@link #allocate(int)} * can be called, i.e. no exceptions will be thrown at {@link #allocate(int)}. * * @param allocator the allocator to be used for allocating/releasing the one buffer * @return a new unsafe {@link ReusingByteBufferAllocator} object */ public static ReusingByteBufferAllocator unsafe(ByteBufferAllocator allocator) { return new ReusingByteBufferAllocator(allocator) { @Override void allocateCheck(ByteBuffer bufferOut) { // no-op } }; } private ReusingByteBufferAllocator(ByteBufferAllocator allocator) { this.allocator = allocator; } /** * A convenience method to get a {@link ByteBufferReleaser} instance already created for this allocator. * * @return a releaser for this allocator */ public ByteBufferReleaser getReleaser() { return releaser; } /** * {@inheritDoc} * * @throws IllegalStateException if strict and the one buffer was not released yet * @see #strict(ByteBufferAllocator) * @see #unsafe(ByteBufferAllocator) */ @Override public ByteBuffer allocate(int size) { allocateCheck(bufferOut); if (buffer == null) { bufferOut = buffer = allocator.allocate(size); } else if (buffer.capacity() < size) { allocator.release(buffer); bufferOut = buffer = allocator.allocate(size); } else { buffer.clear(); buffer.limit(size); bufferOut = buffer.slice(); } return bufferOut; } abstract void allocateCheck(ByteBuffer bufferOut); /** * {@inheritDoc} * * @throws IllegalStateException if the one buffer has already been released or never allocated * @throws IllegalArgumentException if the specified buffer is not the one allocated by this allocator */ @Override public void release(ByteBuffer b) { if (bufferOut == null) { throw new IllegalStateException("The single buffer has already been released or never allocated"); } if (b != bufferOut) { throw new IllegalArgumentException("The buffer to be released is not the one allocated by this allocator"); } bufferOut = null; } @Override public boolean isDirect() { return allocator.isDirect(); } @Override public void close() { if (buffer != null) { allocator.release(buffer); buffer = null; bufferOut = null; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy