blob: 43d80eab46c3f6aab464d3d2f86b8759962216c3 [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.activemq.artemis.jlibaio;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* This is an extension to use libaio.
*/
public final class LibaioFile<Callback extends SubmitInfo> implements AutoCloseable {
protected boolean open;
/**
* This represents a structure allocated on the native
* this is a io_context_t
*/
final LibaioContext<Callback> ctx;
private int fd;
LibaioFile(int fd, LibaioContext ctx) {
this.ctx = ctx;
this.fd = fd;
}
public int getBlockSize() {
return 512;
// FIXME
//return LibaioContext.getBlockSizeFD(fd);
}
public boolean lock() {
return LibaioContext.lock(fd);
}
@Override
public void close() throws IOException {
open = false;
LibaioContext.close(fd);
}
/**
* @return The size of the file.
*/
public long getSize() {
return LibaioContext.getSize(fd);
}
/**
* It will submit a write to the queue. The callback sent here will be received on the
* {@link LibaioContext#poll(SubmitInfo[], int, int)}
* In case of the libaio queue is full (e.g. returning E_AGAIN) this method will return false.
* <br>
* Notice: this won't hold a global reference on buffer, callback should hold a reference towards bufferWrite.
* And don't free the buffer until the callback was called as this could crash the VM.
*
* @param position The position on the file to write. Notice this has to be a multiple of 512.
* @param size The size of the buffer to use while writing.
* @param buffer if you are using O_DIRECT the buffer here needs to be allocated by {@link #newBuffer(int)}.
* @param callback A callback to be returned on the poll method.
* @throws java.io.IOException in case of error
*/
public void write(long position, int size, ByteBuffer buffer, Callback callback) throws IOException {
ctx.submitWrite(fd, position, size, buffer, callback);
}
/**
* It will submit a read to the queue. The callback sent here will be received on the
* {@link LibaioContext#poll(SubmitInfo[], int, int)}.
* In case of the libaio queue is full (e.g. returning E_AGAIN) this method will return false.
* <br>
* Notice: this won't hold a global reference on buffer, callback should hold a reference towards bufferWrite.
* And don't free the buffer until the callback was called as this could crash the VM.
* *
*
* @param position The position on the file to read. Notice this has to be a multiple of 512.
* @param size The size of the buffer to use while reading.
* @param buffer if you are using O_DIRECT the buffer here needs to be allocated by {@link #newBuffer(int)}.
* @param callback A callback to be returned on the poll method.
* @throws java.io.IOException in case of error
* @see LibaioContext#poll(SubmitInfo[], int, int)
*/
public void read(long position, int size, ByteBuffer buffer, Callback callback) throws IOException {
ctx.submitRead(fd, position, size, buffer, callback);
}
/**
* It will allocate a buffer to be used on libaio operations.
* Buffers here are allocated with posix_memalign.
* <br>
* You need to explicitly free the buffer created from here using the
* {@link LibaioContext#freeBuffer(java.nio.ByteBuffer)}.
*
* @param size the size of the buffer.
* @return the buffer allocated.
*/
public ByteBuffer newBuffer(int size) {
return LibaioContext.newAlignedBuffer(size, 512);
}
/**
* It will preallocate the file with a given size.
*
* @param size number of bytes to be filled on the file
*/
public void fill(long size) {
try {
LibaioContext.fill(fd, size);
} catch (OutOfMemoryError e) {
NativeLogger.LOGGER.debug("Didn't have enough memory to allocate " + size + " bytes in memory, using simple fallocate");
LibaioContext.fallocate(fd, size);
}
}
/**
* It will use fallocate to initialize a file.
*
* @param size number of bytes to be filled on the file
*/
public void fallocate(long size) {
LibaioContext.fallocate(fd, size);
}
}