| /* |
| * 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); |
| } |
| |
| } |