blob: 8f552b753eae7789a848dbaea03f179b011c989a [file] [log] [blame]
/**
* 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.io.erasurecode;
import java.nio.ByteBuffer;
/**
* An abstract buffer allocator used for test.
*/
public abstract class BufferAllocator {
private boolean usingDirect = false;
public BufferAllocator(boolean usingDirect) {
this.usingDirect = usingDirect;
}
protected boolean isUsingDirect() {
return usingDirect;
}
/**
* Allocate and return a ByteBuffer of specified length.
* @param bufferLen
* @return
*/
public abstract ByteBuffer allocate(int bufferLen);
/**
* A simple buffer allocator that just uses ByteBuffer's
* allocate/allocateDirect API.
*/
public static class SimpleBufferAllocator extends BufferAllocator {
public SimpleBufferAllocator(boolean usingDirect) {
super(usingDirect);
}
@Override
public ByteBuffer allocate(int bufferLen) {
return isUsingDirect() ? ByteBuffer.allocateDirect(bufferLen) :
ByteBuffer.allocate(bufferLen);
}
}
/**
* A buffer allocator that allocates a buffer from an existing large buffer by
* slice calling, but if no available space just degrades as
* SimpleBufferAllocator. So please ensure enough space for it.
*/
public static class SlicedBufferAllocator extends BufferAllocator {
private ByteBuffer overallBuffer;
public SlicedBufferAllocator(boolean usingDirect, int totalBufferLen) {
super(usingDirect);
overallBuffer = isUsingDirect() ?
ByteBuffer.allocateDirect(totalBufferLen) :
ByteBuffer.allocate(totalBufferLen);
}
@Override
public ByteBuffer allocate(int bufferLen) {
if (bufferLen > overallBuffer.capacity() - overallBuffer.position()) {
// If no available space for the requested length, then allocate new
return isUsingDirect() ? ByteBuffer.allocateDirect(bufferLen) :
ByteBuffer.allocate(bufferLen);
}
overallBuffer.limit(overallBuffer.position() + bufferLen);
ByteBuffer result = overallBuffer.slice();
overallBuffer.position(overallBuffer.position() + bufferLen);
return result;
}
}
}