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

org.apache.flink.runtime.io.network.api.serialization.ResizableBuffer Maven / Gradle / Ivy

/*
 * 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.flink.runtime.io.network.api.serialization;

import org.apache.flink.core.memory.HeapMemorySegment;
import org.apache.flink.core.memory.MemorySegment;
import org.apache.flink.runtime.io.network.buffer.Buffer;
import org.apache.flink.runtime.io.network.buffer.BufferRecycler;
import org.apache.flink.runtime.io.network.buffer.NetworkBuffer;

/**
 * Helper class to reuse an resizable buffer.
 */
final class ResizableBuffer {

	static class EmptyBufferRecycler implements BufferRecycler {
		@Override
		public void recycle(MemorySegment segment) {
			// Do nothing.
		}
	}

	private static EmptyBufferRecycler emptyBufferRecycler = new EmptyBufferRecycler();

	private HeapMemorySegment segment;
	private NetworkBuffer buffer;
	private volatile boolean isRecycled;

	public ResizableBuffer() {
		isRecycled = true;
	}

	public void recycle() {
		if (segment != null && !isRecycled) {
			if (this.segment == segment) {
				isRecycled = true;
				return;
			}
			throw new IllegalStateException("MemorySegment to be recycled doesn't match.");
		}
	}

	public Buffer getBuffer() {
		if (!isRecycled) {
			return buffer;
		}
		throw new IllegalStateException("The buffer has been recycled or uninitialized.");
	}

	public byte[] getHeapMemory() {
		return segment.getArray();
	}

	public void resetCapacity(int length) {
		// Ensure previous buffer has been recycled.
		if (!isRecycled) {
			throw new IllegalStateException("ResizableBuffer needs to be recycled before reset.");
		}

		// Ensure memory segment has enough capacity.
		if (segment != null && segment.size() >= length) {
			buffer.clear();
		} else {
			if (segment == null) {
				segment = HeapMemorySegment.FACTORY.wrapPooledHeapMemory(new byte[length], this);
			} else if (segment.size() < length) {
				segment.pointTo(new byte[length], this);
			}
			buffer = new NetworkBuffer(segment, emptyBufferRecycler);
		}

		isRecycled = false;
	}

	public void clear() {
		isRecycled = true;
		buffer = null;
		if (segment != null) {
			segment.free();
			segment = null;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy