You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by an...@apache.org on 2015/07/30 11:14:23 UTC
[1/9] activemq-artemis git commit: ARTEMIS-163 First pass on the
native AIO refactoring
Repository: activemq-artemis
Updated Branches:
refs/heads/master 661f695ee -> 8182f8bd2
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AsynchronousFileTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AsynchronousFileTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AsynchronousFileTest.java
deleted file mode 100644
index 434dcc8..0000000
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AsynchronousFileTest.java
+++ /dev/null
@@ -1,1015 +0,0 @@
-/*
- * 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.tests.unit.core.asyncio;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
-import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-/**
- * you need to define -Djava.library.path=${project-root}/native/src/.libs when calling the JVM
- * If you are running this test in eclipse you should do:
- * I - Run->Open Run Dialog
- * II - Find the class on the list (you will find it if you already tried running this testcase before)
- * III - Add -Djava.library.path=<your project place>/native/src/.libs
- */
-public class AsynchronousFileTest extends AIOTestBase
-{
-
- @BeforeClass
- public static void hasAIO()
- {
- org.junit.Assume.assumeTrue("Test case needs AIO to run", AIOSequentialFileFactory.isSupported());
- }
-
- private static CharsetEncoder UTF_8_ENCODER = StandardCharsets.UTF_8.newEncoder();
-
- byte[] commonBuffer = null;
-
- ExecutorService executor;
-
- ExecutorService pollerExecutor;
-
- private AsynchronousFileImpl controller;
- private ByteBuffer buffer;
-
- private final BufferCallback bufferCallbackDestroy = new BufferCallback()
- {
-
- public void bufferDone(final ByteBuffer buffer1)
- {
- AsynchronousFileImpl.destroyBuffer(buffer1);
- }
-
- };
-
- private static void debug(final String msg)
- {
- UnitTestLogger.LOGGER.debug(msg);
- }
-
- @Override
- @Before
- public void setUp() throws Exception
- {
- super.setUp();
- pollerExecutor = Executors.newCachedThreadPool(new ActiveMQThreadFactory("ActiveMQ-AIO-poller-pool" + System.identityHashCode(this),
- false,
- this.getClass().getClassLoader()));
- executor = Executors.newSingleThreadExecutor();
- }
-
- @Override
- @After
- public void tearDown() throws Exception
- {
- destroy(buffer);
- if (controller != null)
- {
- try
- {
- controller.close();
- }
- catch (Exception e)
- {
- // ignored
- }
- }
- executor.shutdown();
- pollerExecutor.shutdown();
- super.tearDown();
- }
-
- /**
- * Opening and closing a file immediately can lead to races on the native layer,
- * creating crash conditions.
- */
- @Test
- public void testOpenClose() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- for (int i = 0; i < 100; i++)
- {
- controller.open(fileName, 10000);
- controller.close();
-
- }
- }
-
- @Test
- public void testReleaseBuffers() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- WeakReference<ByteBuffer> bufferCheck = null;
-
- controller.open(fileName, 10000);
- bufferCheck = new WeakReference<ByteBuffer>(controller.getHandler());
- controller.fill(0, 10, 1024, (byte) 0);
-
- ByteBuffer write = AsynchronousFileImpl.newBuffer(1024);
-
- for (int i = 0; i < 1024; i++)
- {
- write.put(ActiveMQTestBase.getSamplebyte(i));
- }
-
- final CountDownLatch latch = new CountDownLatch(1);
-
- controller.write(0, 1024, write, new AIOCallback()
- {
-
- public void onError(final int errorCode, final String errorMessage)
- {
- }
-
- public void done()
- {
- latch.countDown();
- }
- });
-
- assertTrue(latch.await(10, TimeUnit.SECONDS));
-
- WeakReference<ByteBuffer> bufferCheck2 = new WeakReference<ByteBuffer>(write);
-
- destroy(write);
-
- write = null;
-
- ActiveMQTestBase.forceGC(bufferCheck2, 5000);
-
- assertNull(bufferCheck2.get());
-
- controller.close();
-
- controller = null;
-
- ActiveMQTestBase.forceGC(bufferCheck, 5000);
-
- assertNull(bufferCheck.get());
- }
-
- @Test
- public void testFileNonExistent() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- for (int i = 0; i < 100; i++)
- {
- try
- {
- controller.open("/non-existent/IDontExist.error", 10000);
- fail("Exception expected! The test could create a file called /non-existent/IDontExist.error when it was supposed to fail.");
- }
- catch (Exception ignored)
- {
- }
- try
- {
- controller.close();
- fail("Supposed to throw exception as the file wasn't opened");
- }
- catch (Exception ignored)
- {
- }
-
- }
- }
-
- /**
- * This test is validating if the AIO layer can open two different
- * simultaneous files without loose any callbacks. This test made the native
- * layer to crash at some point during development
- */
- @Test
- public void testTwoFiles() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- final AsynchronousFileImpl controller2 = new AsynchronousFileImpl(executor, pollerExecutor);
- controller.open(fileName + ".1", 10000);
- controller2.open(fileName + ".2", 10000);
-
- int numberOfLines = 1000;
- int size = 1024;
-
- ArrayList<Integer> listResult1 = new ArrayList<Integer>();
- ArrayList<Integer> listResult2 = new ArrayList<Integer>();
-
- AtomicInteger errors = new AtomicInteger(0);
-
-
- try
- {
- CountDownLatch latchDone = new CountDownLatch(numberOfLines);
- CountDownLatch latchDone2 = new CountDownLatch(numberOfLines);
-
- buffer = AsynchronousFileImpl.newBuffer(size);
- encodeBufer(buffer);
-
- preAlloc(controller, numberOfLines * size);
- preAlloc(controller2, numberOfLines * size);
-
- ArrayList<CountDownCallback> list = new ArrayList<CountDownCallback>();
- ArrayList<CountDownCallback> list2 = new ArrayList<CountDownCallback>();
-
- for (int i = 0; i < numberOfLines; i++)
- {
- list.add(new CountDownCallback(latchDone, errors, listResult1, i));
- list2.add(new CountDownCallback(latchDone2, errors, listResult2, i));
- }
-
- int counter = 0;
-
- Iterator<CountDownCallback> iter2 = list2.iterator();
-
- for (CountDownCallback cb1 : list)
- {
- CountDownCallback cb2 = iter2.next();
-
- controller.write(counter * size, size, buffer, cb1);
- controller2.write(counter * size, size, buffer, cb2);
- ++counter;
-
- }
-
- ActiveMQTestBase.waitForLatch(latchDone);
- ActiveMQTestBase.waitForLatch(latchDone2);
-
- CountDownCallback.checkResults(numberOfLines, listResult1);
- CountDownCallback.checkResults(numberOfLines, listResult2);
-
- for (CountDownCallback callback : list)
- {
- assertEquals(1, callback.timesDoneCalled.get());
- assertTrue(callback.doneCalled);
- }
-
- for (CountDownCallback callback : list2)
- {
- assertEquals(1, callback.timesDoneCalled.get());
- assertTrue(callback.doneCalled);
- }
-
- assertEquals(0, errors.get());
-
- controller.close();
- }
- finally
- {
- try
- {
- controller2.close();
- }
- catch (Exception ignored)
- {
- }
- }
- }
-
- @Test
- public void testAddBeyongSimultaneousLimit() throws Exception
- {
- asyncData(3000, 1024, 10);
- }
-
- @Test
- public void testAddAsyncData() throws Exception
- {
- asyncData(10000, 1024, 30000);
- }
-
- private static final class LocalCallback implements AIOCallback
- {
- private final CountDownLatch latch = new CountDownLatch(1);
-
- volatile boolean error;
-
- public void done()
- {
- latch.countDown();
- }
-
- public void onError(final int errorCode, final String errorMessage)
- {
- error = true;
- latch.countDown();
- }
- }
-
- @Test
- public void testReleaseNullBuffer() throws Exception
- {
- boolean failed = false;
- try
- {
- AsynchronousFileImpl.destroyBuffer(null);
- }
- catch (Exception expected)
- {
- failed = true;
- }
-
- assertTrue("Exception expected", failed);
- }
-
- @Test
- public void testInvalidReads() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
-
- final int SIZE = 512;
-
- controller.open(fileName, 10);
- controller.close();
-
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
-
- controller.open(fileName, 10);
-
- controller.fill(0, 1, 512, (byte) 'j');
-
- buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
- buffer.clear();
-
- for (int i = 0; i < SIZE; i++)
- {
- buffer.put((byte) (i % 100));
- }
-
- LocalCallback callbackLocal = new LocalCallback();
-
- controller.write(0, 512, buffer, callbackLocal);
-
- waitForLatch(callbackLocal.latch);
-
- {
- ByteBuffer newBuffer = AsynchronousFileImpl.newBuffer(512);
-
- try
- {
- callbackLocal = new LocalCallback();
-
- controller.read(0, 50, newBuffer, callbackLocal);
-
- waitForLatch(callbackLocal.latch);
-
- assertTrue(callbackLocal.error);
-
- }
- finally
- {
- // We have to destroy the native buffer manually as it was created with a malloc like C function
- destroy(newBuffer);
- newBuffer = null;
- }
- }
- callbackLocal = new LocalCallback();
-
- byte[] bytes = new byte[512];
-
- {
- try
- {
- ByteBuffer newBuffer = ByteBuffer.wrap(bytes);
-
- controller.read(0, 512, newBuffer, callbackLocal);
-
- fail("An exception was supposed to be thrown");
- }
- catch (ActiveMQException ignored)
- {
- System.out.println(ignored);
- }
- }
-
- {
- final ByteBuffer newBuffer = AsynchronousFileImpl.newBuffer(512);
- try
- {
- callbackLocal = new LocalCallback();
- controller.read(0, 512, newBuffer, callbackLocal);
- waitForLatch(callbackLocal.latch);
- assertFalse(callbackLocal.error);
-
- newBuffer.rewind();
-
- byte[] bytesRead = new byte[SIZE];
-
- newBuffer.get(bytesRead);
-
- for (int i = 0; i < SIZE; i++)
- {
- assertEquals((byte) (i % 100), bytesRead[i]);
- }
- }
- finally
- {
- destroy(newBuffer);
- }
- }
- }
-
- private static void destroy(ByteBuffer buffer0)
- {
- if (buffer0 != null)
- {
- AsynchronousFileImpl.destroyBuffer(buffer0);
- }
- }
-
- @Test
- public void testBufferCallbackUniqueBuffers() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- final int NUMBER_LINES = 1000;
- final int SIZE = 512;
-
- controller.open(fileName, 1000);
-
- controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
- final ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
-
- BufferCallback bufferCallback = new BufferCallback()
- {
- public void bufferDone(final ByteBuffer buffer)
- {
- buffers.add(buffer);
- }
- };
-
- controller.setBufferCallback(bufferCallback);
-
- CountDownLatch latch = new CountDownLatch(NUMBER_LINES);
- ArrayList<Integer> result = new ArrayList<Integer>();
- for (int i = 0; i < NUMBER_LINES; i++)
- {
- ByteBuffer buffer1 = AsynchronousFileImpl.newBuffer(SIZE);
- buffer1.rewind();
- for (int j = 0; j < SIZE; j++)
- {
- buffer1.put((byte) (j % Byte.MAX_VALUE));
- }
- CountDownCallback aio = new CountDownCallback(latch, null, result, i);
- controller.write(i * SIZE, SIZE, buffer1, aio);
- }
-
- // The buffer callback is only called after the complete callback was
- // called.
- // Because of that a race could happen on the assertions to
- // buffers.size what would invalidate the test
- // We close the file and that would guarantee the buffer callback was
- // called for all the elements
- controller.close();
-
- CountDownCallback.checkResults(NUMBER_LINES, result);
-
- // Make sure all the buffers are unique
- ByteBuffer lineOne = null;
- for (ByteBuffer bufferTmp : buffers)
- {
- if (lineOne == null)
- {
- lineOne = bufferTmp;
- }
- else
- {
- assertTrue(lineOne != bufferTmp);
- }
- }
-
- for (ByteBuffer bufferTmp : buffers)
- {
- destroy(bufferTmp);
- }
-
- buffers.clear();
- }
-
- @Test
- public void testBufferCallbackAwaysSameBuffer() throws Exception
- {
-
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
-
- final int NUMBER_LINES = 1000;
- final int SIZE = 512;
-
- controller.open(fileName, 1000);
-
- controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
- final ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
-
- BufferCallback bufferCallback = new BufferCallback()
- {
- public void bufferDone(final ByteBuffer buffer)
- {
- buffers.add(buffer);
- }
- };
-
- controller.setBufferCallback(bufferCallback);
-
- CountDownLatch latch = new CountDownLatch(NUMBER_LINES);
-
- buffer = AsynchronousFileImpl.newBuffer(SIZE);
- buffer.rewind();
- for (int j = 0; j < SIZE; j++)
- {
- buffer.put((byte) (j % Byte.MAX_VALUE));
- }
-
- ArrayList<Integer> result = new ArrayList<Integer>();
-
- for (int i = 0; i < NUMBER_LINES; i++)
- {
- CountDownCallback aio = new CountDownCallback(latch, null, result, i);
- controller.write(i * SIZE, SIZE, buffer, aio);
- }
-
- // The buffer callback is only called after the complete callback was
- // called.
- // Because of that a race could happen on the assertions to
- // buffers.size what would invalidate the test
- // We close the file and that would guarantee the buffer callback was
- // called for all the elements
- controller.close();
-
- CountDownCallback.checkResults(NUMBER_LINES, result);
-
- assertEquals(NUMBER_LINES, buffers.size());
-
- // Make sure all the buffers are unique
- ByteBuffer lineOne = null;
- for (ByteBuffer bufferTmp : buffers)
- {
- if (lineOne == null)
- {
- lineOne = bufferTmp;
- }
- else
- {
- assertTrue(lineOne == bufferTmp);
- }
- }
-
- buffers.clear();
- }
-
- @Test
- public void testRead() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- controller.setBufferCallback(bufferCallbackDestroy);
-
- final int NUMBER_LINES = 1000;
- final int SIZE = 1024;
-
- controller.open(fileName, 1000);
-
- controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
- {
- CountDownLatch latch = new CountDownLatch(NUMBER_LINES);
- ArrayList<Integer> result = new ArrayList<Integer>();
-
- AtomicInteger errors = new AtomicInteger(0);
-
- for (int i = 0; i < NUMBER_LINES; i++)
- {
- if (i % 100 == 0)
- {
- System.out.println("Wrote " + i + " lines");
- }
- final ByteBuffer buffer0 = AsynchronousFileImpl.newBuffer(SIZE);
- for (int j = 0; j < SIZE; j++)
- {
- buffer0.put(ActiveMQTestBase.getSamplebyte(j));
- }
-
- CountDownCallback aio = new CountDownCallback(latch, errors, result, i);
- controller.write(i * SIZE, SIZE, buffer0, aio);
- }
-
- waitForLatch(latch);
-
- assertEquals(0, errors.get());
-
- CountDownCallback.checkResults(NUMBER_LINES, result);
- }
-
- // If you call close you're supposed to wait events to finish before
- // closing it
- controller.close();
- controller.setBufferCallback(null);
-
- controller.open(fileName, 10);
-
- buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
- for (int i = 0; i < NUMBER_LINES; i++)
- {
- if (i % 100 == 0)
- {
- System.out.println("Read " + i + " lines");
- }
- AsynchronousFileImpl.clearBuffer(buffer);
-
- CountDownLatch latch = new CountDownLatch(1);
- AtomicInteger errors = new AtomicInteger(0);
- CountDownCallback aio = new CountDownCallback(latch, errors, null, 0);
-
- controller.read(i * SIZE, SIZE, buffer, aio);
-
- waitForLatch(latch);
- assertEquals(0, errors.get());
- assertTrue(aio.doneCalled);
-
- byte[] bytesRead = new byte[SIZE];
- buffer.get(bytesRead);
-
- for (int count = 0; count < SIZE; count++)
- {
- Assert.assertEquals("byte position " + count + " differs on line " + i + " position = " + count,
- ActiveMQTestBase.getSamplebyte(count),
- bytesRead[count]);
- }
- }
- }
-
- /**
- * This test will call file.close() when there are still callbacks being processed.
- * This could cause a crash or callbacks missing and this test is validating both situations.
- * The file is also read after being written to validate its correctness
- */
- @Test
- public void testConcurrentClose() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- final int NUMBER_LINES = 1000;
- CountDownLatch readLatch = new CountDownLatch(NUMBER_LINES);
- final int SIZE = 1024;
-
- controller.open(fileName, 10000);
-
- controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
- controller.setBufferCallback(bufferCallbackDestroy);
-
- for (int i = 0; i < NUMBER_LINES; i++)
- {
- ByteBuffer buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
- buffer.clear();
- addString("Str value " + i + "\n", buffer);
- for (int j = buffer.position(); j < buffer.capacity() - 1; j++)
- {
- buffer.put((byte) ' ');
- }
- buffer.put((byte) '\n');
-
- CountDownCallback aio = new CountDownCallback(readLatch, null, null, 0);
- controller.write(i * SIZE, SIZE, buffer, aio);
- }
-
- // If you call close you're supposed to wait events to finish before
- // closing it
- controller.close();
-
- controller.setBufferCallback(null);
-
- assertEquals(0, readLatch.getCount());
- waitForLatch(readLatch);
- controller.open(fileName, 10);
-
- ByteBuffer newBuffer = AsynchronousFileImpl.newBuffer(SIZE);
-
- ByteBuffer buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
- for (int i = 0; i < NUMBER_LINES; i++)
- {
- newBuffer.clear();
- addString("Str value " + i + "\n", newBuffer);
- for (int j = newBuffer.position(); j < newBuffer.capacity() - 1; j++)
- {
- newBuffer.put((byte) ' ');
- }
- newBuffer.put((byte) '\n');
-
- CountDownLatch latch = new CountDownLatch(1);
- CountDownCallback aio = new CountDownCallback(latch, null, null, 0);
- controller.read(i * SIZE, SIZE, buffer, aio);
- waitForLatch(latch);
- assertEquals(0, aio.errorCalled);
- assertTrue(aio.doneCalled);
-
- byte[] bytesRead = new byte[SIZE];
- byte[] bytesCompare = new byte[SIZE];
-
- newBuffer.rewind();
- newBuffer.get(bytesCompare);
- buffer.rewind();
- buffer.get(bytesRead);
-
- for (int count = 0; count < SIZE; count++)
- {
- assertEquals("byte position " + count + " differs on line " + i,
- bytesCompare[count],
- bytesRead[count]);
- }
-
- assertTrue(buffer.equals(newBuffer));
- }
-
- destroy(newBuffer);
- }
-
- private void asyncData(final int numberOfLines, final int size, final int aioLimit) throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- controller.open(fileName, aioLimit);
-
-
- CountDownLatch latchDone = new CountDownLatch(numberOfLines);
-
- buffer = AsynchronousFileImpl.newBuffer(size);
- encodeBufer(buffer);
-
- preAlloc(controller, numberOfLines * size);
-
- ArrayList<CountDownCallback> list = new ArrayList<CountDownCallback>();
-
- ArrayList<Integer> result = new ArrayList<Integer>();
-
- for (int i = 0; i < numberOfLines; i++)
- {
- list.add(new CountDownCallback(latchDone, null, result, i));
- }
-
- long valueInitial = System.currentTimeMillis();
-
- long lastTime = System.currentTimeMillis();
- int counter = 0;
- for (CountDownCallback tmp : list)
- {
- controller.write(counter * size, size, buffer, tmp);
- if (++counter % 20000 == 0)
- {
- AsynchronousFileTest.debug(20000 * 1000 / (System.currentTimeMillis() - lastTime) + " rec/sec (Async)");
- lastTime = System.currentTimeMillis();
- }
-
- }
-
- ActiveMQTestBase.waitForLatch(latchDone);
-
- long timeTotal = System.currentTimeMillis() - valueInitial;
-
- CountDownCallback.checkResults(numberOfLines, result);
-
- AsynchronousFileTest.debug("After completions time = " + timeTotal +
- " for " +
- numberOfLines +
- " registers " +
- " size each line = " +
- size +
- ", Records/Sec=" +
- numberOfLines *
- 1000 /
- timeTotal +
- " (Assynchronous)");
-
- for (CountDownCallback tmp : list)
- {
- assertEquals(1, tmp.timesDoneCalled.get());
- assertTrue(tmp.doneCalled);
- assertEquals(0, tmp.errorCalled);
- }
-
- controller.close();
- }
-
- @Test
- public void testDirectSynchronous() throws Exception
- {
-
- final int NUMBER_LINES = 3000;
- final int SIZE = 1024;
-
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- controller.open(fileName, 2000);
-
- buffer = AsynchronousFileImpl.newBuffer(SIZE);
- encodeBufer(buffer);
-
- preAlloc(controller, NUMBER_LINES * SIZE);
-
- long startTime = System.currentTimeMillis();
-
- for (int i = 0; i < NUMBER_LINES; i++)
- {
- CountDownLatch latchDone = new CountDownLatch(1);
- CountDownCallback aioBlock = new CountDownCallback(latchDone, null, null, 0);
- controller.write(i * 512, 512, buffer, aioBlock);
- ActiveMQTestBase.waitForLatch(latchDone);
- assertTrue(aioBlock.doneCalled);
- assertEquals(0, aioBlock.errorCalled);
- }
-
- long timeTotal = System.currentTimeMillis() - startTime;
- AsynchronousFileTest.debug("time = " + timeTotal +
- " for " +
- NUMBER_LINES +
- " registers " +
- " size each line = " +
- SIZE +
- " Records/Sec=" +
- NUMBER_LINES *
- 1000 /
- timeTotal +
- " Synchronous");
-
- controller.close();
- }
-
-
- @Test
- public void testInternalWrite() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- controller.open(fileName, 2000);
-
- final int SIZE = 10 * 512;
-
- buffer = AsynchronousFileImpl.newBuffer(SIZE);
-
- for (int i = 0; i < SIZE; i++)
- {
- buffer.put(getSamplebyte(i));
- }
-
- controller.writeInternal(0, SIZE, buffer);
-
- InputStream fileInput = new BufferedInputStream(new FileInputStream(new File(fileName)));
-
- for (int i = 0; i < SIZE; i++)
- {
- assertEquals(getSamplebyte(i), fileInput.read());
- }
-
- assertEquals(-1, fileInput.read());
-
- }
-
-
- @Test
- public void testInvalidWrite() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
- controller.open(fileName, 2000);
-
- final int SIZE = 512;
-
- buffer = AsynchronousFileImpl.newBuffer(SIZE);
- encodeBufer(buffer);
-
- preAlloc(controller, 10 * 512);
-
- CountDownLatch latchDone = new CountDownLatch(1);
-
- CountDownCallback aioBlock = new CountDownCallback(latchDone, null, null, 0);
- controller.write(11, 512, buffer, aioBlock);
-
- ActiveMQTestBase.waitForLatch(latchDone);
-
- assertTrue(aioBlock.errorCalled != 0);
- assertFalse(aioBlock.doneCalled);
- }
-
- @Test
- public void testInvalidAlloc() throws Exception
- {
- try
- {
- @SuppressWarnings("unused")
- ByteBuffer buffer = AsynchronousFileImpl.newBuffer(300);
- fail("Exception expected");
- }
- catch (Exception ignored)
- {
- }
-
- }
-
- // This is in particular testing for http://bugs.sun.com/view_bug.do?bug_id=6791815
- @Test
- public void testAllocations() throws Exception
- {
- final AtomicInteger errors = new AtomicInteger(0);
-
- Thread[] ts = new Thread[100];
-
- final CountDownLatch align = new CountDownLatch(ts.length);
- final CountDownLatch start = new CountDownLatch(1);
-
- for (int i = 0; i < ts.length; i++)
- {
- ts[i] = new Thread()
- {
- @Override
- public void run()
- {
- try
- {
- align.countDown();
- start.await();
- for (int j = 0; j < 1000; j++)
- {
- ByteBuffer buffer = AsynchronousFileImpl.newBuffer(512);
- AsynchronousFileTest.destroy(buffer);
- }
- }
- catch (Throwable e)
- {
- e.printStackTrace();
- errors.incrementAndGet();
- }
- }
- };
- ts[i].start();
- }
-
- align.await();
- start.countDown();
-
- for (Thread t : ts)
- {
- t.join();
- }
-
- assertEquals(0, errors.get());
- }
-
- @Test
- public void testSize() throws Exception
- {
- controller = new AsynchronousFileImpl(executor, pollerExecutor);
-
- final int NUMBER_LINES = 10;
- final int SIZE = 1024;
-
- controller.open(fileName, 1);
-
- controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j');
-
- assertEquals(NUMBER_LINES * SIZE, controller.size());
- }
-
- private static void addString(final String str, final ByteBuffer buffer)
- {
- CharBuffer charBuffer = CharBuffer.wrap(str);
- AsynchronousFileTest.UTF_8_ENCODER.encode(charBuffer, buffer, true);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java
index aa8422a..c9d3ce4 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/MultiThreadAsynchronousFileTest.java
@@ -16,10 +16,10 @@
*/
package org.apache.activemq.artemis.tests.unit.core.asyncio;
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFile;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
@@ -55,7 +55,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
static final int SIZE = 1024;
- static final int NUMBER_OF_THREADS = 10;
+ static final int NUMBER_OF_THREADS = 1;
static final int NUMBER_OF_LINES = 1000;
@@ -65,7 +65,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
private static void debug(final String msg)
{
- UnitTestLogger.LOGGER.debug(msg);
+ UnitTestLogger.LOGGER.info(msg);
}
@Override
@@ -102,16 +102,18 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
private void executeTest(final boolean sync) throws Throwable
{
MultiThreadAsynchronousFileTest.debug(sync ? "Sync test:" : "Async test");
- AsynchronousFileImpl jlibAIO = new AsynchronousFileImpl(executor, pollerExecutor);
- jlibAIO.open(fileName, 21000);
+ AIOSequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile(), 21000);
+ factory.start();
+ factory.disableBufferReuse();
+
+ AIOSequentialFile file = (AIOSequentialFile)factory.createSequentialFile(fileName);
+ file.open();
try
{
MultiThreadAsynchronousFileTest.debug("Preallocating file");
- jlibAIO.fill(0L,
- MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS,
- MultiThreadAsynchronousFileTest.SIZE * MultiThreadAsynchronousFileTest.NUMBER_OF_LINES,
- (byte) 0);
+ file.fill(MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS *
+ MultiThreadAsynchronousFileTest.SIZE * MultiThreadAsynchronousFileTest.NUMBER_OF_LINES);
MultiThreadAsynchronousFileTest.debug("Done Preallocating file");
CountDownLatch latchStart = new CountDownLatch(MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS + 1);
@@ -119,7 +121,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
ArrayList<ThreadProducer> list = new ArrayList<ThreadProducer>(MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS);
for (int i = 0; i < MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS; i++)
{
- ThreadProducer producer = new ThreadProducer("Thread " + i, latchStart, jlibAIO, sync);
+ ThreadProducer producer = new ThreadProducer("Thread " + i, latchStart, file, sync);
list.add(producer);
producer.start();
}
@@ -152,7 +154,8 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
}
finally
{
- jlibAIO.close();
+ file.close();
+ factory.stop();
}
}
@@ -170,11 +173,11 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
boolean sync;
- AsynchronousFileImpl libaio;
+ AIOSequentialFile libaio;
public ThreadProducer(final String name,
final CountDownLatch latchStart,
- final AsynchronousFileImpl libaio,
+ final AIOSequentialFile libaio,
final boolean sync)
{
super(name);
@@ -190,10 +193,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
ByteBuffer buffer = null;
- synchronized (MultiThreadAsynchronousFileTest.class)
- {
- buffer = AsynchronousFileImpl.newBuffer(MultiThreadAsynchronousFileTest.SIZE);
- }
+ buffer = LibaioContext.newAlignedBuffer(MultiThreadAsynchronousFileTest.SIZE, 512);
try
{
@@ -268,7 +268,7 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
{
synchronized (MultiThreadAsynchronousFileTest.class)
{
- AsynchronousFileImpl.destroyBuffer(buffer);
+ LibaioContext.freeBuffer(buffer);
}
}
@@ -281,44 +281,9 @@ public class MultiThreadAsynchronousFileTest extends AIOTestBase
buffer.put(bytes);
}
- private void addData(final AsynchronousFileImpl aio, final ByteBuffer buffer, final AIOCallback callback) throws Exception
- {
- executor.execute(new WriteRunnable(aio, buffer, callback));
- }
-
- private class WriteRunnable implements Runnable
+ private void addData(final AIOSequentialFile aio, final ByteBuffer buffer, final IOCallback callback) throws Exception
{
-
- AsynchronousFileImpl aio;
-
- ByteBuffer buffer;
-
- AIOCallback callback;
-
- public WriteRunnable(final AsynchronousFileImpl aio, final ByteBuffer buffer, final AIOCallback callback)
- {
- this.aio = aio;
- this.buffer = buffer;
- this.callback = callback;
- }
-
- public void run()
- {
- try
- {
- aio.write(getNewPosition() * MultiThreadAsynchronousFileTest.SIZE,
- MultiThreadAsynchronousFileTest.SIZE,
- buffer,
- callback);
-
- }
- catch (Exception e)
- {
- callback.onError(ActiveMQExceptionType.GENERIC_EXCEPTION.getCode(), e.toString());
- e.printStackTrace();
- }
- }
-
+ aio.writeDirect(buffer, true, callback);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java
index aa5c68b..e08ef55 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/AlignedJournalImplTest.java
@@ -37,8 +37,8 @@ import org.apache.activemq.artemis.core.journal.EncodingSupport;
import org.apache.activemq.artemis.core.journal.LoaderCallback;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
@@ -100,7 +100,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
FakeSequentialFileFactory factory = new FakeSequentialFileFactory(200, true);
- SequentialFile file = factory.createSequentialFile("test1", 1);
+ SequentialFile file = factory.createSequentialFile("test1");
file.open();
@@ -590,7 +590,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
System.out.println("Files = " + factory.listFiles("tt"));
- SequentialFile file = factory.createSequentialFile("tt-1.tt", 1);
+ SequentialFile file = factory.createSequentialFile("tt-1.tt");
file.open();
@@ -656,7 +656,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
journalImpl.appendCommitRecord(2L, false);
- SequentialFile file = factory.createSequentialFile("tt-1.tt", 1);
+ SequentialFile file = factory.createSequentialFile("tt-1.tt");
file.open();
@@ -761,7 +761,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
journalImpl.appendCommitRecord(1L, false);
- SequentialFile file = factory.createSequentialFile("tt-1.tt", 1);
+ SequentialFile file = factory.createSequentialFile("tt-1.tt");
file.open();
@@ -1046,7 +1046,7 @@ public class AlignedJournalImplTest extends ActiveMQTestBase
Assert.assertEquals(0, records.size());
Assert.assertEquals(1, transactions.size());
- SequentialFile file = factory.createSequentialFile("tt-1.tt", 1);
+ SequentialFile file = factory.createSequentialFile("tt-1.tt");
file.open();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java
index e078043..c2f88ac 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/CleanBufferTest.java
@@ -19,10 +19,10 @@ package org.apache.activemq.artemis.tests.unit.core.journal.impl;
import java.io.File;
import java.nio.ByteBuffer;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Assert;
@@ -44,7 +44,7 @@ public class CleanBufferTest extends ActiveMQTestBase
@Test
public void testCleanOnNIO()
{
- SequentialFileFactory factory = new NIOSequentialFileFactory(new File("Whatever"));
+ SequentialFileFactory factory = new NIOSequentialFileFactory(new File("Whatever"), 1);
testBuffer(factory);
}
@@ -52,9 +52,9 @@ public class CleanBufferTest extends ActiveMQTestBase
@Test
public void testCleanOnAIO()
{
- if (AsynchronousFileImpl.isLoaded())
+ if (LibaioContext.isLoaded())
{
- SequentialFileFactory factory = new AIOSequentialFileFactory(new File("Whatever"));
+ SequentialFileFactory factory = new AIOSequentialFileFactory(new File("Whatever"), 50);
testBuffer(factory);
}
@@ -70,6 +70,7 @@ public class CleanBufferTest extends ActiveMQTestBase
private void testBuffer(final SequentialFileFactory factory)
{
+ factory.start();
ByteBuffer buffer = factory.newBuffer(100);
try
@@ -107,6 +108,7 @@ public class CleanBufferTest extends ActiveMQTestBase
finally
{
factory.releaseBuffer(buffer);
+ factory.stop();
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java
index aaffffa..eabb89e 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeJournalImplTest.java
@@ -17,7 +17,7 @@
package org.apache.activemq.artemis.tests.unit.core.journal.impl;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
public class FakeJournalImplTest extends JournalImplTestUnit
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java
index 7431233..aee1e06 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FakeSequentialFileFactoryTest.java
@@ -17,7 +17,7 @@
package org.apache.activemq.artemis.tests.unit.core.journal.impl;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
public class FakeSequentialFileFactoryTest extends SequentialFileFactoryTestBase
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java
index 8eacec1..73bf148 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/FileFactoryTestBase.java
@@ -15,15 +15,13 @@
* limitations under the License.
*/
package org.apache.activemq.artemis.tests.unit.core.journal.impl;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.junit.Before;
-
import java.nio.ByteBuffer;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Assert;
-
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.junit.Before;
public abstract class FileFactoryTestBase extends ActiveMQTestBase
{
@@ -42,15 +40,15 @@ public abstract class FileFactoryTestBase extends ActiveMQTestBase
// Protected ---------------------------------
- protected void checkFill(final SequentialFile file, final int pos, final int size, final byte fillChar) throws Exception
+ protected void checkFill(final SequentialFile file, final int size) throws Exception
{
- file.fill(pos, size, fillChar);
+ file.fill(size);
file.close();
file.open();
- file.position(pos);
+ file.position(0);
ByteBuffer bb = ByteBuffer.allocateDirect(size);
@@ -67,7 +65,7 @@ public abstract class FileFactoryTestBase extends ActiveMQTestBase
for (int i = 0; i < size; i++)
{
// log.debug(" i is " + i);
- Assert.assertEquals(fillChar, bytes[i]);
+ Assert.assertEquals(0, bytes[i]);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
index e340cf2..7e1347e 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
@@ -30,7 +30,7 @@ import org.apache.activemq.artemis.cli.commands.tools.EncodeJournal;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.TestableJournal;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
@@ -104,6 +104,10 @@ public abstract class JournalImplTestBase extends ActiveMQTestBase
protected void resetFileFactory() throws Exception
{
+ if (fileFactory != null)
+ {
+ fileFactory.stop();
+ }
fileFactory = getFileFactory();
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java
index ab86abc..b009092 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestUnit.java
@@ -25,7 +25,7 @@ import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.SimpleEncoding;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
import org.apache.activemq.artemis.tests.util.RandomUtil;
@@ -42,7 +42,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
for (String file : files)
{
- SequentialFile seqFile = fileFactory.createSequentialFile(file, 1);
+ SequentialFile seqFile = fileFactory.createSequentialFile(file);
Assert.assertEquals(fileSize, seqFile.size());
}
@@ -222,7 +222,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
for (String fileStr : files)
{
- SequentialFile file = fileFactory.createSequentialFile(fileStr, 1);
+ SequentialFile file = fileFactory.createSequentialFile(fileStr);
ByteBuffer buffer = fileFactory.newBuffer(JournalImpl.SIZE_HEADER);
@@ -284,7 +284,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
long fileID = Integer.MAX_VALUE;
for (String fileStr : files)
{
- SequentialFile file = fileFactory.createSequentialFile(fileStr, 1);
+ SequentialFile file = fileFactory.createSequentialFile(fileStr);
file.open();
@@ -2138,6 +2138,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
createJournal();
startJournal();
loadAndCheck();
+ stopJournal();
}
@Test
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java
index b5b721e..858227a 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/ReclaimerTest.java
@@ -27,7 +27,7 @@ import java.util.Set;
import org.junit.Assert;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.apache.activemq.artemis.core.journal.impl.Reclaimer;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java
index 469bdf2..60ca28d 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/SequentialFileFactoryTestBase.java
@@ -23,9 +23,9 @@ import java.util.UUID;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.After;
import org.junit.Assert;
@@ -49,14 +49,14 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
@After
public void tearDown() throws Exception
{
- Assert.assertEquals(0, AsynchronousFileImpl.getTotalMaxIO());
-
factory.stop();
factory = null;
ActiveMQTestBase.forceGC();
+ Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
+
super.tearDown();
}
@@ -86,7 +86,7 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
expectedFiles.add(fileName);
- SequentialFile sf = factory.createSequentialFile(fileName, 1);
+ SequentialFile sf = factory.createSequentialFile(fileName);
sf.open();
@@ -98,10 +98,10 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
// Create a couple with a different extension - they shouldn't be picked
// up
- SequentialFile sf1 = factory.createSequentialFile("different.file", 1);
+ SequentialFile sf1 = factory.createSequentialFile("different.file");
sf1.open();
- SequentialFile sf2 = factory.createSequentialFile("different.cheese", 1);
+ SequentialFile sf2 = factory.createSequentialFile("different.cheese");
sf2.open();
List<String> fileNames = factory.listFiles("amq");
@@ -132,22 +132,18 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
@Test
public void testFill() throws Exception
{
- SequentialFile sf = factory.createSequentialFile("fill.amq", 1);
+ SequentialFile sf = factory.createSequentialFile("fill.amq");
sf.open();
try
{
- checkFill(sf, 0, 2048, (byte)'X');
-
- checkFill(sf, 512, 512, (byte)'Y');
-
- checkFill(sf, 0, 1, (byte)'Z');
+ checkFill(sf, 2048);
- checkFill(sf, 512, 1, (byte)'A');
+ checkFill(sf, 512);
- checkFill(sf, 1024, 512 * 4, (byte)'B');
+ checkFill(sf, 512 * 4);
}
finally
{
@@ -158,11 +154,11 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
@Test
public void testDelete() throws Exception
{
- SequentialFile sf = factory.createSequentialFile("delete-me.amq", 1);
+ SequentialFile sf = factory.createSequentialFile("delete-me.amq");
sf.open();
- SequentialFile sf2 = factory.createSequentialFile("delete-me2.amq", 1);
+ SequentialFile sf2 = factory.createSequentialFile("delete-me2.amq");
sf2.open();
@@ -189,7 +185,7 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
@Test
public void testRename() throws Exception
{
- SequentialFile sf = factory.createSequentialFile("test1.amq", 1);
+ SequentialFile sf = factory.createSequentialFile("test1.amq");
sf.open();
@@ -222,7 +218,7 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
@Test
public void testWriteandRead() throws Exception
{
- SequentialFile sf = factory.createSequentialFile("write.amq", 1);
+ SequentialFile sf = factory.createSequentialFile("write.amq");
sf.open();
@@ -291,14 +287,14 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
@Test
public void testPosition() throws Exception
{
- SequentialFile sf = factory.createSequentialFile("position.amq", 1);
+ SequentialFile sf = factory.createSequentialFile("position.amq");
sf.open();
try
{
- sf.fill(0, 3 * 512, (byte)0);
+ sf.fill(3 * 512);
String s1 = "orange";
byte[] bytes1 = s1.getBytes(StandardCharsets.UTF_8);
@@ -376,11 +372,11 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
@Test
public void testOpenClose() throws Exception
{
- SequentialFile sf = factory.createSequentialFile("openclose.amq", 1);
+ SequentialFile sf = factory.createSequentialFile("openclose.amq");
sf.open();
- sf.fill(0, 512, (byte)0);
+ sf.fill(512);
String s1 = "cheesecake";
byte[] bytes1 = s1.getBytes(StandardCharsets.UTF_8);
@@ -418,15 +414,15 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
return ActiveMQBuffers.wrappedBuffer(bytes);
}
- protected void checkFill(final SequentialFile file, final int pos, final int size, final byte fillChar) throws Exception
+ protected void checkFill(final SequentialFile file, final int size) throws Exception
{
- file.fill(pos, size, fillChar);
+ file.fill(size);
file.close();
file.open();
- file.position(pos);
+ file.position(0);
ByteBuffer bb = factory.newBuffer(size);
@@ -437,7 +433,7 @@ public abstract class SequentialFileFactoryTestBase extends ActiveMQTestBase
for (int i = 0; i < size; i++)
{
// log.debug(" i is " + i);
- Assert.assertEquals(fillChar, bb.get(i));
+ Assert.assertEquals(0, bb.get(i));
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java
index 76234b8..21866c6 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/TimedBufferTest.java
@@ -16,11 +16,6 @@
*/
package org.apache.activemq.artemis.tests.unit.core.journal.impl;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.junit.Test;
-
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -28,11 +23,14 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
+import org.apache.activemq.artemis.core.io.buffer.TimedBufferObserver;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Assert;
-
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.impl.TimedBuffer;
-import org.apache.activemq.artemis.core.journal.impl.TimedBufferObserver;
+import org.junit.Test;
public class TimedBufferTest extends ActiveMQTestBase
{
@@ -49,7 +47,7 @@ public class TimedBufferTest extends ActiveMQTestBase
// Public --------------------------------------------------------
- IOAsyncTask dummyCallback = new IOAsyncTask()
+ IOCallback dummyCallback = new IOCallback()
{
public void done()
@@ -69,7 +67,7 @@ public class TimedBufferTest extends ActiveMQTestBase
final AtomicInteger flushTimes = new AtomicInteger(0);
class TestObserver implements TimedBufferObserver
{
- public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOAsyncTask> callbacks)
+ public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks)
{
buffers.add(buffer);
flushTimes.incrementAndGet();
@@ -144,7 +142,7 @@ public class TimedBufferTest extends ActiveMQTestBase
final AtomicInteger flushTimes = new AtomicInteger(0);
class TestObserver implements TimedBufferObserver
{
- public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOAsyncTask> callbacks)
+ public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks)
{
buffers.add(buffer);
flushTimes.incrementAndGet();
@@ -235,7 +233,7 @@ public class TimedBufferTest extends ActiveMQTestBase
{
class TestObserver implements TimedBufferObserver
{
- public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOAsyncTask> callbacks)
+ public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks)
{
}
@@ -321,7 +319,7 @@ public class TimedBufferTest extends ActiveMQTestBase
{
class TestObserver implements TimedBufferObserver
{
- public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOAsyncTask> callbacks)
+ public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks)
{
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
index 59586fd..75a9535 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/fakes/FakeSequentialFileFactory.java
@@ -27,12 +27,11 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.TimedBuffer;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
public class FakeSequentialFileFactory implements SequentialFileFactory
{
@@ -63,9 +62,16 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
this(1, false);
}
+ @Override
+ public int getMaxIO()
+ {
+ return 1;
+ }
+
+
// Public --------------------------------------------------------
- public SequentialFile createSequentialFile(final String fileName, final int maxAIO)
+ public SequentialFile createSequentialFile(final String fileName)
{
FakeSequentialFile sf = fileMap.get(fileName);
@@ -233,11 +239,11 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
final ByteBuffer bytes;
- final IOAsyncTask callback;
+ final IOCallback callback;
volatile boolean sendError;
- CallbackRunnable(final FakeSequentialFile file, final ByteBuffer bytes, final IOAsyncTask callback)
+ CallbackRunnable(final FakeSequentialFile file, final ByteBuffer bytes, final IOCallback callback)
{
this.file = file;
this.bytes = bytes;
@@ -260,11 +266,6 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
{
callback.done();
}
-
- if (file.bufferCallback != null)
- {
- file.bufferCallback.bufferDone(bytes);
- }
}
catch (Throwable e)
{
@@ -288,8 +289,6 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
private ByteBuffer data;
- private BufferCallback bufferCallback;
-
public ByteBuffer getData()
{
return data;
@@ -321,14 +320,6 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
notifyAll();
}
- public synchronized void waitForClose() throws Exception
- {
- while (open)
- {
- this.wait();
- }
- }
-
public void delete()
{
if (open)
@@ -355,26 +346,21 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
checkAndResize(0);
}
- public void setBufferCallback(final BufferCallback callback)
- {
- bufferCallback = callback;
- }
-
- public void fill(final int pos, final int size, final byte fillCharacter) throws Exception
+ public void fill(final int size) throws Exception
{
if (!open)
{
throw new IllegalStateException("Is closed");
}
- checkAndResize(pos + size);
+ checkAndResize(size);
// log.debug("size is " + size + " pos is " + pos);
- for (int i = pos; i < size + pos; i++)
+ for (int i = 0; i < size; i++)
{
byte[] array = data.array();
- array[i] = fillCharacter;
+ array[i] = 0;
// log.debug("Filling " + pos + " with char " + fillCharacter);
}
@@ -385,7 +371,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
return read(bytes, null);
}
- public int read(final ByteBuffer bytes, final IOAsyncTask callback) throws Exception
+ public int read(final ByteBuffer bytes, final IOCallback callback) throws Exception
{
if (!open)
{
@@ -426,7 +412,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
return data.position();
}
- public synchronized void writeDirect(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback)
+ public synchronized void writeDirect(final ByteBuffer bytes, final boolean sync, final IOCallback callback)
{
if (!open)
{
@@ -485,7 +471,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#writeInternal(java.nio.ByteBuffer)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#writeInternal(java.nio.ByteBuffer)
*/
public void writeInternal(ByteBuffer bytes) throws Exception
{
@@ -555,7 +541,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#renameTo(org.apache.activemq.artemis.core.journal.SequentialFile)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#renameTo(org.apache.activemq.artemis.core.io.SequentialFile)
*/
public void renameTo(final String newFileName) throws Exception
{
@@ -565,7 +551,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#fits(int)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#fits(int)
*/
public boolean fits(final int size)
{
@@ -573,21 +559,21 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#setBuffering(boolean)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#setBuffering(boolean)
*/
public void setBuffering(final boolean buffering)
{
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#lockBuffer()
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#lockBuffer()
*/
public void disableAutoFlush()
{
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#unlockBuffer()
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#unlockBuffer()
*/
public void enableAutoFlush()
{
@@ -599,9 +585,9 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#write(org.apache.activemq.artemis.spi.core.remoting.ActiveMQBuffer, boolean, org.apache.activemq.artemis.core.journal.IOCallback)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#write(org.apache.activemq.artemis.spi.core.remoting.ActiveMQBuffer, boolean, org.apache.activemq.artemis.core.journal.IOCallback)
*/
- public void write(final ActiveMQBuffer bytes, final boolean sync, final IOAsyncTask callback) throws Exception
+ public void write(final ActiveMQBuffer bytes, final boolean sync, final IOCallback callback) throws Exception
{
bytes.writerIndex(bytes.capacity());
bytes.readerIndex(0);
@@ -610,7 +596,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#write(org.apache.activemq.artemis.spi.core.remoting.ActiveMQBuffer, boolean)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#write(org.apache.activemq.artemis.spi.core.remoting.ActiveMQBuffer, boolean)
*/
public void write(final ActiveMQBuffer bytes, final boolean sync) throws Exception
{
@@ -620,9 +606,9 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#write(org.apache.activemq.artemis.core.journal.EncodingSupport, boolean, org.apache.activemq.artemis.core.journal.IOCompletion)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#write(org.apache.activemq.artemis.core.journal.EncodingSupport, boolean, org.apache.activemq.artemis.core.journal.IOCompletion)
*/
- public void write(final EncodingSupport bytes, final boolean sync, final IOAsyncTask callback) throws Exception
+ public void write(final EncodingSupport bytes, final boolean sync, final IOCallback callback) throws Exception
{
ByteBuffer buffer = newBuffer(bytes.getEncodeSize());
ActiveMQBuffer outbuffer = ActiveMQBuffers.wrappedBuffer(buffer);
@@ -631,7 +617,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#write(org.apache.activemq.artemis.core.journal.EncodingSupport, boolean)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#write(org.apache.activemq.artemis.core.journal.EncodingSupport, boolean)
*/
public void write(final EncodingSupport bytes, final boolean sync) throws Exception
{
@@ -642,7 +628,7 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#exists()
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#exists()
*/
public boolean exists()
{
@@ -652,14 +638,14 @@ public class FakeSequentialFileFactory implements SequentialFileFactory
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#setTimedBuffer(org.apache.activemq.artemis.core.journal.impl.TimedBuffer)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#setTimedBuffer(org.apache.activemq.artemis.core.io.buffer.TimedBuffer)
*/
public void setTimedBuffer(final TimedBuffer buffer)
{
}
/* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFile#copyTo(org.apache.activemq.artemis.core.journal.SequentialFile)
+ * @see org.apache.activemq.artemis.core.io.SequentialFile#copyTo(org.apache.activemq.artemis.core.io.SequentialFile)
*/
public void copyTo(SequentialFile newFileName)
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java
index 8c4ff47..5accdac 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PageTest.java
@@ -22,9 +22,9 @@ import java.util.List;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.paging.impl.Page;
import org.apache.activemq.artemis.core.paging.impl.PagedMessageImpl;
@@ -52,14 +52,14 @@ public class PageTest extends ActiveMQTestBase
public void testPageWithNIO() throws Exception
{
recreateDirectory(getTestDir());
- testAdd(new NIOSequentialFileFactory(getTestDirfile()), 1000);
+ testAdd(new NIOSequentialFileFactory(getTestDirfile(), 1), 1000);
}
@Test
public void testDamagedDataWithNIO() throws Exception
{
recreateDirectory(getTestDir());
- testDamagedPage(new NIOSequentialFileFactory(getTestDirfile()), 1000);
+ testDamagedPage(new NIOSequentialFileFactory(getTestDirfile(), 1), 1000);
}
@Test
@@ -83,7 +83,7 @@ public class PageTest extends ActiveMQTestBase
protected void testAdd(final SequentialFileFactory factory, final int numberOfElements) throws Exception
{
- SequentialFile file = factory.createSequentialFile("00010.page", 1);
+ SequentialFile file = factory.createSequentialFile("00010.page");
Page impl = new Page(new SimpleString("something"), new NullStorageManager(), factory, file, 10);
@@ -100,7 +100,7 @@ public class PageTest extends ActiveMQTestBase
impl.sync();
impl.close();
- file = factory.createSequentialFile("00010.page", 1);
+ file = factory.createSequentialFile("00010.page");
file.open();
impl = new Page(new SimpleString("something"), new NullStorageManager(), factory, file, 10);
@@ -130,7 +130,7 @@ public class PageTest extends ActiveMQTestBase
protected void testDamagedPage(final SequentialFileFactory factory, final int numberOfElements) throws Exception
{
- SequentialFile file = factory.createSequentialFile("00010.page", 1);
+ SequentialFile file = factory.createSequentialFile("00010.page");
Page impl = new Page(new SimpleString("something"), new NullStorageManager(), factory, file, 10);
@@ -172,7 +172,7 @@ public class PageTest extends ActiveMQTestBase
impl.close();
- file = factory.createSequentialFile("00010.page", 1);
+ file = factory.createSequentialFile("00010.page");
file.open();
impl = new Page(new SimpleString("something"), new NullStorageManager(), factory, file, 10);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
index 1a657c1..3863c12 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
@@ -34,9 +34,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.paging.PagingManager;
@@ -129,7 +129,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase
public void testPageWithNIO() throws Exception
{
ActiveMQTestBase.recreateDirectory(getTestDir());
- testConcurrentPaging(new NIOSequentialFileFactory(new File(getTestDir())), 1);
+ testConcurrentPaging(new NIOSequentialFileFactory(new File(getTestDir()), 1), 1);
}
@Test
@@ -565,7 +565,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase
for (String file : files)
{
- SequentialFile fileTmp = factory.createSequentialFile(file, 1);
+ SequentialFile fileTmp = factory.createSequentialFile(file);
fileTmp.open();
Assert.assertTrue("The page file size (" + fileTmp.size() + ") shouldn't be > " + MAX_SIZE,
fileTmp.size() <= MAX_SIZE);
@@ -645,7 +645,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase
public void testRestartPage() throws Throwable
{
clearDataRecreateServerDirs();
- SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()));
+ SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()), 1);
PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
@@ -682,7 +682,7 @@ public class PagingStoreImplTest extends ActiveMQTestBase
public void testOrderOnPaging() throws Throwable
{
clearDataRecreateServerDirs();
- SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()));
+ SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()), 1);
PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java
index 3c1fb88..f89d61c 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/BatchIDGeneratorUnitTest.java
@@ -25,7 +25,7 @@ import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.persistence.StorageManager;
import org.apache.activemq.artemis.core.persistence.impl.journal.BatchingIDGenerator;
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
@@ -39,7 +39,7 @@ public class BatchIDGeneratorUnitTest extends ActiveMQTestBase
@Test
public void testSequence() throws Exception
{
- NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getTestDir()));
+ NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getTestDir()), 1);
Journal journal = new JournalImpl(10 * 1024, 2, 0, 0, factory, "activemq-bindings", "bindings", 1);
journal.start();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java
index 8e14647..f4abbaa 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/persistence/impl/OperationContextUnitTest.java
@@ -23,8 +23,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
import org.junit.Assert;
import org.junit.Test;
@@ -52,7 +52,7 @@ public class OperationContextUnitTest extends ActiveMQTestBase
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
- impl.executeOnCompletion(new IOAsyncTask()
+ impl.executeOnCompletion(new IOCallback()
{
public void onError(int errorCode, String errorMessage)
@@ -70,7 +70,7 @@ public class OperationContextUnitTest extends ActiveMQTestBase
for (int i = 0; i < 10; i++) impl.storeLineUp();
for (int i = 0; i < 3; i++) impl.pageSyncLineUp();
- impl.executeOnCompletion(new IOAsyncTask()
+ impl.executeOnCompletion(new IOCallback()
{
public void onError(int errorCode, String errorMessage)
@@ -213,7 +213,7 @@ public class OperationContextUnitTest extends ActiveMQTestBase
final AtomicInteger operations = new AtomicInteger(0);
// We should be up to date with lineUps and executions. this should now just finish processing
- context.executeOnCompletion(new IOAsyncTask()
+ context.executeOnCompletion(new IOCallback()
{
public void done()
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java
index 643e6c2..89c017b 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/FileLockTest.java
@@ -17,9 +17,9 @@
package org.apache.activemq.artemis.tests.unit.core.server.impl;
import java.io.File;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.server.impl.AIOFileLockNodeManager;
import org.apache.activemq.artemis.core.server.impl.FileLockNodeManager;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Before;
import org.junit.Test;
@@ -47,7 +47,7 @@ public class FileLockTest extends ActiveMQTestBase
@Test
public void testAIOLock() throws Exception
{
- if (AsynchronousFileImpl.isLoaded())
+ if (LibaioContext.isLoaded())
{
doTestLock(new AIOFileLockNodeManager(getTestDirfile(), false), new AIOFileLockNodeManager(getTestDirfile(), false));
}
[8/9] activemq-artemis git commit: ARTEMIS-163 First pass on the
native AIO refactoring
Posted by an...@apache.org.
ARTEMIS-163 First pass on the native AIO refactoring
https://issues.apache.org/jira/browse/ARTEMIS-163
On this pass I'm just converting the native layer to a simpler one.
It wasn't very easy to change the alignment at the current framework,
so I did some refactoring simplifying the native layer
The volume of the nubmer of changes here is because:
- The API is changed, we now don't close the libaio queue between files
- The native layer won't use malloc as much as it used to, saving some CPU and memory defragmentation
- I organized the code around nio and libaio
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/6fe9e0eb
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/6fe9e0eb
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/6fe9e0eb
Branch: refs/heads/master
Commit: 6fe9e0ebd6504897ba2b3ce7185cc63a0dbc8feb
Parents: 661f695
Author: Clebert Suconic <cl...@apache.org>
Authored: Mon Jul 27 16:15:03 2015 -0400
Committer: Clebert Suconic <cl...@apache.org>
Committed: Wed Jul 29 22:12:03 2015 -0400
----------------------------------------------------------------------
.gitignore | 2 +-
CMakeLists.txt | 18 +
README.md | 2 +-
.../activemq/artemis/cli/commands/Create.java | 90 +-
.../cli/commands/tools/CompactJournal.java | 6 +-
.../cli/commands/tools/DecodeJournal.java | 4 +-
.../cli/commands/tools/EncodeJournal.java | 6 +-
.../cli/commands/tools/XmlDataExporter.java | 6 +-
.../cli/commands/util/SyncCalculation.java | 190 ++++
.../artemis/cli/commands/etc/broker.xml | 1 +
.../commands/etc/journal-buffer-settings.txt | 8 +
.../apache/activemq/cli/test/ArtemisTest.java | 23 +-
.../activemq/cli/test/StreamClassPathTest.java | 1 +
.../artemis/api/core/ActiveMQNativeIOError.java | 5 +
.../journal/JMSJournalStorageManagerImpl.java | 6 +-
.../artemis/core/asyncio/AIOCallback.java | 33 -
.../artemis/core/asyncio/AsynchronousFile.java | 58 -
.../artemis/core/asyncio/BufferCallback.java | 27 -
.../core/asyncio/IOExceptionListener.java | 22 -
.../core/asyncio/impl/ActiveMQFileLock.java | 47 -
.../core/asyncio/impl/AsynchronousFileImpl.java | 822 --------------
.../artemis/core/io/AbstractSequentialFile.java | 407 +++++++
.../core/io/AbstractSequentialFileFactory.java | 224 ++++
.../activemq/artemis/core/io/DummyCallback.java | 49 +
.../activemq/artemis/core/io/IOCallback.java | 33 +
.../core/io/IOCriticalErrorListener.java | 25 +
.../artemis/core/io/IOExceptionListener.java | 22 +
.../artemis/core/io/SequentialFile.java | 116 ++
.../artemis/core/io/SequentialFileFactory.java | 91 ++
.../artemis/core/io/aio/AIOSequentialFile.java | 333 ++++++
.../core/io/aio/AIOSequentialFileFactory.java | 531 +++++++++
.../artemis/core/io/aio/ActiveMQFileLock.java | 47 +
.../artemis/core/io/buffer/TimedBuffer.java | 558 ++++++++++
.../core/io/buffer/TimedBufferObserver.java | 53 +
.../artemis/core/io/nio/NIOSequentialFile.java | 393 +++++++
.../core/io/nio/NIOSequentialFileFactory.java | 168 +++
.../artemis/core/journal/IOAsyncTask.java | 27 -
.../artemis/core/journal/IOCompletion.java | 4 +-
.../core/journal/IOCriticalErrorListener.java | 22 -
.../activemq/artemis/core/journal/Journal.java | 1 +
.../artemis/core/journal/SequentialFile.java | 129 ---
.../core/journal/SequentialFileFactory.java | 89 --
.../core/journal/impl/AIOSequentialFile.java | 326 ------
.../journal/impl/AIOSequentialFileFactory.java | 358 ------
.../journal/impl/AbstractJournalUpdateTask.java | 8 +-
.../journal/impl/AbstractSequentialFile.java | 407 -------
.../impl/AbstractSequentialFileFactory.java | 218 ----
.../core/journal/impl/DummyCallback.java | 48 -
.../core/journal/impl/FileWrapperJournal.java | 2 +-
.../artemis/core/journal/impl/JournalBase.java | 1 +
.../core/journal/impl/JournalCompactor.java | 6 +-
.../artemis/core/journal/impl/JournalFile.java | 2 +-
.../core/journal/impl/JournalFileImpl.java | 2 +-
.../journal/impl/JournalFilesRepository.java | 8 +-
.../artemis/core/journal/impl/JournalImpl.java | 28 +-
.../core/journal/impl/NIOSequentialFile.java | 404 -------
.../journal/impl/NIOSequentialFileFactory.java | 168 ---
.../core/journal/impl/SyncSpeedTest.java | 354 ------
.../artemis/core/journal/impl/TimedBuffer.java | 558 ----------
.../core/journal/impl/TimedBufferObserver.java | 52 -
.../core/journal/impl/TransactionCallback.java | 12 +-
.../artemis/core/io/aio/CallbackOrderTest.java | 97 ++
.../artemis/maven/ActiveMQCreatePlugin.java | 1 +
artemis-native/bin/libartemis-native-32.so | Bin 44082 -> 22260 bytes
artemis-native/bin/libartemis-native-64.so | Bin 46624 -> 23984 bytes
artemis-native/pom.xml | 24 +
artemis-native/src/main/c/AIOController.cpp | 63 --
artemis-native/src/main/c/AIOController.h | 51 -
artemis-native/src/main/c/AIOException.h | 75 --
artemis-native/src/main/c/AsyncFile.cpp | 348 ------
artemis-native/src/main/c/AsyncFile.h | 93 --
artemis-native/src/main/c/CMakeLists.txt | 26 +-
artemis-native/src/main/c/CallbackAdapter.h | 42 -
artemis-native/src/main/c/JAIODatatypes.h | 28 -
.../src/main/c/JNICallbackAdapter.cpp | 62 --
artemis-native/src/main/c/JNICallbackAdapter.h | 66 --
.../src/main/c/JNI_AsynchronousFileImpl.cpp | 377 -------
artemis-native/src/main/c/JavaUtilities.cpp | 62 --
artemis-native/src/main/c/JavaUtilities.h | 26 -
artemis-native/src/main/c/LockClass.h | 39 -
artemis-native/src/main/c/Version.h | 24 -
artemis-native/src/main/c/exception_helper.h | 23 +
...che_activemq_artemis_jlibaio_LibaioContext.c | 710 ++++++++++++
.../activemq/artemis/core/libaio/Native.java | 74 --
.../activemq/artemis/jlibaio/LibaioContext.java | 446 ++++++++
.../activemq/artemis/jlibaio/LibaioFile.java | 152 +++
.../activemq/artemis/jlibaio/NativeLogger.java | 51 +
.../activemq/artemis/jlibaio/SubmitInfo.java | 25 +
.../activemq/artemis/jlibaio/package-info.java | 24 +
.../artemis/jlibaio/util/CallbackCache.java | 93 ++
.../jlibaio/test/CallbackCachelTest.java | 112 ++
.../artemis/jlibaio/test/LibaioTest.java | 859 +++++++++++++++
.../plug/ProtonSessionIntegrationCallback.java | 4 +-
.../core/protocol/mqtt/MQTTPublishManager.java | 4 +-
.../openwire/OpenWireProtocolManager.java | 4 +-
.../protocol/stomp/StompProtocolManager.java | 4 +-
.../deployers/impl/FileConfigurationParser.java | 2 +-
.../artemis/core/paging/PagingManager.java | 2 +-
.../artemis/core/paging/PagingStore.java | 2 +-
.../artemis/core/paging/PagingStoreFactory.java | 2 +-
.../cursor/impl/PageSubscriptionImpl.java | 6 +-
.../activemq/artemis/core/paging/impl/Page.java | 4 +-
.../core/paging/impl/PagingStoreFactoryNIO.java | 8 +-
.../core/paging/impl/PagingStoreImpl.java | 10 +-
.../core/persistence/OperationContext.java | 4 +-
.../core/persistence/StorageManager.java | 6 +-
.../impl/journal/DescribeJournal.java | 8 +-
.../impl/journal/JournalStorageManager.java | 33 +-
.../impl/journal/LargeServerMessageImpl.java | 2 +-
.../impl/journal/LargeServerMessageInSync.java | 4 +-
.../impl/journal/OperationContextImpl.java | 12 +-
.../nullpm/NullStorageLargeServerMessage.java | 2 +-
.../impl/nullpm/NullStorageManager.java | 8 +-
.../core/postoffice/impl/PostOfficeImpl.java | 6 +-
.../core/ServerSessionPacketHandler.java | 4 +-
.../core/replication/ReplicatedJournal.java | 2 +-
.../core/replication/ReplicationEndpoint.java | 6 +-
.../core/replication/ReplicationManager.java | 2 +-
.../core/server/ActiveMQServerLogger.java | 10 +-
.../artemis/core/server/LargeServerMessage.java | 2 +-
.../core/server/cluster/impl/Redistributor.java | 4 +-
.../server/impl/AIOFileLockNodeManager.java | 29 +-
.../core/server/impl/ActiveMQServerImpl.java | 18 +-
.../artemis/core/server/impl/QueueImpl.java | 4 +-
.../core/server/impl/ServerSessionImpl.java | 4 +-
.../core/transaction/impl/TransactionImpl.java | 8 +-
.../artemis/tests/util/ActiveMQTestBase.java | 66 +-
.../tests/util/ColocatedActiveMQServer.java | 7 +-
.../integration/client/HangConsumerTest.java | 6 +-
.../integration/client/JournalCrashTest.java | 4 +-
.../client/LibaioDependencyCheckTest.java | 4 +-
.../tests/integration/client/PagingTest.java | 8 +-
.../client/RedeliveryConsumerTest.java | 4 +-
.../integration/cluster/bridge/BridgeTest.java | 6 +-
.../journal/AIOImportExportTest.java | 6 +-
.../journal/AIOJournalCompactTest.java | 6 +-
.../integration/journal/AIOJournalImplTest.java | 10 +-
.../journal/AIOSequentialFileFactoryTest.java | 10 +-
.../journal/NIOBufferedJournalCompactTest.java | 6 +-
.../journal/NIOImportExportTest.java | 6 +-
.../journal/NIOJournalCompactTest.java | 16 +-
.../integration/journal/NIOJournalImplTest.java | 6 +-
.../journal/NIONoBufferJournalImplTest.java | 6 +-
...NIONonBufferedSequentialFileFactoryTest.java | 6 +-
.../journal/NIOSequentialFileFactoryTest.java | 6 +-
.../journal/ValidateTransactionHealthTest.java | 15 +-
.../management/ActiveMQServerControlTest.java | 12 +-
.../replication/ReplicationTest.java | 16 +-
.../integration/server/FileLockTimeoutTest.java | 4 +-
.../journal/FakeJournalImplTest.java | 2 +-
.../journal/JournalImplTestUnit.java | 13 +-
.../journal/RealJournalImplAIOTest.java | 6 +-
.../journal/RealJournalImplNIOTest.java | 6 +-
.../AIOAllPossibilitiesCompactStressTest.java | 6 +-
.../AIOMultiThreadCompactorStressTest.java | 2 +-
.../stress/journal/AddAndRemoveStressTest.java | 16 +-
.../stress/journal/CompactingStressTest.java | 12 +-
.../JournalCleanupCompactStressTest.java | 50 +-
.../stress/journal/MixupCompactorTestBase.java | 6 +-
.../NIOMultiThreadCompactorStressTest.java | 8 +-
.../core/journal/impl/AIOJournalImplTest.java | 6 +-
.../core/journal/impl/FakeJournalImplTest.java | 2 +-
.../core/journal/impl/JournalImplTestUnit.java | 15 +-
.../core/journal/impl/NIOJournalImplTest.java | 6 +-
.../tests/unit/core/asyncio/AIOTestBase.java | 18 +-
.../unit/core/asyncio/AsynchronousFileTest.java | 1015 ------------------
.../MultiThreadAsynchronousFileTest.java | 81 +-
.../journal/impl/AlignedJournalImplTest.java | 14 +-
.../unit/core/journal/impl/CleanBufferTest.java | 16 +-
.../core/journal/impl/FakeJournalImplTest.java | 2 +-
.../impl/FakeSequentialFileFactoryTest.java | 2 +-
.../core/journal/impl/FileFactoryTestBase.java | 18 +-
.../core/journal/impl/JournalImplTestBase.java | 6 +-
.../core/journal/impl/JournalImplTestUnit.java | 9 +-
.../unit/core/journal/impl/ReclaimerTest.java | 2 +-
.../impl/SequentialFileFactoryTestBase.java | 52 +-
.../unit/core/journal/impl/TimedBufferTest.java | 26 +-
.../impl/fakes/FakeSequentialFileFactory.java | 84 +-
.../tests/unit/core/paging/impl/PageTest.java | 18 +-
.../core/paging/impl/PagingStoreImplTest.java | 14 +-
.../impl/BatchIDGeneratorUnitTest.java | 4 +-
.../impl/OperationContextUnitTest.java | 8 +-
.../unit/core/server/impl/FileLockTest.java | 4 +-
183 files changed, 6522 insertions(+), 7227 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 71af624..ce57485 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,4 @@ ratReport.txt
**/cmake_install.cmake
# this file is generated
-artemis-native/src/main/c/org_apache_activemq_artemis_core_libaio_Native.h
+artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.h
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..4681205
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,18 @@
+# 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.
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SUBDIRS(artemis-native)
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 65155f3..195441f 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ This file describes some minimum 'stuff one needs to know' to get started coding
## Source
-For details about the modifying the code, building the project, running tests, IDE integration, etc. see
+For details about the modifying the code, building the project, running tests, IDE integration, etc. see
our [Hacking Guide](./docs/hacking-guide/en/SUMMARY.md).
## Examples
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
index 7495ce2..2fdf5f2 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
@@ -26,6 +26,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
+import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -36,8 +37,10 @@ import java.util.regex.Pattern;
import io.airlift.airline.Arguments;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
+import org.apache.activemq.artemis.cli.commands.util.SyncCalculation;
import org.apache.activemq.artemis.core.server.cluster.impl.MessageLoadBalancingType;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
import static java.nio.file.attribute.PosixFilePermission.GROUP_EXECUTE;
import static java.nio.file.attribute.PosixFilePermission.GROUP_READ;
@@ -84,6 +87,7 @@ public class Create extends InputAbstract
public static final String ETC_CLUSTER_SETTINGS_TXT = "etc/cluster-settings.txt";
public static final String ETC_CONNECTOR_SETTINGS_TXT = "etc/connector-settings.txt";
public static final String ETC_BOOTSTRAP_WEB_SETTINGS_TXT = "etc/bootstrap-web-settings.txt";
+ public static final String ETC_JOURNAL_BUFFER_SETTINGS = "etc/journal-buffer-settings.txt";
@Arguments(description = "The instance directory to hold the broker's configuration and data. Path must be writable.", required = true)
File directory;
@@ -142,6 +146,9 @@ public class Create extends InputAbstract
@Option(name = "--require-login", description = "This will configure security to require user / password, opposite of --allow-anonymous")
Boolean requireLogin = null;
+ @Option(name = "--no-sync-test", description = "Disable the calculation for the buffer")
+ boolean noSyncTest;
+
@Option(name = "--user", description = "The username (Default: input)")
String user;
@@ -529,12 +536,16 @@ public class Create extends InputAbstract
filters.put("${shared-store.settings}", "");
}
- if (IS_WINDOWS || !AsynchronousFileImpl.isLoaded())
+ boolean aio;
+
+ if (IS_WINDOWS || !supportsLibaio())
{
+ aio = false;
filters.put("${journal.settings}", "NIO");
}
else
{
+ aio = true;
filters.put("${journal.settings}", "ASYNCIO");
}
@@ -590,7 +601,8 @@ public class Create extends InputAbstract
new File(directory, "etc").mkdirs();
new File(directory, "log").mkdirs();
new File(directory, "tmp").mkdirs();
- new File(directory, "data").mkdirs();
+ File dataFolder = new File(directory, "data");
+ dataFolder.mkdirs();
if (javaOptions == null || javaOptions.length() == 0)
{
@@ -638,7 +650,7 @@ public class Create extends InputAbstract
filters.put("${bootstrap-web-settings}", applyFilters(readTextFile(ETC_BOOTSTRAP_WEB_SETTINGS_TXT), filters));
}
-
+ performSyncCalc(filters, aio, dataFolder);
write(ETC_BOOTSTRAP_XML, filters, false);
write(ETC_BROKER_XML, filters, false);
@@ -694,6 +706,76 @@ public class Create extends InputAbstract
return null;
}
+ private void performSyncCalc(HashMap<String, String> filters, boolean aio, File dataFolder)
+ {
+ if (noSyncTest)
+ {
+ filters.put("${journal-buffer.settings}", "");
+ }
+ else
+ {
+ try
+ {
+ int writes = 250;
+ System.out.println("");
+ System.out.println("Performing write sync calculation...");
+
+ long time = SyncCalculation.syncTest(dataFolder, 4096, writes, 5, verbose, aio);
+ long nanoseconds = SyncCalculation.toNanos(time, writes);
+ double writesPerMillisecond = (double)writes / (double) time;
+
+ String writesPerMillisecondStr = new DecimalFormat("###.##").format(writesPerMillisecond);
+
+ HashMap<String, String> syncFilter = new HashMap<String, String>();
+ syncFilter.put("${nanoseconds}", Long.toString(nanoseconds));
+ syncFilter.put("${writesPerMillisecond}", writesPerMillisecondStr);
+
+ System.out.println("done! Your system can make " + writesPerMillisecondStr +
+ " writes per millisecond, your journal-buffer-timeout will be " + nanoseconds);
+
+ filters.put("${journal-buffer.settings}", applyFilters(readTextFile(ETC_JOURNAL_BUFFER_SETTINGS), syncFilter));
+
+ }
+ catch (Exception e)
+ {
+ filters.put("${journal-buffer.settings}", "");
+ e.printStackTrace();
+ System.err.println("Couldn't perform sync calculation, using default values");
+ }
+ }
+ }
+
+ private boolean supportsLibaio()
+ {
+ if (LibaioContext.isLoaded())
+ {
+ try (LibaioContext context = new LibaioContext(1, true))
+ {
+ File tmpFile = new File(directory, "validateAIO.bin");
+ boolean supportsLibaio = true;
+ try
+ {
+ LibaioFile file = context.openFile(tmpFile, true);
+ file.close();
+ }
+ catch (Exception e)
+ {
+ supportsLibaio = false;
+ }
+ tmpFile.delete();
+ if (!supportsLibaio)
+ {
+ System.err.println("The filesystem used on " + directory + " doesn't support libAIO and O_DIRECT files, switching journal-type to NIO");
+ }
+ return supportsLibaio;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
private void makeExec(String path) throws IOException
{
try
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
index 0239998..38fb785 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
@@ -22,9 +22,9 @@ import io.airlift.airline.Command;
import org.apache.activemq.artemis.cli.commands.Action;
import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
@Command(name = "compact", description = "Compacts the journal of a non running server")
public final class CompactJournal extends DataAbstract implements Action
@@ -54,7 +54,7 @@ public final class CompactJournal extends DataAbstract implements Action
final int fileSize,
final IOCriticalErrorListener listener) throws Exception
{
- NIOSequentialFileFactory nio = new NIOSequentialFileFactory(directory, listener);
+ NIOSequentialFileFactory nio = new NIOSequentialFileFactory(directory, listener, 1);
JournalImpl journal = new JournalImpl(fileSize, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
index 5b28a18..6b608c3 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
@@ -35,7 +35,7 @@ import org.apache.activemq.artemis.cli.commands.Configurable;
import org.apache.activemq.artemis.core.journal.RecordInfo;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.apache.activemq.artemis.core.journal.impl.JournalRecord;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.utils.Base64;
@Command(name = "decode", description = "Decode a journal's internal format into a new journal set of files")
@@ -117,7 +117,7 @@ public class DecodeJournal extends Configurable implements Action
System.err.println("Could not create directory " + directory);
}
- NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null);
+ NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null, 1);
JournalImpl journal = new JournalImpl(fileSize, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
index 8b0721b..a408951 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
@@ -28,11 +28,11 @@ import org.apache.activemq.artemis.cli.commands.Action;
import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.cli.commands.Configurable;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.apache.activemq.artemis.core.journal.impl.JournalReaderCallback;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.utils.Base64;
@Command(name = "encode", description = "Encode a set of journal files into an internal encoded data format")
@@ -113,7 +113,7 @@ public class EncodeJournal extends Configurable implements Action
final int fileSize,
final PrintStream out) throws Exception
{
- NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null);
+ NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null, 1);
JournalImpl journal = new JournalImpl(fileSize, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
index e099a0b..cf5be12 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
@@ -52,10 +52,10 @@ import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.message.BodyEncoder;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.paging.PagingManager;
@@ -345,7 +345,7 @@ public final class XmlDataExporter extends DataAbstract implements Action
private void getJmsBindings() throws Exception
{
- SequentialFileFactory bindingsJMS = new NIOSequentialFileFactory(config.getBindingsLocation());
+ SequentialFileFactory bindingsJMS = new NIOSequentialFileFactory(config.getBindingsLocation(), 1);
Journal jmsJournal = new JournalImpl(1024 * 1024,
2,
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java
new file mode 100644
index 0000000..b5a8845
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/SyncCalculation.java
@@ -0,0 +1,190 @@
+/**
+ * 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.cli.commands.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.text.DecimalFormat;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.utils.ReusableLatch;
+
+/**
+ * It will perform a simple test to evaluate how many syncs a disk can make per second
+ * * *
+ */
+public class SyncCalculation
+{
+ /**
+ * It will perform a write test of blockSize * bocks, sinc on each write, for N tries.
+ * It will return the lowest spent time from the tries.
+ */
+ public static long syncTest(File datafolder, int blockSize, int blocks, int tries, boolean verbose, boolean aio) throws Exception
+ {
+ SequentialFileFactory factory = newFactory(datafolder, aio);
+ SequentialFile file = factory.createSequentialFile("test.tmp");
+
+ try
+ {
+ file.delete();
+ file.open();
+
+ file.fill(blockSize * blocks);
+
+ long[] result = new long[tries];
+
+ byte[] block = new byte[blockSize];
+
+ for (int i = 0; i < block.length; i++)
+ {
+ block[i] = (byte) 't';
+ }
+
+ ByteBuffer bufferBlock = factory.newBuffer(blockSize);
+ bufferBlock.put(block);
+ bufferBlock.position(0);
+
+ final ReusableLatch latch = new ReusableLatch(0);
+
+ IOCallback callback = new IOCallback()
+ {
+ @Override
+ public void done()
+ {
+ latch.countDown();
+ }
+
+ @Override
+ public void onError(int errorCode, String errorMessage)
+ {
+
+ }
+ };
+
+ DecimalFormat dcformat = new DecimalFormat("###.##");
+ for (int ntry = 0; ntry < tries; ntry++)
+ {
+
+ if (verbose)
+ {
+ System.out.println("**************************************************");
+ System.out.println(ntry + " of " + tries + " calculation");
+ }
+ file.position(0);
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < blocks; i++)
+ {
+ bufferBlock.position(0);
+ latch.countUp();
+ file.writeDirect(bufferBlock, true, callback);
+ if (!latch.await(5, TimeUnit.SECONDS))
+ {
+ throw new IOException("Callback wasn't called");
+ }
+ }
+ long end = System.currentTimeMillis();
+
+ result[ntry] = (end - start);
+
+ if (verbose)
+ {
+ double writesPerMillisecond = (double)blocks / (double) result[ntry];
+ System.out.println("Time = " + result[ntry]);
+ System.out.println("Writes / millisecond = " + dcformat.format(writesPerMillisecond));
+ System.out.println("bufferTimeout = " + toNanos(result[ntry], blocks));
+ System.out.println("**************************************************");
+ }
+ }
+
+ factory.releaseDirectBuffer(bufferBlock);
+
+ long totalTime = Long.MAX_VALUE;
+ for (int i = 0; i < tries; i++)
+ {
+ if (result[i] < totalTime)
+ {
+ totalTime = result[i];
+ }
+ }
+
+ return totalTime;
+ }
+ finally
+ {
+ try
+ {
+ file.close();
+ }
+ catch (Exception e)
+ {
+ }
+ try
+ {
+ file.delete();
+ }
+ catch (Exception e)
+ {
+ }
+ try
+ {
+ factory.stop();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+
+ public static long toNanos(long time, long blocks)
+ {
+
+ double blocksPerMillisecond = (double) blocks / (double) (time);
+
+ long nanoSeconds = TimeUnit.NANOSECONDS.convert(1, TimeUnit.MILLISECONDS);
+
+ long timeWait = (long) (nanoSeconds / blocksPerMillisecond);
+
+ return timeWait;
+ }
+
+ private static SequentialFileFactory newFactory(File datafolder, boolean aio)
+ {
+ if (aio && LibaioContext.isLoaded())
+ {
+ SequentialFileFactory factory = new AIOSequentialFileFactory(datafolder, 1);
+ factory.start();
+ ((AIOSequentialFileFactory) factory).disableBufferReuse();
+
+ return factory;
+ }
+ else
+ {
+ SequentialFileFactory factory = new NIOSequentialFileFactory(datafolder, 1);
+ factory.start();
+ return factory;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
index 52d665e..1cd3245 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
@@ -42,6 +42,7 @@ under the License.
<large-messages-directory>${data.dir}/large-messages</large-messages-directory>
<journal-min-files>10</journal-min-files>
+${journal-buffer.settings}
${connector-config.settings}
<acceptors>
<!-- Default ActiveMQ Artemis Acceptor. Multi-protocol adapter. Currently supports Core, OpenWire, Stomp and AMQP. -->
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/journal-buffer-settings.txt
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/journal-buffer-settings.txt b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/journal-buffer-settings.txt
new file mode 100644
index 0000000..566c29e
--- /dev/null
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/journal-buffer-settings.txt
@@ -0,0 +1,8 @@
+
+ <!--
+ This value was determined through a calculation.
+ Your system could perform ${writesPerMillisecond} writes per millisecond
+ on the current journal configuration.
+ That translates as a sync write every ${nanoseconds} nanoseconds
+ -->
+ <journal-buffer-timeout>${nanoseconds}</journal-buffer-timeout>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
index 99c8f23..3aed71e 100644
--- a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
+++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
@@ -25,6 +25,8 @@ import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.cli.Artemis;
import org.apache.activemq.artemis.cli.commands.Run;
+import org.apache.activemq.artemis.cli.commands.util.SyncCalculation;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
import org.junit.After;
@@ -69,15 +71,29 @@ public class ArtemisTest
}
@Test
+ public void testSync() throws Exception
+ {
+ int writes = 2560;
+ int tries = 10;
+ long totalAvg = SyncCalculation.syncTest(temporaryFolder.getRoot(), 4096, writes, tries, true, true);
+ System.out.println();
+ System.out.println("TotalAvg = " + totalAvg);
+ long nanoTime = SyncCalculation.toNanos(totalAvg, writes);
+ System.out.println("nanoTime avg = " + nanoTime);
+ Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
+
+ }
+
+ @Test
public void testSimpleRun() throws Exception
{
Run.setEmbedded(true);
Artemis.main("create", temporaryFolder.getRoot().getAbsolutePath(), "--force", "--silent-input", "--no-web");
System.setProperty("artemis.instance", temporaryFolder.getRoot().getAbsolutePath());
// Some exceptions may happen on the initialization, but they should be ok on start the basic core protocol
- Artemis.main("run");
- Assert.assertEquals(Integer.valueOf(70), Artemis.execute("producer", "--txt-size", "50", "--message-count", "70", "--verbose"));
- Assert.assertEquals(Integer.valueOf(70), Artemis.execute("consumer", "--txt-size", "50", "--verbose", "--break-on-null", "--receive-timeout", "100"));
+ Artemis.execute("run");
+ Assert.assertEquals(Integer.valueOf(1000), Artemis.execute("producer", "--message-count", "1000", "--verbose"));
+ Assert.assertEquals(Integer.valueOf(1000), Artemis.execute("consumer", "--verbose", "--break-on-null", "--receive-timeout", "100"));
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = cf.createConnection();
@@ -116,6 +132,7 @@ public class ArtemisTest
Artemis.execute("stop");
Assert.assertTrue(Run.latchRunning.await(5, TimeUnit.SECONDS));
+ Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
index 632e2c0..0ee3afb 100644
--- a/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
+++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
@@ -49,6 +49,7 @@ public class StreamClassPathTest
openStream(Create.ETC_CLUSTER_SETTINGS_TXT);
openStream(Create.ETC_CONNECTOR_SETTINGS_TXT);
openStream(Create.ETC_BOOTSTRAP_WEB_SETTINGS_TXT);
+ openStream(Create.ETC_JOURNAL_BUFFER_SETTINGS);
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java
index 8a47dfa..e69a7fd 100644
--- a/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ActiveMQNativeIOError.java
@@ -34,4 +34,9 @@ public final class ActiveMQNativeIOError extends ActiveMQException
{
super(ActiveMQExceptionType.NATIVE_ERROR_CANT_INITIALIZE_AIO, msg);
}
+
+ public ActiveMQNativeIOError(String msg, Throwable e)
+ {
+ super(ActiveMQExceptionType.NATIVE_ERROR_CANT_INITIALIZE_AIO, msg, e);
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java
index b3ef038..2d884e7 100644
--- a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java
+++ b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/persistence/impl/journal/JMSJournalStorageManagerImpl.java
@@ -29,9 +29,9 @@ import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.replication.ReplicatedJournal;
import org.apache.activemq.artemis.core.replication.ReplicationManager;
import org.apache.activemq.artemis.core.server.JournalType;
@@ -87,7 +87,7 @@ public final class JMSJournalStorageManagerImpl implements JMSStorageManager
createDir = config.isCreateBindingsDir();
- SequentialFileFactory bindingsJMS = new NIOSequentialFileFactory(config.getBindingsLocation());
+ SequentialFileFactory bindingsJMS = new NIOSequentialFileFactory(config.getBindingsLocation(), 1);
Journal localJMS = new JournalImpl(1024 * 1024,
2,
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AIOCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AIOCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AIOCallback.java
deleted file mode 100644
index 80aa753..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AIOCallback.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.core.asyncio;
-
-/**
- * The interface used for AIO Callbacks.
- */
-public interface AIOCallback
-{
- /**
- * Method for sync notifications. When this callback method is called, there is a guarantee the data is written on the disk.
- * <br><b>Note:</b><i>Leave this method as soon as possible, or you would be blocking the whole notification thread</i> */
- void done();
-
- /**
- * Method for error notifications.
- * Observation: The whole file will be probably failing if this happens. Like, if you delete the file, you will start to get errors for these operations*/
- void onError(int errorCode, String errorMessage);
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AsynchronousFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AsynchronousFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AsynchronousFile.java
deleted file mode 100644
index 52b8e05..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/AsynchronousFile.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.core.asyncio;
-
-import java.nio.ByteBuffer;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-
-public interface AsynchronousFile
-{
- void close() throws InterruptedException, ActiveMQException;
-
- /**
- *
- * Note: If you are using a native Linux implementation, maxIO can't be higher than what's defined on /proc/sys/fs/aio-max-nr, or you would get an error
- * @param fileName
- * @param maxIO The number of max concurrent asynchronous IO operations. It has to be balanced between the size of your writes and the capacity of your disk.
- * @throws ActiveMQException
- */
- void open(String fileName, int maxIO) throws ActiveMQException;
-
- /**
- * Warning: This function will perform a synchronous IO, probably translating to a fstat call
- * @throws ActiveMQException
- * */
- long size() throws ActiveMQException;
-
- /** Any error will be reported on the callback interface */
- void write(long position, long size, ByteBuffer directByteBuffer, AIOCallback aioCallback);
-
- /**
- * Performs an internal direct write.
- * @throws ActiveMQException
- */
- void writeInternal(long positionToWrite, long size, ByteBuffer bytes) throws ActiveMQException;
-
- void read(long position, long size, ByteBuffer directByteBuffer, AIOCallback aioCallback) throws ActiveMQException;
-
- void fill(long position, int blocks, long size, byte fillChar) throws ActiveMQException;
-
- void setBufferCallback(BufferCallback callback);
-
- int getBlockSize();
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/BufferCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/BufferCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/BufferCallback.java
deleted file mode 100644
index e7b0ca5..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/BufferCallback.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.core.asyncio;
-
-import java.nio.ByteBuffer;
-
-/**
- * Used to receive a notification on completed buffers used by the AIO layer.
- */
-public interface BufferCallback
-{
- void bufferDone(ByteBuffer buffer);
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/IOExceptionListener.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/IOExceptionListener.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/IOExceptionListener.java
deleted file mode 100644
index 0cfe945..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/IOExceptionListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.core.asyncio;
-
-public interface IOExceptionListener
-{
- void onIOException(Exception exception, String message);
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/ActiveMQFileLock.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/ActiveMQFileLock.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/ActiveMQFileLock.java
deleted file mode 100644
index 0af3152..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/ActiveMQFileLock.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.core.asyncio.impl;
-
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-
-import org.apache.activemq.artemis.core.libaio.Native;
-
-public class ActiveMQFileLock extends FileLock
-{
-
- private final int handle;
-
- protected ActiveMQFileLock(final int handle)
- {
- super((FileChannel)null, 0, 0, false);
- this.handle = handle;
- }
-
- @Override
- public boolean isValid()
- {
- return true;
- }
-
- @Override
- public void release() throws IOException
- {
- Native.closeFile(handle);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/AsynchronousFileImpl.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/AsynchronousFileImpl.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/AsynchronousFileImpl.java
deleted file mode 100644
index be4d885..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/asyncio/impl/AsynchronousFileImpl.java
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * 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.core.asyncio.impl;
-
-import java.nio.ByteBuffer;
-import java.nio.channels.FileLock;
-import java.util.PriorityQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-import org.apache.activemq.artemis.core.asyncio.AsynchronousFile;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
-import org.apache.activemq.artemis.core.asyncio.IOExceptionListener;
-import org.apache.activemq.artemis.core.libaio.Native;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-import org.apache.activemq.artemis.utils.ReusableLatch;
-
-/**
- * AsynchronousFile implementation
- *
- * Warning: Case you refactor the name or the package of this class
- * You need to make sure you also rename the C++ native calls
- */
-public class AsynchronousFileImpl implements AsynchronousFile
-{
- // Static ----------------------------------------------------------------------------
-
- private static final AtomicInteger totalMaxIO = new AtomicInteger(0);
-
- private static boolean loaded = false;
-
- /**
- * This definition needs to match Version.h on the native sources.
- * <br>
- * Or else the native module won't be loaded because of version mismatches
- */
- private static final int EXPECTED_NATIVE_VERSION = 52;
-
- /**
- * Used to determine the next writing sequence
- */
- private final AtomicLong nextWritingSequence = new AtomicLong(0);
-
- /**
- * Used to determine the next writing sequence.
- * This is accessed from a single thread (the Poller Thread)
- */
- private long nextReadSequence = 0;
-
- /**
- * AIO can't guarantee ordering over callbacks.
- * <br>
- * We use this {@link PriorityQueue} to hold values until they are in order
- */
- private final PriorityQueue<CallbackHolder> pendingCallbacks = new PriorityQueue<CallbackHolder>();
-
- public static void addMax(final int io)
- {
- AsynchronousFileImpl.totalMaxIO.addAndGet(io);
- }
-
- /**
- * For test purposes
- */
- public static int getTotalMaxIO()
- {
- return AsynchronousFileImpl.totalMaxIO.get();
- }
-
- public static void resetMaxAIO()
- {
- AsynchronousFileImpl.totalMaxIO.set(0);
- }
-
- public static int openFile(String fileName)
- {
- return Native.openFile(fileName);
- }
-
- public static void closeFile(int handle)
- {
- Native.closeFile(handle);
- }
-
- public static void destroyBuffer(ByteBuffer buffer)
- {
- Native.destroyBuffer(buffer);
- }
-
- private static boolean loadLibrary(final String name)
- {
- try
- {
- ActiveMQJournalLogger.LOGGER.trace(name + " being loaded");
- System.loadLibrary(name);
- if (Native.getNativeVersion() != AsynchronousFileImpl.EXPECTED_NATIVE_VERSION)
- {
- ActiveMQJournalLogger.LOGGER.incompatibleNativeLibrary();
- return false;
- }
- else
- {
- return true;
- }
- }
- catch (Throwable e)
- {
- ActiveMQJournalLogger.LOGGER.debug(name + " -> error loading the native library", e);
- return false;
- }
-
- }
-
- static
- {
- String[] libraries = new String[]{"artemis-native", "artemis-native-64", "artemis-native-32"};
-
- for (String library : libraries)
- {
- if (AsynchronousFileImpl.loadLibrary(library))
- {
- AsynchronousFileImpl.loaded = true;
- break;
- }
- else
- {
- ActiveMQJournalLogger.LOGGER.debug("Library " + library + " not found!");
- }
- }
-
- if (!AsynchronousFileImpl.loaded)
- {
- ActiveMQJournalLogger.LOGGER.debug("Couldn't locate LibAIO Wrapper");
- }
- }
-
- public static boolean isLoaded()
- {
- return AsynchronousFileImpl.loaded;
- }
-
- // Attributes ------------------------------------------------------------------------
-
- private boolean opened = false;
-
- private String fileName;
-
- /**
- * Used while inside the callbackDone and callbackError
- */
- private final Lock callbackLock = new ReentrantLock();
-
- private final ReusableLatch pollerLatch = new ReusableLatch();
-
- private volatile Runnable poller;
-
- private int maxIO;
-
- private final Lock writeLock = new ReentrantReadWriteLock().writeLock();
-
- private final ReusableLatch pendingWrites = new ReusableLatch();
-
- private Semaphore maxIOSemaphore;
-
- private BufferCallback bufferCallback;
-
- /**
- * A callback for IO errors when they happen
- */
- private final IOExceptionListener ioExceptionListener;
-
- /**
- * Warning: Beware of the C++ pointer! It will bite you! :-)
- */
- private ByteBuffer handler;
-
- // A context switch on AIO would make it to synchronize the disk before
- // switching to the new thread, what would cause
- // serious performance problems. Because of that we make all the writes on
- // AIO using a single thread.
- private final Executor writeExecutor;
-
- private final Executor pollerExecutor;
-
- // AsynchronousFile implementation ---------------------------------------------------
-
- /**
- * @param writeExecutor It needs to be a single Thread executor. If null it will use the user thread to execute write operations
- * @param pollerExecutor The thread pool that will initialize poller handlers
- */
- public AsynchronousFileImpl(final Executor writeExecutor, final Executor pollerExecutor, final IOExceptionListener ioExceptionListener)
- {
- this.writeExecutor = writeExecutor;
- this.pollerExecutor = pollerExecutor;
- this.ioExceptionListener = ioExceptionListener;
- }
-
- public AsynchronousFileImpl(final Executor writeExecutor, final Executor pollerExecutor)
- {
- this(writeExecutor, pollerExecutor, null);
- }
-
- public void open(final String fileName1, final int maxIOArgument) throws ActiveMQException
- {
- writeLock.lock();
-
- try
- {
- if (opened)
- {
- throw new IllegalStateException("AsynchronousFile is already opened");
- }
-
- this.maxIO = maxIOArgument;
- maxIOSemaphore = new Semaphore(this.maxIO);
-
- this.fileName = fileName1;
-
- try
- {
- handler = Native.init(AsynchronousFileImpl.class, fileName1, this.maxIO, ActiveMQJournalLogger.LOGGER);
- }
- catch (ActiveMQException e)
- {
- ActiveMQException ex = null;
- if (e.getType() == ActiveMQExceptionType.NATIVE_ERROR_CANT_INITIALIZE_AIO)
- {
- ex = new ActiveMQException(e.getType(),
- "Can't initialize AIO. Currently AIO in use = " + AsynchronousFileImpl.totalMaxIO.get() +
- ", trying to allocate more " +
- maxIOArgument,
- e);
- }
- else
- {
- ex = e;
- }
- throw ex;
- }
- opened = true;
- AsynchronousFileImpl.addMax(this.maxIO);
- nextWritingSequence.set(0);
- nextReadSequence = 0;
- }
- finally
- {
- writeLock.unlock();
- }
- }
-
- public void close() throws InterruptedException, ActiveMQException
- {
- checkOpened();
-
- writeLock.lock();
-
- try
- {
-
- while (!pendingWrites.await(60000))
- {
- ActiveMQJournalLogger.LOGGER.couldNotGetLock(fileName);
- }
-
- while (!maxIOSemaphore.tryAcquire(maxIO, 60, TimeUnit.SECONDS))
- {
- ActiveMQJournalLogger.LOGGER.couldNotGetLock(fileName);
- }
-
- maxIOSemaphore = null;
- if (poller != null)
- {
- stopPoller();
- }
-
- if (handler != null)
- {
- Native.closeInternal(handler);
- AsynchronousFileImpl.addMax(-maxIO);
- }
- opened = false;
- handler = null;
- }
- finally
- {
- writeLock.unlock();
- }
- }
-
-
- public void writeInternal(long positionToWrite, long size, ByteBuffer bytes) throws ActiveMQException
- {
- try
- {
- Native.writeInternal(handler, positionToWrite, size, bytes);
- }
- catch (ActiveMQException e)
- {
- fireExceptionListener(e.getType().getCode(), e.getMessage());
- throw e;
- }
- if (bufferCallback != null)
- {
- bufferCallback.bufferDone(bytes);
- }
- }
-
-
- public void write(final long position,
- final long size,
- final ByteBuffer directByteBuffer,
- final AIOCallback aioCallback)
- {
- if (aioCallback == null)
- {
- throw new NullPointerException("Null Callback");
- }
-
- checkOpened();
- if (poller == null)
- {
- startPoller();
- }
-
- pendingWrites.countUp();
-
- if (writeExecutor != null)
- {
- maxIOSemaphore.acquireUninterruptibly();
-
- writeExecutor.execute(new Runnable()
- {
- public void run()
- {
- long sequence = nextWritingSequence.getAndIncrement();
-
- try
- {
- Native.write(AsynchronousFileImpl.this, handler, sequence, position, size, directByteBuffer, aioCallback);
- }
- catch (ActiveMQException e)
- {
- callbackError(aioCallback, sequence, directByteBuffer, e.getType().getCode(), e.getMessage());
- }
- catch (RuntimeException e)
- {
- callbackError(aioCallback,
- sequence,
- directByteBuffer,
- ActiveMQExceptionType.INTERNAL_ERROR.getCode(),
- e.getMessage());
- }
- }
- });
- }
- else
- {
- maxIOSemaphore.acquireUninterruptibly();
-
- long sequence = nextWritingSequence.getAndIncrement();
-
- try
- {
- Native.write(this, handler, sequence, position, size, directByteBuffer, aioCallback);
- }
- catch (ActiveMQException e)
- {
- callbackError(aioCallback, sequence, directByteBuffer, e.getType().getCode(), e.getMessage());
- }
- catch (RuntimeException e)
- {
- callbackError(aioCallback, sequence, directByteBuffer, ActiveMQExceptionType.INTERNAL_ERROR.getCode(), e.getMessage());
- }
- }
-
- }
-
- public void read(final long position,
- final long size,
- final ByteBuffer directByteBuffer,
- final AIOCallback aioPackage) throws ActiveMQException
- {
- checkOpened();
- if (poller == null)
- {
- startPoller();
- }
- pendingWrites.countUp();
- maxIOSemaphore.acquireUninterruptibly();
- try
- {
- Native.read(this, handler, position, size, directByteBuffer, aioPackage);
- }
- catch (ActiveMQException e)
- {
- // Release only if an exception happened
- maxIOSemaphore.release();
- pendingWrites.countDown();
- throw e;
- }
- catch (RuntimeException e)
- {
- // Release only if an exception happened
- maxIOSemaphore.release();
- pendingWrites.countDown();
- throw e;
- }
- }
-
- public long size() throws ActiveMQException
- {
- checkOpened();
- return Native.size0(handler);
- }
-
- public void fill(final long position, final int blocks, final long size, final byte fillChar) throws ActiveMQException
- {
- checkOpened();
- try
- {
- Native.fill(handler, position, blocks, size, fillChar);
- }
- catch (ActiveMQException e)
- {
- fireExceptionListener(e.getType().getCode(), e.getMessage());
- throw e;
- }
- }
-
- public int getBlockSize()
- {
- return 512;
- }
-
- /**
- * This needs to be synchronized because of
- * http://bugs.sun.com/view_bug.do?bug_id=6791815
- * http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2009-January/000386.html
- */
- public static synchronized ByteBuffer newBuffer(final int size)
- {
- if (size % 512 != 0)
- {
- throw new RuntimeException("Buffer size needs to be aligned to 512");
- }
-
- return Native.newNativeBuffer(size);
- }
-
- public void setBufferCallback(final BufferCallback callback)
- {
- bufferCallback = callback;
- }
-
- /**
- * Return the JNI handler used on C++
- */
- public ByteBuffer getHandler()
- {
- return handler;
- }
-
- public static void clearBuffer(final ByteBuffer buffer)
- {
- Native.resetBuffer(buffer, buffer.limit());
- buffer.position(0);
- }
-
- // Protected -------------------------------------------------------------------------
-
- @Override
- protected void finalize()
- {
- if (opened)
- {
- ActiveMQJournalLogger.LOGGER.fileFinalizedWhileOpen(fileName);
- }
- }
-
- // Private ---------------------------------------------------------------------------
-
- private void callbackDone(final AIOCallback callback, final long sequence, final ByteBuffer buffer)
- {
- maxIOSemaphore.release();
-
- pendingWrites.countDown();
-
- callbackLock.lock();
-
- try
- {
-
- if (sequence == -1)
- {
- callback.done();
- }
- else
- {
- if (sequence == nextReadSequence)
- {
- nextReadSequence++;
- callback.done();
- flushCallbacks();
- }
- else
- {
- pendingCallbacks.add(new CallbackHolder(sequence, callback));
- }
- }
-
- // The buffer is not sent on callback for read operations
- if (bufferCallback != null && buffer != null)
- {
- bufferCallback.bufferDone(buffer);
- }
- }
- finally
- {
- callbackLock.unlock();
- }
- }
-
- private void flushCallbacks()
- {
- while (!pendingCallbacks.isEmpty() && pendingCallbacks.peek().sequence == nextReadSequence)
- {
- CallbackHolder holder = pendingCallbacks.poll();
- if (holder.isError())
- {
- ErrorCallback error = (ErrorCallback) holder;
- holder.callback.onError(error.errorCode, error.message);
- }
- else
- {
- holder.callback.done();
- }
- nextReadSequence++;
- }
- }
-
- // Called by the JNI layer.. just ignore the
- // warning
- private void callbackError(final AIOCallback callback,
- final long sequence,
- final ByteBuffer buffer,
- final int errorCode,
- final String errorMessage)
- {
- ActiveMQJournalLogger.LOGGER.callbackError(errorMessage);
-
- fireExceptionListener(errorCode, errorMessage);
-
- maxIOSemaphore.release();
-
- pendingWrites.countDown();
-
- callbackLock.lock();
-
- try
- {
- if (sequence == -1)
- {
- callback.onError(errorCode, errorMessage);
- }
- else
- {
- if (sequence == nextReadSequence)
- {
- nextReadSequence++;
- callback.onError(errorCode, errorMessage);
- flushCallbacks();
- }
- else
- {
- pendingCallbacks.add(new ErrorCallback(sequence, callback, errorCode, errorMessage));
- }
- }
- }
- finally
- {
- callbackLock.unlock();
- }
-
- // The buffer is not sent on callback for read operations
- if (bufferCallback != null && buffer != null)
- {
- bufferCallback.bufferDone(buffer);
- }
- }
-
- /**
- * This is called by the native layer
- *
- * @param errorCode
- * @param errorMessage
- */
- private void fireExceptionListener(final int errorCode, final String errorMessage)
- {
- ActiveMQJournalLogger.LOGGER.ioError(errorCode, errorMessage);
- if (ioExceptionListener != null)
- {
- ioExceptionListener.onIOException(ActiveMQExceptionType.getType(errorCode).createException(errorMessage), errorMessage);
- }
- }
-
- private void pollEvents()
- {
- if (!opened)
- {
- return;
- }
- Native.internalPollEvents(handler);
- }
-
- private void startPoller()
- {
- writeLock.lock();
-
- try
- {
-
- if (poller == null)
- {
- pollerLatch.countUp();
- poller = new PollerRunnable();
- try
- {
- pollerExecutor.execute(poller);
- }
- catch (Exception ex)
- {
- ActiveMQJournalLogger.LOGGER.errorStartingPoller(ex);
- }
- }
- }
- finally
- {
- writeLock.unlock();
- }
- }
-
- private void checkOpened()
- {
- if (!opened)
- {
- throw new RuntimeException("File is not opened");
- }
- }
-
- /**
- * @throws ActiveMQException
- * @throws InterruptedException
- */
- private void stopPoller() throws ActiveMQException, InterruptedException
- {
- Native.stopPoller(handler);
- // We need to make sure we won't call close until Poller is
- // completely done, or we might get beautiful GPFs
- pollerLatch.await();
- }
-
- public static FileLock lock(int handle)
- {
- if (Native.flock(handle))
- {
- return new ActiveMQFileLock(handle);
- }
- else
- {
- return null;
- }
- }
-
- // Native ----------------------------------------------------------------------------
-
-
- /**
- * Explicitly adding a compare to clause that returns 0 for at least the same object.
- * <br>
- * If {@link Comparable#compareTo(Object)} does not return 0 -for at least the same object- some
- * Collection classes methods will fail (example {@link PriorityQueue#remove(Object)}. If it
- * returns 0, then {@link #equals(Object)} must return {@code true} for the exact same cases,
- * otherwise we will get compatibility problems between Java5 and Java6.
- */
- private static class CallbackHolder implements Comparable<CallbackHolder>
- {
- final long sequence;
-
- final AIOCallback callback;
-
- public boolean isError()
- {
- return false;
- }
-
- public CallbackHolder(final long sequence, final AIOCallback callback)
- {
- this.sequence = sequence;
- this.callback = callback;
- }
-
- public int compareTo(final CallbackHolder o)
- {
- // It shouldn't be equals in any case
- if (this == o)
- return 0;
- if (sequence <= o.sequence)
- {
- return -1;
- }
- else
- {
- return 1;
- }
- }
-
- /**
- * See {@link CallbackHolder}.
- */
- @Override
- public int hashCode()
- {
- return super.hashCode();
- }
-
- /**
- * See {@link CallbackHolder}.
- */
- @Override
- public boolean equals(Object obj)
- {
- return super.equals(obj);
- }
- }
-
- private static final class ErrorCallback extends CallbackHolder
- {
- final int errorCode;
-
- final String message;
-
- @Override
- public boolean isError()
- {
- return true;
- }
-
- public ErrorCallback(final long sequence, final AIOCallback callback, final int errorCode, final String message)
- {
- super(sequence, callback);
-
- this.errorCode = errorCode;
-
- this.message = message;
- }
-
- /**
- * See {@link CallbackHolder}.
- */
- @Override
- public int hashCode()
- {
- return super.hashCode();
- }
-
- /**
- * See {@link CallbackHolder}.
- */
- @Override
- public boolean equals(Object obj)
- {
- return super.equals(obj);
- }
- }
-
- private class PollerRunnable implements Runnable
- {
- PollerRunnable()
- {
- }
-
- public void run()
- {
- try
- {
- pollEvents();
- }
- finally
- {
- // This gives us extra protection in cases of interruption
- // Case the poller thread is interrupted, this will allow us to
- // restart the thread when required
- poller = null;
- pollerLatch.countDown();
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFile.java
new file mode 100644
index 0000000..acc0732
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFile.java
@@ -0,0 +1,407 @@
+/*
+ * 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.core.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
+import org.apache.activemq.artemis.core.journal.EncodingSupport;
+import org.apache.activemq.artemis.core.journal.impl.SimpleWaitIOCallback;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
+import org.apache.activemq.artemis.core.io.buffer.TimedBufferObserver;
+import org.apache.activemq.artemis.journal.ActiveMQJournalBundle;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+
+public abstract class AbstractSequentialFile implements SequentialFile
+{
+
+ private File file;
+
+ protected final File directory;
+
+ protected final SequentialFileFactory factory;
+
+ protected long fileSize = 0;
+
+ protected final AtomicLong position = new AtomicLong(0);
+
+ protected TimedBuffer timedBuffer;
+
+ /**
+ * Instead of having AIOSequentialFile implementing the Observer, I have done it on an inner class.
+ * This is the class returned to the factory when the file is being activated.
+ */
+ protected final TimedBufferObserver timedBufferObserver = new LocalBufferObserver();
+
+ /**
+ * Used for asynchronous writes
+ */
+ protected final Executor writerExecutor;
+
+ /**
+ * @param file
+ * @param directory
+ */
+ public AbstractSequentialFile(final File directory,
+ final String file,
+ final SequentialFileFactory factory,
+ final Executor writerExecutor)
+ {
+ super();
+ this.file = new File(directory, file);
+ this.directory = directory;
+ this.factory = factory;
+ this.writerExecutor = writerExecutor;
+ }
+
+ // Public --------------------------------------------------------
+
+ public final boolean exists()
+ {
+ return file.exists();
+ }
+
+ public final String getFileName()
+ {
+ return file.getName();
+ }
+
+ public final void delete() throws IOException, InterruptedException, ActiveMQException
+ {
+ if (isOpen())
+ {
+ close();
+ }
+
+ if (file.exists() && !file.delete())
+ {
+ ActiveMQJournalLogger.LOGGER.errorDeletingFile(this);
+ }
+ }
+
+ public void copyTo(SequentialFile newFileName) throws Exception
+ {
+ try
+ {
+ ActiveMQJournalLogger.LOGGER.debug("Copying " + this + " as " + newFileName);
+ if (!newFileName.isOpen())
+ {
+ newFileName.open();
+ }
+
+ if (!isOpen())
+ {
+ this.open();
+ }
+
+
+ ByteBuffer buffer = ByteBuffer.allocate(10 * 1024);
+
+ for (;;)
+ {
+ buffer.rewind();
+ int size = this.read(buffer);
+ newFileName.writeDirect(buffer, false);
+ if (size < 10 * 1024)
+ {
+ break;
+ }
+ }
+ newFileName.close();
+ this.close();
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+ throw e;
+ }
+ }
+
+ /**
+ * @throws IOException only declare exception due to signature. Sub-class needs it.
+ */
+ @Override
+ public void position(final long pos) throws IOException
+ {
+ position.set(pos);
+ }
+
+ public long position()
+ {
+ return position.get();
+ }
+
+ public final void renameTo(final String newFileName) throws IOException, InterruptedException,
+ ActiveMQException
+ {
+ try
+ {
+ close();
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+ throw e;
+ }
+
+ File newFile = new File(directory + "/" + newFileName);
+
+ if (!file.equals(newFile))
+ {
+ if (!file.renameTo(newFile))
+ {
+ throw ActiveMQJournalBundle.BUNDLE.ioRenameFileError(file.getName(), newFileName);
+ }
+ file = newFile;
+ }
+ }
+
+ /**
+ * @throws IOException we declare throwing IOException because sub-classes need to do it
+ * @throws ActiveMQException
+ */
+ public synchronized void close() throws IOException, InterruptedException, ActiveMQException
+ {
+ final CountDownLatch donelatch = new CountDownLatch(1);
+
+ if (writerExecutor != null)
+ {
+ writerExecutor.execute(new Runnable()
+ {
+ public void run()
+ {
+ donelatch.countDown();
+ }
+ });
+
+ while (!donelatch.await(60, TimeUnit.SECONDS))
+ {
+ ActiveMQJournalLogger.LOGGER.couldNotCompleteTask(new Exception("trace"), file.getName());
+ }
+ }
+ }
+
+ public final boolean fits(final int size)
+ {
+ if (timedBuffer == null)
+ {
+ return position.get() + size <= fileSize;
+ }
+ else
+ {
+ return timedBuffer.checkSize(size);
+ }
+ }
+
+ public void setTimedBuffer(final TimedBuffer buffer)
+ {
+ if (timedBuffer != null)
+ {
+ timedBuffer.setObserver(null);
+ }
+
+ timedBuffer = buffer;
+
+ if (buffer != null)
+ {
+ buffer.setObserver(timedBufferObserver);
+ }
+
+ }
+
+ public void write(final ActiveMQBuffer bytes, final boolean sync, final IOCallback callback) throws IOException
+ {
+ if (timedBuffer != null)
+ {
+ bytes.setIndex(0, bytes.capacity());
+ timedBuffer.addBytes(bytes, sync, callback);
+ }
+ else
+ {
+ ByteBuffer buffer = factory.newBuffer(bytes.capacity());
+ buffer.put(bytes.toByteBuffer().array());
+ buffer.rewind();
+ writeDirect(buffer, sync, callback);
+ }
+ }
+
+ public void write(final ActiveMQBuffer bytes, final boolean sync) throws IOException, InterruptedException,
+ ActiveMQException
+ {
+ if (sync)
+ {
+ SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
+
+ write(bytes, true, completion);
+
+ completion.waitCompletion();
+ }
+ else
+ {
+ write(bytes, false, DummyCallback.getInstance());
+ }
+ }
+
+ public void write(final EncodingSupport bytes, final boolean sync, final IOCallback callback)
+ {
+ if (timedBuffer != null)
+ {
+ timedBuffer.addBytes(bytes, sync, callback);
+ }
+ else
+ {
+ ByteBuffer buffer = factory.newBuffer(bytes.getEncodeSize());
+
+ // If not using the TimedBuffer, a final copy is necessary
+ // Because AIO will need a specific Buffer
+ // And NIO will also need a whole buffer to perform the write
+
+ ActiveMQBuffer outBuffer = ActiveMQBuffers.wrappedBuffer(buffer);
+ bytes.encode(outBuffer);
+ buffer.rewind();
+ writeDirect(buffer, sync, callback);
+ }
+ }
+
+ public void write(final EncodingSupport bytes, final boolean sync) throws InterruptedException, ActiveMQException
+ {
+ if (sync)
+ {
+ SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
+
+ write(bytes, true, completion);
+
+ completion.waitCompletion();
+ }
+ else
+ {
+ write(bytes, false, DummyCallback.getInstance());
+ }
+ }
+
+ protected File getFile()
+ {
+ return file;
+ }
+
+ private static final class DelegateCallback implements IOCallback
+ {
+ final List<IOCallback> delegates;
+
+ private DelegateCallback(final List<IOCallback> delegates)
+ {
+ this.delegates = delegates;
+ }
+
+ public void done()
+ {
+ for (IOCallback callback : delegates)
+ {
+ try
+ {
+ callback.done();
+ }
+ catch (Throwable e)
+ {
+ ActiveMQJournalLogger.LOGGER.errorCompletingCallback(e);
+ }
+ }
+ }
+
+ public void onError(final int errorCode, final String errorMessage)
+ {
+ for (IOCallback callback : delegates)
+ {
+ try
+ {
+ callback.onError(errorCode, errorMessage);
+ }
+ catch (Throwable e)
+ {
+ ActiveMQJournalLogger.LOGGER.errorCallingErrorCallback(e);
+ }
+ }
+ }
+ }
+
+ protected ByteBuffer newBuffer(int size, int limit)
+ {
+ size = factory.calculateBlockSize(size);
+ limit = factory.calculateBlockSize(limit);
+
+ ByteBuffer buffer = factory.newBuffer(size);
+ buffer.limit(limit);
+ return buffer;
+ }
+
+ protected class LocalBufferObserver implements TimedBufferObserver
+ {
+ public void flushBuffer(final ByteBuffer buffer, final boolean requestedSync, final List<IOCallback> callbacks)
+ {
+ buffer.flip();
+
+ if (buffer.limit() == 0)
+ {
+ factory.releaseBuffer(buffer);
+ }
+ else
+ {
+ writeDirect(buffer, requestedSync, new DelegateCallback(callbacks));
+ }
+ }
+
+ public ByteBuffer newBuffer(final int size, final int limit)
+ {
+ return AbstractSequentialFile.this.newBuffer(size, limit);
+ }
+
+ public int getRemainingBytes()
+ {
+ if (fileSize - position.get() > Integer.MAX_VALUE)
+ {
+ return Integer.MAX_VALUE;
+ }
+ else
+ {
+ return (int)(fileSize - position.get());
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return "TimedBufferObserver on file (" + getFile().getName() + ")";
+ }
+
+ }
+
+ @Override
+ public File getJavaFile()
+ {
+ return getFile().getAbsoluteFile();
+ }
+}
[6/9] activemq-artemis git commit: ARTEMIS-163 First pass on the
native AIO refactoring
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java
index b85a845..d0140f1 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCompletion.java
@@ -16,7 +16,9 @@
*/
package org.apache.activemq.artemis.core.journal;
-public interface IOCompletion extends IOAsyncTask
+import org.apache.activemq.artemis.core.io.IOCallback;
+
+public interface IOCompletion extends IOCallback
{
void storeLineUp();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCriticalErrorListener.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCriticalErrorListener.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCriticalErrorListener.java
deleted file mode 100644
index fc0bbf9..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOCriticalErrorListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.core.journal;
-
-public interface IOCriticalErrorListener
-{
- void onIOException(Exception code, String message, SequentialFile file);
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java
index f3335b0..6b0beab 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/Journal.java
@@ -19,6 +19,7 @@ package org.apache.activemq.artemis.core.journal;
import java.util.List;
import java.util.Map;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.server.ActiveMQComponent;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFile.java
deleted file mode 100644
index 34e6d02..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFile.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.core.journal;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.journal.impl.TimedBuffer;
-
-public interface SequentialFile
-{
- /*
- * Creates the file if it doesn't already exist, then opens it
- */
- void open() throws Exception;
-
- boolean isOpen();
-
- boolean exists();
-
- /**
- * The maximum number of simultaneous writes accepted
- * @param maxIO
- * @throws Exception
- */
- void open(int maxIO, boolean useExecutor) throws Exception;
-
- boolean fits(int size);
-
- int getAlignment() throws Exception;
-
- int calculateBlockStart(int position) throws Exception;
-
- String getFileName();
-
- void fill(int position, int size, byte fillCharacter) throws Exception;
-
- void delete() throws IOException, InterruptedException, ActiveMQException;
-
- void write(ActiveMQBuffer bytes, boolean sync, IOAsyncTask callback) throws Exception;
-
- void write(ActiveMQBuffer bytes, boolean sync) throws Exception;
-
- void write(EncodingSupport bytes, boolean sync, IOAsyncTask callback) throws Exception;
-
- void write(EncodingSupport bytes, boolean sync) throws Exception;
-
- /**
- * Write directly to the file without using any buffer
- * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
- * NIO). To be safe, use a buffer from the corresponding
- * {@link SequentialFileFactory#newBuffer(int)}.
- */
- void writeDirect(ByteBuffer bytes, boolean sync, IOAsyncTask callback);
-
- /**
- * Write directly to the file without using any buffer
- * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
- * NIO). To be safe, use a buffer from the corresponding
- * {@link SequentialFileFactory#newBuffer(int)}.
- */
- void writeDirect(ByteBuffer bytes, boolean sync) throws Exception;
-
- /**
- * Write directly to the file. This is used by compacting and other places where we write a big
- * buffer in a single shot. writeInternal should always block until the entire write is sync on
- * disk.
- * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
- * NIO). To be safe, use a buffer from the corresponding
- * {@link SequentialFileFactory#newBuffer(int)}.
- */
- void writeInternal(ByteBuffer bytes) throws Exception;
-
- /**
- * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
- * NIO). To be safe, use a buffer from the corresponding
- * {@link SequentialFileFactory#newBuffer(int)}.
- */
- int read(ByteBuffer bytes, IOAsyncTask callback) throws Exception;
-
- /**
- * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
- * NIO). To be safe, use a buffer from the corresponding
- * {@link SequentialFileFactory#newBuffer(int)}.
- */
- int read(ByteBuffer bytes) throws Exception;
-
- void position(long pos) throws IOException;
-
- long position();
-
- void close() throws Exception;
-
- void waitForClose() throws Exception;
-
- void sync() throws IOException;
-
- long size() throws Exception;
-
- void renameTo(String newFileName) throws Exception;
-
- SequentialFile cloneFile();
-
- void copyTo(SequentialFile newFileName) throws Exception;
-
- void setTimedBuffer(TimedBuffer buffer);
-
- /**
- * Returns a native File of the file underlying this sequential file.
- */
- File getJavaFile();
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFileFactory.java
deleted file mode 100644
index cb47bd9..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/SequentialFileFactory.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.core.journal;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.util.List;
-
-/**
- *
- * A SequentialFileFactory
- */
-public interface SequentialFileFactory
-{
- SequentialFile createSequentialFile(String fileName, int maxIO);
-
- /**
- * Lists files that end with the given extension.
- * <p>
- * This method inserts a ".' before the extension.
- * @param extension
- * @return
- * @throws Exception
- */
- List<String> listFiles(String extension) throws Exception;
-
- boolean isSupportsCallbacks();
-
- /** The SequentialFile will call this method when a disk IO Error happens during the live phase. */
- void onIOError(Exception exception, String message, SequentialFile file);
-
- /** used for cases where you need direct buffer outside of the journal context.
- * This is because the native layer has a method that can be reused in certain cases like paging */
- ByteBuffer allocateDirectBuffer(int size);
-
- /** used for cases where you need direct buffer outside of the journal context.
- * This is because the native layer has a method that can be reused in certain cases like paging */
- void releaseDirectBuffer(ByteBuffer buffer);
-
- /**
- * Note: You need to release the buffer if is used for reading operations. You don't need to do
- * it if using writing operations (AIO Buffer Lister will take of writing operations)
- * @param size
- * @return the allocated ByteBuffer
- */
- ByteBuffer newBuffer(int size);
-
- void releaseBuffer(ByteBuffer buffer);
-
- void activateBuffer(SequentialFile file);
-
- void deactivateBuffer();
-
- // To be used in tests only
- ByteBuffer wrapBuffer(byte[] bytes);
-
- int getAlignment();
-
- int calculateBlockSize(int bytes);
-
- File getDirectory();
-
- void clearBuffer(ByteBuffer buffer);
-
- void start();
-
- void stop();
-
- /**
- * Creates the directory if it does not exist yet.
- */
- void createDirs() throws Exception;
-
- void flush();
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFile.java
deleted file mode 100644
index acef8a5..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFile.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.concurrent.Executor;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.asyncio.AsynchronousFile;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
-import org.apache.activemq.artemis.core.asyncio.IOExceptionListener;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-
-public class AIOSequentialFile extends AbstractSequentialFile implements IOExceptionListener
-{
- private boolean opened = false;
-
- private final int maxIO;
-
- private AsynchronousFile aioFile;
-
- private final BufferCallback bufferCallback;
-
- /** The pool for Thread pollers */
- private final Executor pollerExecutor;
-
- public AIOSequentialFile(final SequentialFileFactory factory,
- final int bufferSize,
- final long bufferTimeoutMilliseconds,
- final File directory,
- final String fileName,
- final int maxIO,
- final BufferCallback bufferCallback,
- final Executor writerExecutor,
- final Executor pollerExecutor)
- {
- super(directory, fileName, factory, writerExecutor);
- this.maxIO = maxIO;
- this.bufferCallback = bufferCallback;
- this.pollerExecutor = pollerExecutor;
- }
-
- public boolean isOpen()
- {
- return opened;
- }
-
- public int getAlignment()
- {
- checkOpened();
-
- return aioFile.getBlockSize();
- }
-
- public int calculateBlockStart(final int position)
- {
- int alignment = getAlignment();
-
- int pos = (position / alignment + (position % alignment != 0 ? 1 : 0)) * alignment;
-
- return pos;
- }
-
- public SequentialFile cloneFile()
- {
- return new AIOSequentialFile(factory,
- -1,
- -1,
- getFile().getParentFile(),
- getFile().getName(),
- maxIO,
- bufferCallback,
- writerExecutor,
- pollerExecutor);
- }
-
- @Override
- public synchronized void close() throws IOException, InterruptedException, ActiveMQException
- {
- if (!opened)
- {
- return;
- }
-
- super.close();
-
- opened = false;
-
- timedBuffer = null;
-
- aioFile.close();
- aioFile = null;
-
- notifyAll();
- }
-
- @Override
- public synchronized void waitForClose() throws Exception
- {
- while (isOpen())
- {
- wait();
- }
- }
-
- public void fill(final int position, final int size, final byte fillCharacter) throws Exception
- {
- checkOpened();
-
- int fileblockSize = aioFile.getBlockSize();
-
- int blockSize = fileblockSize;
-
- if (size % (100 * 1024 * 1024) == 0)
- {
- blockSize = 100 * 1024 * 1024;
- }
- else if (size % (10 * 1024 * 1024) == 0)
- {
- blockSize = 10 * 1024 * 1024;
- }
- else if (size % (1024 * 1024) == 0)
- {
- blockSize = 1024 * 1024;
- }
- else if (size % (10 * 1024) == 0)
- {
- blockSize = 10 * 1024;
- }
- else
- {
- blockSize = fileblockSize;
- }
-
- int blocks = size / blockSize;
-
- if (size % blockSize != 0)
- {
- blocks++;
- }
-
- int filePosition = position;
-
- if (position % fileblockSize != 0)
- {
- filePosition = (position / fileblockSize + 1) * fileblockSize;
- }
-
- aioFile.fill(filePosition, blocks, blockSize, fillCharacter);
-
- fileSize = aioFile.size();
- }
-
- public void open() throws Exception
- {
- open(maxIO, true);
- }
-
- public synchronized void open(final int maxIO, final boolean useExecutor) throws ActiveMQException
- {
- opened = true;
-
- aioFile = new AsynchronousFileImpl(useExecutor ? writerExecutor : null, pollerExecutor, this);
-
- try
- {
- aioFile.open(getFile().getAbsolutePath(), maxIO);
- }
- catch (ActiveMQException e)
- {
- factory.onIOError(e, e.getMessage(), this);
- throw e;
- }
-
- position.set(0);
-
- aioFile.setBufferCallback(bufferCallback);
-
- fileSize = aioFile.size();
- }
-
- public void setBufferCallback(final BufferCallback callback)
- {
- aioFile.setBufferCallback(callback);
- }
-
- public int read(final ByteBuffer bytes, final IOAsyncTask callback) throws ActiveMQException
- {
- int bytesToRead = bytes.limit();
-
- long positionToRead = position.getAndAdd(bytesToRead);
-
- bytes.rewind();
-
- aioFile.read(positionToRead, bytesToRead, bytes, callback);
-
- return bytesToRead;
- }
-
- public int read(final ByteBuffer bytes) throws Exception
- {
- SimpleWaitIOCallback waitCompletion = new SimpleWaitIOCallback();
-
- int bytesRead = read(bytes, waitCompletion);
-
- waitCompletion.waitCompletion();
-
- return bytesRead;
- }
-
- public void sync()
- {
- throw new UnsupportedOperationException("This method is not supported on AIO");
- }
-
- public long size() throws Exception
- {
- if (aioFile == null)
- {
- return getFile().length();
- }
- else
- {
- return aioFile.size();
- }
- }
-
- @Override
- public String toString()
- {
- return "AIOSequentialFile:" + getFile().getAbsolutePath();
- }
-
- // Public methods
- // -----------------------------------------------------------------------------------------------------
-
- @Override
- public void onIOException(Exception code, String message)
- {
- factory.onIOError(code, message, this);
- }
-
-
- public void writeDirect(final ByteBuffer bytes, final boolean sync) throws Exception
- {
- if (sync)
- {
- SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
-
- writeDirect(bytes, true, completion);
-
- completion.waitCompletion();
- }
- else
- {
- writeDirect(bytes, false, DummyCallback.getInstance());
- }
- }
-
- /**
- *
- * @param sync Not used on AIO
- * */
- public void writeDirect(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback)
- {
- final int bytesToWrite = factory.calculateBlockSize(bytes.limit());
-
- final long positionToWrite = position.getAndAdd(bytesToWrite);
-
- aioFile.write(positionToWrite, bytesToWrite, bytes, callback);
- }
-
- public void writeInternal(final ByteBuffer bytes) throws ActiveMQException
- {
- final int bytesToWrite = factory.calculateBlockSize(bytes.limit());
-
- final long positionToWrite = position.getAndAdd(bytesToWrite);
-
- aioFile.writeInternal(positionToWrite, bytesToWrite, bytes);
- }
-
- // Protected methods
- // -----------------------------------------------------------------------------------------------------
-
- @Override
- protected ByteBuffer newBuffer(int size, int limit)
- {
- size = factory.calculateBlockSize(size);
- limit = factory.calculateBlockSize(limit);
-
- ByteBuffer buffer = factory.newBuffer(size);
- buffer.limit(limit);
- return buffer;
- }
-
- // Private methods
- // -----------------------------------------------------------------------------------------------------
-
- private void checkOpened()
- {
- if (aioFile == null || !opened)
- {
- throw new IllegalStateException("File not opened");
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFileFactory.java
deleted file mode 100644
index 65e6a6f..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AIOSequentialFileFactory.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
-import org.apache.activemq.artemis.core.asyncio.BufferCallback;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.libaio.Native;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-
-public final class AIOSequentialFileFactory extends AbstractSequentialFileFactory
-{
- private static final boolean trace = ActiveMQJournalLogger.LOGGER.isTraceEnabled();
-
- private final ReuseBuffersController buffersControl = new ReuseBuffersController();
-
- private ExecutorService pollerExecutor;
-
- // This method exists just to make debug easier.
- // I could replace log.trace by log.info temporarily while I was debugging
- // Journal
- private static void trace(final String message)
- {
- ActiveMQJournalLogger.LOGGER.trace(message);
- }
-
- public AIOSequentialFileFactory(final File journalDir)
- {
- this(journalDir,
- JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
- JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
- false,
- null);
- }
-
- public AIOSequentialFileFactory(final File journalDir, final IOCriticalErrorListener listener)
- {
- this(journalDir,
- JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
- JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
- false,
- listener);
- }
-
- public AIOSequentialFileFactory(final File journalDir,
- final int bufferSize,
- final int bufferTimeout,
- final boolean logRates)
- {
- this(journalDir, bufferSize, bufferTimeout, logRates, null);
- }
-
- public AIOSequentialFileFactory(final File journalDir,
- final int bufferSize,
- final int bufferTimeout,
- final boolean logRates,
- final IOCriticalErrorListener listener)
- {
- super(journalDir, true, bufferSize, bufferTimeout, logRates, listener);
- }
-
- public SequentialFile createSequentialFile(final String fileName, final int maxIO)
- {
- return new AIOSequentialFile(this,
- bufferSize,
- bufferTimeout,
- journalDir,
- fileName,
- maxIO,
- buffersControl.callback,
- writeExecutor,
- pollerExecutor);
- }
-
- public boolean isSupportsCallbacks()
- {
- return true;
- }
-
- public static boolean isSupported()
- {
- return AsynchronousFileImpl.isLoaded();
- }
-
- public ByteBuffer allocateDirectBuffer(final int size)
- {
-
- int blocks = size / 512;
- if (size % 512 != 0)
- {
- blocks++;
- }
-
- // The buffer on AIO has to be a multiple of 512
- ByteBuffer buffer = AsynchronousFileImpl.newBuffer(blocks * 512);
-
- buffer.limit(size);
-
- return buffer;
- }
-
- public void releaseDirectBuffer(final ByteBuffer buffer)
- {
- Native.destroyBuffer(buffer);
- }
-
- public ByteBuffer newBuffer(int size)
- {
- if (size % 512 != 0)
- {
- size = (size / 512 + 1) * 512;
- }
-
- return buffersControl.newBuffer(size);
- }
-
- public void clearBuffer(final ByteBuffer directByteBuffer)
- {
- AsynchronousFileImpl.clearBuffer(directByteBuffer);
- }
-
- public int getAlignment()
- {
- return 512;
- }
-
- // For tests only
- public ByteBuffer wrapBuffer(final byte[] bytes)
- {
- ByteBuffer newbuffer = newBuffer(bytes.length);
- newbuffer.put(bytes);
- return newbuffer;
- }
-
- public int calculateBlockSize(final int position)
- {
- int alignment = getAlignment();
-
- int pos = (position / alignment + (position % alignment != 0 ? 1 : 0)) * alignment;
-
- return pos;
- }
-
- /* (non-Javadoc)
- * @see org.apache.activemq.artemis.core.journal.SequentialFileFactory#releaseBuffer(java.nio.ByteBuffer)
- */
- @Override
- public synchronized void releaseBuffer(final ByteBuffer buffer)
- {
- Native.destroyBuffer(buffer);
- }
-
- @Override
- public void start()
- {
- super.start();
-
- pollerExecutor = Executors.newCachedThreadPool(new ActiveMQThreadFactory("ActiveMQ-AIO-poller-pool" + System.identityHashCode(this),
- true,
- AIOSequentialFileFactory.getThisClassLoader()));
-
- }
-
- @Override
- public void stop()
- {
- buffersControl.stop();
-
- if (pollerExecutor != null)
- {
- pollerExecutor.shutdown();
-
- try
- {
- if (!pollerExecutor.awaitTermination(AbstractSequentialFileFactory.EXECUTOR_TIMEOUT, TimeUnit.SECONDS))
- {
- ActiveMQJournalLogger.LOGGER.timeoutOnPollerShutdown(new Exception("trace"));
- }
- }
- catch (InterruptedException e)
- {
- throw new ActiveMQInterruptedException(e);
- }
- }
-
- super.stop();
- }
-
- @Override
- protected void finalize()
- {
- stop();
- }
-
- /**
- * Class that will control buffer-reuse
- */
- private class ReuseBuffersController
- {
- private volatile long bufferReuseLastTime = System.currentTimeMillis();
-
- /**
- * This queue is fed by {@link org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory.ReuseBuffersController.LocalBufferCallback}
- * which is called directly by NIO or NIO. On the case of the AIO this is almost called by the native layer as
- * soon as the buffer is not being used any more and ready to be reused or GCed
- */
- private final ConcurrentLinkedQueue<ByteBuffer> reuseBuffersQueue = new ConcurrentLinkedQueue<ByteBuffer>();
-
- private boolean stopped = false;
-
- final BufferCallback callback = new LocalBufferCallback();
-
- public ByteBuffer newBuffer(final int size)
- {
- // if a new buffer wasn't requested in 10 seconds, we clear the queue
- // This is being done this way as we don't need another Timeout Thread
- // just to cleanup this
- if (bufferSize > 0 && System.currentTimeMillis() - bufferReuseLastTime > 10000)
- {
- if (AIOSequentialFileFactory.trace)
- {
- AIOSequentialFileFactory.trace("Clearing reuse buffers queue with " + reuseBuffersQueue.size() +
- " elements");
- }
-
- bufferReuseLastTime = System.currentTimeMillis();
-
- clearPoll();
- }
-
- // if a buffer is bigger than the configured-bufferSize, we just create a new
- // buffer.
- if (size > bufferSize)
- {
- return AsynchronousFileImpl.newBuffer(size);
- }
- else
- {
- // We need to allocate buffers following the rules of the storage
- // being used (AIO/NIO)
- int alignedSize = calculateBlockSize(size);
-
- // Try getting a buffer from the queue...
- ByteBuffer buffer = reuseBuffersQueue.poll();
-
- if (buffer == null)
- {
- // if empty create a new one.
- buffer = AsynchronousFileImpl.newBuffer(bufferSize);
-
- buffer.limit(alignedSize);
- }
- else
- {
- clearBuffer(buffer);
-
- // set the limit of the buffer to the bufferSize being required
- buffer.limit(alignedSize);
- }
-
- buffer.rewind();
-
- return buffer;
- }
- }
-
- public synchronized void stop()
- {
- stopped = true;
- clearPoll();
- }
-
- public synchronized void clearPoll()
- {
- ByteBuffer reusedBuffer;
-
- while ((reusedBuffer = reuseBuffersQueue.poll()) != null)
- {
- releaseBuffer(reusedBuffer);
- }
- }
-
- private class LocalBufferCallback implements BufferCallback
- {
- public void bufferDone(final ByteBuffer buffer)
- {
- synchronized (ReuseBuffersController.this)
- {
-
- if (stopped)
- {
- releaseBuffer(buffer);
- }
- else
- {
- bufferReuseLastTime = System.currentTimeMillis();
-
- // If a buffer has any other than the configured bufferSize, the buffer
- // will be just sent to GC
- if (buffer.capacity() == bufferSize)
- {
- reuseBuffersQueue.offer(buffer);
- }
- else
- {
- releaseBuffer(buffer);
- }
- }
- }
- }
- }
- }
-
- private static ClassLoader getThisClassLoader()
- {
- return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
- {
- public ClassLoader run()
- {
- return AIOSequentialFileFactory.class.getClassLoader();
- }
- });
-
- }
-
- @Override
- public String toString()
- {
- return AIOSequentialFileFactory.class.getSimpleName() + "(buffersControl.stopped=" + buffersControl.stopped +
- "):" + super.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java
index e21b046..b36a0c4 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractJournalUpdateTask.java
@@ -24,8 +24,8 @@ import java.util.Set;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.Pair;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecord;
import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalInternalRecord;
@@ -87,7 +87,7 @@ public abstract class AbstractJournalUpdateTask implements JournalReaderCallback
final List<Pair<String, String>> renames) throws Exception
{
- SequentialFile controlFile = fileFactory.createSequentialFile(AbstractJournalUpdateTask.FILE_COMPACT_CONTROL, 1);
+ SequentialFile controlFile = fileFactory.createSequentialFile(AbstractJournalUpdateTask.FILE_COMPACT_CONTROL);
try
{
@@ -182,7 +182,7 @@ public abstract class AbstractJournalUpdateTask implements JournalReaderCallback
// To Fix the size of the file
writingChannel.writerIndex(writingChannel.capacity());
- sequentialFile.writeInternal(writingChannel.toByteBuffer());
+ sequentialFile.writeDirect(writingChannel.toByteBuffer(), true);
sequentialFile.close();
newDataFiles.add(currentFile);
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFile.java
deleted file mode 100644
index a4eed58..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFile.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
-import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.journal.ActiveMQJournalBundle;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-public abstract class AbstractSequentialFile implements SequentialFile
-{
-
- private File file;
-
- protected final File directory;
-
- protected final SequentialFileFactory factory;
-
- protected long fileSize = 0;
-
- protected final AtomicLong position = new AtomicLong(0);
-
- protected TimedBuffer timedBuffer;
-
- /**
- * Instead of having AIOSequentialFile implementing the Observer, I have done it on an inner class.
- * This is the class returned to the factory when the file is being activated.
- */
- protected final TimedBufferObserver timedBufferObserver = new LocalBufferObserver();
-
- /**
- * Used for asynchronous writes
- */
- protected final Executor writerExecutor;
-
- /**
- * @param file
- * @param directory
- */
- public AbstractSequentialFile(final File directory,
- final String file,
- final SequentialFileFactory factory,
- final Executor writerExecutor)
- {
- super();
- this.file = new File(directory, file);
- this.directory = directory;
- this.factory = factory;
- this.writerExecutor = writerExecutor;
- }
-
- // Public --------------------------------------------------------
-
- public final boolean exists()
- {
- return file.exists();
- }
-
- public final String getFileName()
- {
- return file.getName();
- }
-
- public final void delete() throws IOException, InterruptedException, ActiveMQException
- {
- if (isOpen())
- {
- close();
- }
-
- if (file.exists() && !file.delete())
- {
- ActiveMQJournalLogger.LOGGER.errorDeletingFile(this);
- }
- }
-
- public void copyTo(SequentialFile newFileName) throws Exception
- {
- try
- {
- ActiveMQJournalLogger.LOGGER.debug("Copying " + this + " as " + newFileName);
- if (!newFileName.isOpen())
- {
- newFileName.open();
- }
-
- if (!isOpen())
- {
- this.open();
- }
-
-
- ByteBuffer buffer = ByteBuffer.allocate(10 * 1024);
-
- for (;;)
- {
- buffer.rewind();
- int size = this.read(buffer);
- newFileName.writeDirect(buffer, false);
- if (size < 10 * 1024)
- {
- break;
- }
- }
- newFileName.close();
- this.close();
- }
- catch (IOException e)
- {
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
- throw e;
- }
- }
-
- /**
- * @throws IOException only declare exception due to signature. Sub-class needs it.
- */
- @Override
- public void position(final long pos) throws IOException
- {
- position.set(pos);
- }
-
- public long position()
- {
- return position.get();
- }
-
- public final void renameTo(final String newFileName) throws IOException, InterruptedException,
- ActiveMQException
- {
- try
- {
- close();
- }
- catch (IOException e)
- {
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
- throw e;
- }
-
- File newFile = new File(directory + "/" + newFileName);
-
- if (!file.equals(newFile))
- {
- if (!file.renameTo(newFile))
- {
- throw ActiveMQJournalBundle.BUNDLE.ioRenameFileError(file.getName(), newFileName);
- }
- file = newFile;
- }
- }
-
- /**
- * @throws IOException we declare throwing IOException because sub-classes need to do it
- * @throws ActiveMQException
- */
- public synchronized void close() throws IOException, InterruptedException, ActiveMQException
- {
- final CountDownLatch donelatch = new CountDownLatch(1);
-
- if (writerExecutor != null)
- {
- writerExecutor.execute(new Runnable()
- {
- public void run()
- {
- donelatch.countDown();
- }
- });
-
- while (!donelatch.await(60, TimeUnit.SECONDS))
- {
- ActiveMQJournalLogger.LOGGER.couldNotCompleteTask(new Exception("trace"), file.getName());
- }
- }
- }
-
- public final boolean fits(final int size)
- {
- if (timedBuffer == null)
- {
- return position.get() + size <= fileSize;
- }
- else
- {
- return timedBuffer.checkSize(size);
- }
- }
-
- public void setTimedBuffer(final TimedBuffer buffer)
- {
- if (timedBuffer != null)
- {
- timedBuffer.setObserver(null);
- }
-
- timedBuffer = buffer;
-
- if (buffer != null)
- {
- buffer.setObserver(timedBufferObserver);
- }
-
- }
-
- public void write(final ActiveMQBuffer bytes, final boolean sync, final IOAsyncTask callback) throws IOException
- {
- if (timedBuffer != null)
- {
- bytes.setIndex(0, bytes.capacity());
- timedBuffer.addBytes(bytes, sync, callback);
- }
- else
- {
- ByteBuffer buffer = factory.newBuffer(bytes.capacity());
- buffer.put(bytes.toByteBuffer().array());
- buffer.rewind();
- writeDirect(buffer, sync, callback);
- }
- }
-
- public void write(final ActiveMQBuffer bytes, final boolean sync) throws IOException, InterruptedException,
- ActiveMQException
- {
- if (sync)
- {
- SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
-
- write(bytes, true, completion);
-
- completion.waitCompletion();
- }
- else
- {
- write(bytes, false, DummyCallback.getInstance());
- }
- }
-
- public void write(final EncodingSupport bytes, final boolean sync, final IOAsyncTask callback)
- {
- if (timedBuffer != null)
- {
- timedBuffer.addBytes(bytes, sync, callback);
- }
- else
- {
- ByteBuffer buffer = factory.newBuffer(bytes.getEncodeSize());
-
- // If not using the TimedBuffer, a final copy is necessary
- // Because AIO will need a specific Buffer
- // And NIO will also need a whole buffer to perform the write
-
- ActiveMQBuffer outBuffer = ActiveMQBuffers.wrappedBuffer(buffer);
- bytes.encode(outBuffer);
- buffer.rewind();
- writeDirect(buffer, sync, callback);
- }
- }
-
- public void write(final EncodingSupport bytes, final boolean sync) throws InterruptedException, ActiveMQException
- {
- if (sync)
- {
- SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
-
- write(bytes, true, completion);
-
- completion.waitCompletion();
- }
- else
- {
- write(bytes, false, DummyCallback.getInstance());
- }
- }
-
- protected File getFile()
- {
- return file;
- }
-
- private static final class DelegateCallback implements IOAsyncTask
- {
- final List<IOAsyncTask> delegates;
-
- private DelegateCallback(final List<IOAsyncTask> delegates)
- {
- this.delegates = delegates;
- }
-
- public void done()
- {
- for (IOAsyncTask callback : delegates)
- {
- try
- {
- callback.done();
- }
- catch (Throwable e)
- {
- ActiveMQJournalLogger.LOGGER.errorCompletingCallback(e);
- }
- }
- }
-
- public void onError(final int errorCode, final String errorMessage)
- {
- for (IOAsyncTask callback : delegates)
- {
- try
- {
- callback.onError(errorCode, errorMessage);
- }
- catch (Throwable e)
- {
- ActiveMQJournalLogger.LOGGER.errorCallingErrorCallback(e);
- }
- }
- }
- }
-
- protected ByteBuffer newBuffer(int size, int limit)
- {
- size = factory.calculateBlockSize(size);
- limit = factory.calculateBlockSize(limit);
-
- ByteBuffer buffer = factory.newBuffer(size);
- buffer.limit(limit);
- return buffer;
- }
-
- protected class LocalBufferObserver implements TimedBufferObserver
- {
- public void flushBuffer(final ByteBuffer buffer, final boolean requestedSync, final List<IOAsyncTask> callbacks)
- {
- buffer.flip();
-
- if (buffer.limit() == 0)
- {
- factory.releaseBuffer(buffer);
- }
- else
- {
- writeDirect(buffer, requestedSync, new DelegateCallback(callbacks));
- }
- }
-
- public ByteBuffer newBuffer(final int size, final int limit)
- {
- return AbstractSequentialFile.this.newBuffer(size, limit);
- }
-
- public int getRemainingBytes()
- {
- if (fileSize - position.get() > Integer.MAX_VALUE)
- {
- return Integer.MAX_VALUE;
- }
- else
- {
- return (int)(fileSize - position.get());
- }
- }
-
- @Override
- public String toString()
- {
- return "TimedBufferObserver on file (" + getFile().getName() + ")";
- }
-
- }
-
- @Override
- public File getJavaFile()
- {
- return getFile().getAbsoluteFile();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFileFactory.java
deleted file mode 100644
index ec0ab4d..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/AbstractSequentialFileFactory.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-
-/**
- * An abstract SequentialFileFactory containing basic functionality for both AIO and NIO SequentialFactories
- */
-abstract class AbstractSequentialFileFactory implements SequentialFileFactory
-{
-
- // Timeout used to wait executors to shutdown
- protected static final int EXECUTOR_TIMEOUT = 60;
-
- protected final File journalDir;
-
- protected final TimedBuffer timedBuffer;
-
- protected final int bufferSize;
-
- protected final long bufferTimeout;
-
- private final IOCriticalErrorListener critialErrorListener;
-
- /**
- * Asynchronous writes need to be done at another executor.
- * This needs to be done at NIO, or else we would have the callers thread blocking for the return.
- * At AIO this is necessary as context switches on writes would fire flushes at the kernel.
- * */
- protected ExecutorService writeExecutor;
-
- AbstractSequentialFileFactory(final File journalDir,
- final boolean buffered,
- final int bufferSize,
- final int bufferTimeout,
- final boolean logRates,
- final IOCriticalErrorListener criticalErrorListener)
- {
- this.journalDir = journalDir;
-
- if (buffered)
- {
- timedBuffer = new TimedBuffer(bufferSize, bufferTimeout, logRates);
- }
- else
- {
- timedBuffer = null;
- }
- this.bufferSize = bufferSize;
- this.bufferTimeout = bufferTimeout;
- this.critialErrorListener = criticalErrorListener;
- }
-
- public void stop()
- {
- if (timedBuffer != null)
- {
- timedBuffer.stop();
- }
-
- if (isSupportsCallbacks() && writeExecutor != null)
- {
- writeExecutor.shutdown();
-
- try
- {
- if (!writeExecutor.awaitTermination(AbstractSequentialFileFactory.EXECUTOR_TIMEOUT, TimeUnit.SECONDS))
- {
- ActiveMQJournalLogger.LOGGER.timeoutOnWriterShutdown(new Exception("trace"));
- }
- }
- catch (InterruptedException e)
- {
- throw new ActiveMQInterruptedException(e);
- }
- }
- }
-
- @Override
- public File getDirectory()
- {
- return journalDir;
- }
-
- public void start()
- {
- if (timedBuffer != null)
- {
- timedBuffer.start();
- }
-
- if (isSupportsCallbacks())
- {
- writeExecutor = Executors.newSingleThreadExecutor(new ActiveMQThreadFactory("ActiveMQ-Asynchronous-Persistent-Writes" + System.identityHashCode(this),
- true,
- AbstractSequentialFileFactory.getThisClassLoader()));
- }
-
- }
-
- @Override
- public void onIOError(Exception exception, String message, SequentialFile file)
- {
- if (critialErrorListener != null)
- {
- critialErrorListener.onIOException(exception, message, file);
- }
- }
-
- @Override
- public void activateBuffer(final SequentialFile file)
- {
- if (timedBuffer != null)
- {
- file.setTimedBuffer(timedBuffer);
- }
- }
-
- public void flush()
- {
- if (timedBuffer != null)
- {
- timedBuffer.flush();
- }
- }
-
- public void deactivateBuffer()
- {
- if (timedBuffer != null)
- {
- // When moving to a new file, we need to make sure any pending buffer will be transferred to the buffer
- timedBuffer.flush();
- timedBuffer.setObserver(null);
- }
- }
-
- public void releaseBuffer(final ByteBuffer buffer)
- {
- }
-
- /**
- * Create the directory if it doesn't exist yet
- */
- public void createDirs() throws Exception
- {
- boolean ok = journalDir.mkdirs();
- if (!ok)
- {
- throw new IOException("Failed to create directory " + journalDir);
- }
- }
-
- public List<String> listFiles(final String extension) throws Exception
- {
- FilenameFilter fnf = new FilenameFilter()
- {
- public boolean accept(final File file, final String name)
- {
- return name.endsWith("." + extension);
- }
- };
-
- String[] fileNames = journalDir.list(fnf);
-
- if (fileNames == null)
- {
- return Collections.EMPTY_LIST;
- }
-
- return Arrays.asList(fileNames);
- }
-
- private static ClassLoader getThisClassLoader()
- {
- return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
- {
- public ClassLoader run()
- {
- return AbstractSequentialFileFactory.class.getClassLoader();
- }
- });
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/DummyCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/DummyCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/DummyCallback.java
deleted file mode 100644
index 9c4c3d6..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/DummyCallback.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-class DummyCallback extends SyncIOCompletion
-{
- private static final DummyCallback instance = new DummyCallback();
-
- public static DummyCallback getInstance()
- {
- return DummyCallback.instance;
- }
-
- public void done()
- {
- }
-
- public void onError(final int errorCode, final String errorMessage)
- {
- ActiveMQJournalLogger.LOGGER.errorWritingData(new Exception(errorMessage), errorMessage, errorCode);
- }
-
- @Override
- public void waitCompletion() throws Exception
- {
- }
-
- @Override
- public void storeLineUp()
- {
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java
index a41e72f..5a0f11f 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/FileWrapperJournal.java
@@ -32,7 +32,7 @@ import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
import org.apache.activemq.artemis.core.journal.LoaderCallback;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecord;
import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecordTX;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java
index d6a856a..1ba8f0b 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalBase.java
@@ -17,6 +17,7 @@
package org.apache.activemq.artemis.core.journal.impl;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.core.io.DummyCallback;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
import org.apache.activemq.artemis.core.journal.IOCompletion;
import org.apache.activemq.artemis.core.journal.Journal;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java
index 5b0a1b8..1f657a2 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalCompactor.java
@@ -28,8 +28,8 @@ import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecord;
import org.apache.activemq.artemis.core.journal.impl.dataformat.JournalAddRecordTX;
@@ -64,7 +64,7 @@ public class JournalCompactor extends AbstractJournalUpdateTask implements Journ
final List<String> newFiles,
final List<Pair<String, String>> renameFile) throws Exception
{
- SequentialFile controlFile = fileFactory.createSequentialFile(AbstractJournalUpdateTask.FILE_COMPACT_CONTROL, 1);
+ SequentialFile controlFile = fileFactory.createSequentialFile(AbstractJournalUpdateTask.FILE_COMPACT_CONTROL);
if (controlFile.exists())
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java
index e3b1624..dcfc1a2 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFile.java
@@ -16,7 +16,7 @@
*/
package org.apache.activemq.artemis.core.journal.impl;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
public interface JournalFile
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java
index 4438a96..7e96575 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFileImpl.java
@@ -21,7 +21,7 @@ import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
public class JournalFileImpl implements JournalFile
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java
index 052dc25..268a23d 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalFilesRepository.java
@@ -31,8 +31,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
/**
@@ -662,13 +662,13 @@ public class JournalFilesRepository
String tmpFileName = fileName + ".tmp";
- SequentialFile sequentialFile = fileFactory.createSequentialFile(tmpFileName, maxAIO);
+ SequentialFile sequentialFile = fileFactory.createSequentialFile(tmpFileName);
sequentialFile.open(1, false);
if (init)
{
- sequentialFile.fill(0, fileSize, JournalImpl.FILL_CHARACTER);
+ sequentialFile.fill(fileSize);
JournalImpl.initFileHeader(fileFactory, sequentialFile, userVersion, fileID);
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java
index 6f411eb..068e697 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/JournalImpl.java
@@ -46,15 +46,15 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.journal.IOCompletion;
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
import org.apache.activemq.artemis.core.journal.LoaderCallback;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.TestableJournal;
import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
@@ -293,7 +293,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
final CountDownLatch latch = new CountDownLatch(numIts * 2);
- class MyIOAsyncTask implements IOCompletion
+ class MyAIOCallback implements IOCompletion
{
public void done()
{
@@ -310,7 +310,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
}
}
- final MyIOAsyncTask task = new MyIOAsyncTask();
+ final MyAIOCallback task = new MyAIOCallback();
final int recordSize = 1024;
@@ -373,11 +373,11 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
for (String fileName : fileNames)
{
- SequentialFile file = fileFactory.createSequentialFile(fileName, filesRepository.getMaxAIO());
+ SequentialFile file = fileFactory.createSequentialFile(fileName);
if (file.size() >= SIZE_HEADER)
{
- file.open(1, false);
+ file.open();
try
{
@@ -2776,11 +2776,11 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
final boolean completeTransaction,
final boolean sync,
final JournalTransaction tx,
- final IOAsyncTask parameterCallback) throws Exception
+ final IOCallback parameterCallback) throws Exception
{
checkJournalIsLoaded();
- final IOAsyncTask callback;
+ final IOCallback callback;
final int size = encoder.getEncodeSize();
@@ -2896,7 +2896,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
{
for (String dataFile : dataFiles)
{
- SequentialFile file = fileFactory.createSequentialFile(dataFile, 1);
+ SequentialFile file = fileFactory.createSequentialFile(dataFile);
if (file.exists())
{
file.delete();
@@ -2905,7 +2905,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
for (String newFile : newFiles)
{
- SequentialFile file = fileFactory.createSequentialFile(newFile, 1);
+ SequentialFile file = fileFactory.createSequentialFile(newFile);
if (file.exists())
{
final String originalName = file.getFileName();
@@ -2916,8 +2916,8 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
for (Pair<String, String> rename : renames)
{
- SequentialFile fileTmp = fileFactory.createSequentialFile(rename.getA(), 1);
- SequentialFile fileTo = fileFactory.createSequentialFile(rename.getB(), 1);
+ SequentialFile fileTmp = fileFactory.createSequentialFile(rename.getA());
+ SequentialFile fileTo = fileFactory.createSequentialFile(rename.getB());
// We should do the rename only if the tmp file still exist, or else we could
// delete a valid file depending on where the crash occurred during the control file delete
if (fileTmp.exists())
@@ -2951,7 +2951,7 @@ public class JournalImpl extends JournalBase implements TestableJournal, Journal
for (String fileToDelete : leftFiles)
{
ActiveMQJournalLogger.LOGGER.deletingOrphanedFile(fileToDelete);
- SequentialFile file = fileFactory.createSequentialFile(fileToDelete, 1);
+ SequentialFile file = fileFactory.createSequentialFile(fileToDelete);
file.delete();
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFile.java
deleted file mode 100644
index 0dac7f2..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFile.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
-import org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.journal.ActiveMQJournalBundle;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-public final class NIOSequentialFile extends AbstractSequentialFile
-{
- private FileChannel channel;
-
- private RandomAccessFile rfile;
-
- /**
- * The write semaphore here is only used when writing asynchronously
- */
- private Semaphore maxIOSemaphore;
-
- private final int defaultMaxIO;
-
- private int maxIO;
-
- public NIOSequentialFile(final SequentialFileFactory factory,
- final File directory,
- final String file,
- final int maxIO,
- final Executor writerExecutor)
- {
- super(directory, file, factory, writerExecutor);
- defaultMaxIO = maxIO;
- }
-
- public int getAlignment()
- {
- return 1;
- }
-
- public int calculateBlockStart(final int position)
- {
- return position;
- }
-
- public synchronized boolean isOpen()
- {
- return channel != null;
- }
-
- /**
- * this.maxIO represents the default maxIO.
- * Some operations while initializing files on the journal may require a different maxIO
- */
- public synchronized void open() throws IOException
- {
- open(defaultMaxIO, true);
- }
-
- public void open(final int maxIO, final boolean useExecutor) throws IOException
- {
- try
- {
- rfile = new RandomAccessFile(getFile(), "rw");
-
- channel = rfile.getChannel();
-
- fileSize = channel.size();
- }
- catch (IOException e)
- {
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
- throw e;
- }
-
- if (writerExecutor != null && useExecutor)
- {
- maxIOSemaphore = new Semaphore(maxIO);
- this.maxIO = maxIO;
- }
- }
-
- public void fill(final int position, final int size, final byte fillCharacter) throws IOException
- {
- ByteBuffer bb = ByteBuffer.allocate(size);
-
- for (int i = 0; i < size; i++)
- {
- bb.put(fillCharacter);
- }
-
- bb.flip();
-
- try
- {
- channel.position(position);
- channel.write(bb);
- channel.force(false);
- channel.position(0);
- }
- catch (IOException e)
- {
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
- throw e;
- }
-
- fileSize = channel.size();
- }
-
- public synchronized void waitForClose() throws InterruptedException
- {
- while (isOpen())
- {
- wait();
- }
- }
-
- @Override
- public synchronized void close() throws IOException, InterruptedException, ActiveMQException
- {
- super.close();
-
- if (maxIOSemaphore != null)
- {
- while (!maxIOSemaphore.tryAcquire(maxIO, 60, TimeUnit.SECONDS))
- {
- ActiveMQJournalLogger.LOGGER.errorClosingFile(getFileName());
- }
- }
-
- maxIOSemaphore = null;
- try
- {
- if (channel != null)
- {
- channel.close();
- }
-
- if (rfile != null)
- {
- rfile.close();
- }
- }
- catch (IOException e)
- {
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
- throw e;
- }
- channel = null;
-
- rfile = null;
-
- notifyAll();
- }
-
- public int read(final ByteBuffer bytes) throws Exception
- {
- return read(bytes, null);
- }
-
- public synchronized int read(final ByteBuffer bytes, final IOAsyncTask callback) throws IOException,
- ActiveMQIllegalStateException
- {
- try
- {
- if (channel == null)
- {
- throw new ActiveMQIllegalStateException("File " + this.getFileName() + " has a null channel");
- }
- int bytesRead = channel.read(bytes);
-
- if (callback != null)
- {
- callback.done();
- }
-
- bytes.flip();
-
- return bytesRead;
- }
- catch (IOException e)
- {
- if (callback != null)
- {
- callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getLocalizedMessage());
- }
-
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
-
- throw e;
- }
- }
-
- public void sync() throws IOException
- {
- if (channel != null)
- {
- try
- {
- channel.force(false);
- }
- catch (IOException e)
- {
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
- throw e;
- }
- }
- }
-
- public long size() throws IOException
- {
- if (channel == null)
- {
- return getFile().length();
- }
-
- try
- {
- return channel.size();
- }
- catch (IOException e)
- {
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
- throw e;
- }
- }
-
- @Override
- public void position(final long pos) throws IOException
- {
- try
- {
- super.position(pos);
- channel.position(pos);
- }
- catch (IOException e)
- {
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
- throw e;
- }
- }
-
- @Override
- public String toString()
- {
- return "NIOSequentialFile " + getFile();
- }
-
- public SequentialFile cloneFile()
- {
- return new NIOSequentialFile(factory, directory, getFileName(), maxIO, writerExecutor);
- }
-
- public void writeDirect(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback)
- {
- if (callback == null)
- {
- throw new NullPointerException("callback parameter need to be set");
- }
-
- try
- {
- internalWrite(bytes, sync, callback);
- }
- catch (Exception e)
- {
- callback.onError(ActiveMQExceptionType.GENERIC_EXCEPTION.getCode(), e.getMessage());
- }
- }
-
- public void writeDirect(final ByteBuffer bytes, final boolean sync) throws Exception
- {
- internalWrite(bytes, sync, null);
- }
-
- public void writeInternal(final ByteBuffer bytes) throws Exception
- {
- internalWrite(bytes, true, null);
- }
-
- @Override
- protected ByteBuffer newBuffer(int size, final int limit)
- {
- // For NIO, we don't need to allocate a buffer the entire size of the timed buffer, unlike AIO
-
- size = limit;
-
- return super.newBuffer(size, limit);
- }
-
- private void internalWrite(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback) throws IOException, ActiveMQIOErrorException, InterruptedException
- {
- if (!isOpen())
- {
- if (callback != null)
- {
- callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), "File not opened");
- }
- else
- {
- throw ActiveMQJournalBundle.BUNDLE.fileNotOpened();
- }
- return;
- }
-
- position.addAndGet(bytes.limit());
-
- if (maxIOSemaphore == null || callback == null)
- {
- // if maxIOSemaphore == null, that means we are not using executors and the writes are synchronous
- try
- {
- doInternalWrite(bytes, sync, callback);
- }
- catch (IOException e)
- {
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
- }
- }
- else
- {
- // This is a flow control on writing, just like maxAIO on libaio
- maxIOSemaphore.acquire();
-
- writerExecutor.execute(new Runnable()
- {
- public void run()
- {
- try
- {
- try
- {
- doInternalWrite(bytes, sync, callback);
- }
- catch (IOException e)
- {
- ActiveMQJournalLogger.LOGGER.errorSubmittingWrite(e);
- factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), NIOSequentialFile.this);
- callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getMessage());
- }
- catch (Throwable e)
- {
- ActiveMQJournalLogger.LOGGER.errorSubmittingWrite(e);
- callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getMessage());
- }
- }
- finally
- {
- maxIOSemaphore.release();
- }
- }
- });
- }
- }
-
- /**
- * @param bytes
- * @param sync
- * @param callback
- * @throws IOException
- * @throws Exception
- */
- private void doInternalWrite(final ByteBuffer bytes, final boolean sync, final IOAsyncTask callback) throws IOException
- {
- channel.write(bytes);
-
- if (sync)
- {
- sync();
- }
-
- if (callback != null)
- {
- callback.done();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFileFactory.java
deleted file mode 100644
index e471928..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/NIOSequentialFileFactory.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import java.io.File;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-
-public class NIOSequentialFileFactory extends AbstractSequentialFileFactory
-{
- public NIOSequentialFileFactory(final File journalDir)
- {
- this(journalDir, null);
- }
-
- public NIOSequentialFileFactory(final File journalDir, final IOCriticalErrorListener listener)
- {
- this(journalDir,
- false,
- JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO,
- JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO,
- false,
- listener);
- }
-
- public NIOSequentialFileFactory(final File journalDir, final boolean buffered)
- {
- this(journalDir, buffered, null);
- }
-
- public NIOSequentialFileFactory(final File journalDir,
- final boolean buffered,
- final IOCriticalErrorListener listener)
- {
- this(journalDir,
- buffered,
- JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO,
- JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO,
- false,
- listener);
- }
-
- public NIOSequentialFileFactory(final File journalDir,
- final boolean buffered,
- final int bufferSize,
- final int bufferTimeout,
- final boolean logRates)
- {
- this(journalDir, buffered, bufferSize, bufferTimeout, logRates, null);
- }
-
- public NIOSequentialFileFactory(final File journalDir,
- final boolean buffered,
- final int bufferSize,
- final int bufferTimeout,
- final boolean logRates,
- final IOCriticalErrorListener listener)
- {
- super(journalDir, buffered, bufferSize, bufferTimeout, logRates, listener);
- }
-
- public SequentialFile createSequentialFile(final String fileName, int maxIO)
- {
- if (maxIO < 1)
- {
- // A single threaded IO
- maxIO = 1;
- }
-
- return new NIOSequentialFile(this, journalDir, fileName, maxIO, writeExecutor);
- }
-
- public boolean isSupportsCallbacks()
- {
- return timedBuffer != null;
- }
-
-
- public ByteBuffer allocateDirectBuffer(final int size)
- {
- // Using direct buffer, as described on https://jira.jboss.org/browse/HORNETQ-467
- ByteBuffer buffer2 = null;
- try
- {
- buffer2 = ByteBuffer.allocateDirect(size);
- }
- catch (OutOfMemoryError error)
- {
- // This is a workaround for the way the JDK will deal with native buffers.
- // the main portion is outside of the VM heap
- // and the JDK will not have any reference about it to take GC into account
- // so we force a GC and try again.
- WeakReference<Object> obj = new WeakReference<Object>(new Object());
- try
- {
- long timeout = System.currentTimeMillis() + 5000;
- while (System.currentTimeMillis() > timeout && obj.get() != null)
- {
- System.gc();
- Thread.sleep(100);
- }
- }
- catch (InterruptedException e)
- {
- }
-
- buffer2 = ByteBuffer.allocateDirect(size);
-
- }
- return buffer2;
- }
-
- public void releaseDirectBuffer(ByteBuffer buffer)
- {
- // nothing we can do on this case. we can just have good faith on GC
- }
-
- public ByteBuffer newBuffer(final int size)
- {
- return ByteBuffer.allocate(size);
- }
-
- public void clearBuffer(final ByteBuffer buffer)
- {
- final int limit = buffer.limit();
- buffer.rewind();
-
- for (int i = 0; i < limit; i++)
- {
- buffer.put((byte)0);
- }
-
- buffer.rewind();
- }
-
- public ByteBuffer wrapBuffer(final byte[] bytes)
- {
- return ByteBuffer.wrap(bytes);
- }
-
- public int getAlignment()
- {
- return 1;
- }
-
- public int calculateBlockSize(final int bytes)
- {
- return bytes;
- }
-
-}
[3/9] activemq-artemis git commit: ARTEMIS-163 First pass on the
native AIO refactoring
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
index d245985..fcdff05 100644
--- a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
+++ b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
@@ -36,6 +36,7 @@ import org.apache.activemq.artemis.api.core.BaseInterceptor;
import org.apache.activemq.artemis.api.core.Interceptor;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.api.core.management.ManagementHelper;
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQConsumer;
import org.apache.activemq.artemis.core.server.management.ManagementService;
@@ -62,7 +63,6 @@ import org.apache.activemq.command.TransactionId;
import org.apache.activemq.command.TransactionInfo;
import org.apache.activemq.command.WireFormatInfo;
import org.apache.activemq.command.XATransactionId;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQConnectionContext;
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQPersistenceAdapter;
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQProducerBrokerExchange;
@@ -261,7 +261,7 @@ public class OpenWireProtocolManager implements ProtocolManager<Interceptor>, No
public void sendReply(final OpenWireConnection connection,
final Command command)
{
- server.getStorageManager().afterCompleteOperations(new IOAsyncTask()
+ server.getStorageManager().afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
index a4e8ea5..b3d926c 100644
--- a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
+++ b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
@@ -33,7 +33,7 @@ import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
import org.apache.activemq.artemis.api.core.management.ManagementHelper;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.postoffice.BindingType;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyServerConnection;
import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
@@ -357,7 +357,7 @@ class StompProtocolManager implements ProtocolManager<StompFrameInterceptor>, No
public void sendReply(final StompConnection connection, final StompFrame frame)
{
- server.getStorageManager().afterCompleteOperations(new IOAsyncTask()
+ server.getStorageManager().afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
index 8efeabb..c1b767a 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
@@ -41,7 +41,7 @@ import org.apache.activemq.artemis.core.config.ha.SharedStoreMasterPolicyConfigu
import org.apache.activemq.artemis.core.config.ha.SharedStoreSlavePolicyConfiguration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.config.impl.Validators;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
index ee3bb86..8e06cde 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
@@ -26,7 +26,7 @@ import org.apache.activemq.artemis.core.settings.HierarchicalRepositoryChangeLis
* <PRE>
*
* +--------------+ 1 +----------------+ N +--------------+ N +--------+ 1 +-------------------+
- * | {@link org.apache.activemq.artemis.core.postoffice.PostOffice} |-------> |{@link PagingManager}|-------> |{@link PagingStore} | ------> | {@link org.apache.activemq.artemis.core.paging.impl.Page} | ------> | {@link org.apache.activemq.artemis.core.journal.SequentialFile} |
+ * | {@link org.apache.activemq.artemis.core.postoffice.PostOffice} |-------> |{@link PagingManager}|-------> |{@link PagingStore} | ------> | {@link org.apache.activemq.artemis.core.paging.impl.Page} | ------> | {@link SequentialFile} |
* +--------------+ +----------------+ +--------------+ +--------+ +-------------------+
* | 1 ^
* | |
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
index 3b74e45..b0129e7 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
@@ -158,7 +158,7 @@ public interface PagingStore extends ActiveMQComponent
/**
* Sends the pages with given IDs to the {@link ReplicationManager}.
* <p>
- * Sending is done here to avoid exposing the internal {@link org.apache.activemq.artemis.core.journal.SequentialFile}s.
+ * Sending is done here to avoid exposing the internal {@link SequentialFile}s.
*
* @param replicator
* @param pageIds
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
index f83966d..0818034 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
@@ -19,7 +19,7 @@ package org.apache.activemq.artemis.core.paging;
import java.util.List;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java
index 39324da..e98da75 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/cursor/impl/PageSubscriptionImpl.java
@@ -32,8 +32,8 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.paging.PagingStore;
@@ -521,7 +521,7 @@ final class PageSubscriptionImpl implements PageSubscription
store.storeCursorAcknowledge(cursorId, position);
}
- store.afterCompleteOperations(new IOAsyncTask()
+ store.afterCompleteOperations(new IOCallback()
{
volatile String error = "";
@@ -541,7 +541,7 @@ final class PageSubscriptionImpl implements PageSubscription
@Override
public String toString()
{
- return IOAsyncTask.class.getSimpleName() + "(" + PageSubscriptionImpl.class.getSimpleName() + ") " + error;
+ return IOCallback.class.getSimpleName() + "(" + PageSubscriptionImpl.class.getSimpleName() + ") " + error;
}
});
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java
index 24d60df..ae41bb0 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/Page.java
@@ -25,8 +25,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.paging.cursor.LivePageCache;
import org.apache.activemq.artemis.core.paging.cursor.PageSubscriptionCounter;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
index 3a12b96..63681f2 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
@@ -29,9 +29,9 @@ import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.paging.PagingManager;
import org.apache.activemq.artemis.core.paging.PagingStore;
import org.apache.activemq.artemis.core.paging.PagingStoreFactory;
@@ -208,6 +208,6 @@ public class PagingStoreFactoryNIO implements PagingStoreFactory
private SequentialFileFactory newFileFactory(final String directoryName)
{
- return new NIOSequentialFileFactory(new File(directory, directoryName), false, critialErrorListener);
+ return new NIOSequentialFileFactory(new File(directory, directoryName), false, critialErrorListener, 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
index 3b0a139..6b67f3e 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
@@ -37,8 +37,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.paging.PagingManager;
@@ -576,7 +576,7 @@ public class PagingStoreImpl implements PagingStore
public boolean checkPageFileExists(final int pageNumber)
{
String fileName = createFileName(pageNumber);
- SequentialFile file = fileFactory.createSequentialFile(fileName, 1);
+ SequentialFile file = fileFactory.createSequentialFile(fileName);
return file.exists();
}
@@ -589,7 +589,7 @@ public class PagingStoreImpl implements PagingStore
fileFactory = storeFactory.newFileFactory(getStoreName());
}
- SequentialFile file = fileFactory.createSequentialFile(fileName, 1000);
+ SequentialFile file = fileFactory.createSequentialFile(fileName);
Page page = new Page(storeName, storageManager, fileFactory, file, pageNumber);
@@ -1227,7 +1227,7 @@ public class PagingStoreImpl implements PagingStore
{
for (Integer id : pageIds)
{
- SequentialFile sFile = fileFactory.createSequentialFile(createFileName(id), 1);
+ SequentialFile sFile = fileFactory.createSequentialFile(createFileName(id));
if (!sFile.exists())
{
continue;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java
index 2e1dd73..d13f311 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/OperationContext.java
@@ -16,7 +16,7 @@
*/
package org.apache.activemq.artemis.core.persistence;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.journal.IOCompletion;
/**
@@ -28,7 +28,7 @@ public interface OperationContext extends IOCompletion
{
/** Execute the task when all IO operations are complete,
* Or execute it immediately if nothing is pending. */
- void executeOnCompletion(IOAsyncTask runnable);
+ void executeOnCompletion(IOCallback runnable);
void replicationLineUp();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
index 5196ccc..7cf8112 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
@@ -25,10 +25,10 @@ import java.util.concurrent.Executor;
import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.message.impl.MessageInternal;
import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -99,7 +99,7 @@ public interface StorageManager extends IDGenerator, ActiveMQComponent
void pageWrite(PagedMessage message, int pageNumber);
- void afterCompleteOperations(IOAsyncTask run);
+ void afterCompleteOperations(IOCallback run);
/**
* Block until the operations are done.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java
index 3c25164..210877c 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/DescribeJournal.java
@@ -31,12 +31,12 @@ import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.apache.activemq.artemis.core.journal.impl.JournalReaderCallback;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.paging.cursor.impl.PageSubscriptionCounterImpl;
import org.apache.activemq.artemis.core.paging.impl.PageTransactionInfoImpl;
import org.apache.activemq.artemis.core.persistence.impl.journal.BatchingIDGenerator.IDCounterEncoding;
@@ -109,7 +109,7 @@ public final class DescribeJournal
public static void describeBindingsJournal(final File bindingsDir) throws Exception
{
- SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(bindingsDir, null);
+ SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(bindingsDir, null, 1);
JournalImpl bindings = new JournalImpl(1024 * 1024, 2, -1, 0, bindingsFF, "activemq-bindings", "bindings", 1);
describeJournal(bindingsFF, bindings, bindingsDir);
@@ -118,7 +118,7 @@ public final class DescribeJournal
public static DescribeJournal describeMessagesJournal(final File messagesDir) throws Exception
{
- SequentialFileFactory messagesFF = new NIOSequentialFileFactory(messagesDir, null);
+ SequentialFileFactory messagesFF = new NIOSequentialFileFactory(messagesDir, null, 1);
// Will use only default values. The load function should adapt to anything different
ConfigurationImpl defaultValues = new ConfigurationImpl();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
index 5104b68..33a1cbe 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
@@ -53,22 +53,22 @@ import org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.filter.Filter;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.message.impl.MessageInternal;
import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -236,7 +236,9 @@ public class JournalStorageManager implements StorageManager
}
- SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(config.getBindingsLocation(), criticalErrorListener);
+ SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(config.getBindingsLocation(),
+ criticalErrorListener,
+ config.getJournalMaxIO_NIO());
Journal localBindings = new JournalImpl(1024 * 1024,
2,
@@ -261,6 +263,7 @@ public class JournalStorageManager implements StorageManager
journalFF = new AIOSequentialFileFactory(config.getJournalLocation(),
config.getJournalBufferSize_AIO(),
config.getJournalBufferTimeout_AIO(),
+ config.getJournalMaxIO_AIO(),
config.isLogJournalWriteRate(),
criticalErrorListener);
}
@@ -271,6 +274,7 @@ public class JournalStorageManager implements StorageManager
true,
config.getJournalBufferSize_NIO(),
config.getJournalBufferTimeout_NIO(),
+ config.getJournalMaxIO_NIO(),
config.isLogJournalWriteRate(),
criticalErrorListener);
}
@@ -296,7 +300,8 @@ public class JournalStorageManager implements StorageManager
largeMessagesDirectory = config.getLargeMessagesDirectory();
- largeMessagesFactory = new NIOSequentialFileFactory(config.getLargeMessagesLocation(), false, criticalErrorListener);
+ largeMessagesFactory = new NIOSequentialFileFactory(config.getLargeMessagesLocation(), false, criticalErrorListener,
+ 1);
perfBlastPages = config.getJournalPerfBlastPages();
@@ -572,7 +577,7 @@ public class JournalStorageManager implements StorageManager
String fileName = entry.getValue().getA();
final long id = entry.getKey();
long size = entry.getValue().getB();
- SequentialFile seqFile = largeMessagesFactory.createSequentialFile(fileName, 1);
+ SequentialFile seqFile = largeMessagesFactory.createSequentialFile(fileName);
if (!seqFile.exists())
continue;
replicator.syncLargeMessageFile(seqFile, size, id);
@@ -608,7 +613,7 @@ public class JournalStorageManager implements StorageManager
if (!largeMessagesToDelete.contains(id))
{
idList.add(id);
- SequentialFile seqFile = largeMessagesFactory.createSequentialFile(filename, 1);
+ SequentialFile seqFile = largeMessagesFactory.createSequentialFile(filename);
long size = seqFile.size();
largeMessages.put(id, new Pair<String, Long>(filename, size));
}
@@ -747,7 +752,7 @@ public class JournalStorageManager implements StorageManager
return new OperationContextImpl(executor1);
}
- public void afterCompleteOperations(final IOAsyncTask run)
+ public void afterCompleteOperations(final IOCallback run)
{
getContext().executeOnCompletion(run);
}
@@ -2498,7 +2503,7 @@ public class JournalStorageManager implements StorageManager
public SequentialFile createFileForLargeMessage(final long messageID, LargeMessageExtension extension)
{
- return largeMessagesFactory.createSequentialFile(messageID + extension.getExtension(), -1);
+ return largeMessagesFactory.createSequentialFile(messageID + extension.getExtension());
}
@@ -2788,7 +2793,7 @@ public class JournalStorageManager implements StorageManager
List<String> tmpFiles = largeMessagesFactory.listFiles("tmp");
for (String tmpFile : tmpFiles)
{
- SequentialFile file = largeMessagesFactory.createSequentialFile(tmpFile, -1);
+ SequentialFile file = largeMessagesFactory.createSequentialFile(tmpFile);
file.delete();
}
}
@@ -2830,7 +2835,7 @@ public class JournalStorageManager implements StorageManager
return DummyOperationContext.instance;
}
- public void executeOnCompletion(final IOAsyncTask runnable)
+ public void executeOnCompletion(final IOCallback runnable)
{
// There are no executeOnCompletion calls while using the DummyOperationContext
// However we keep the code here for correctness
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java
index dc09160..c4aa058 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageImpl.java
@@ -24,7 +24,7 @@ import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
import org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException;
import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.message.BodyEncoder;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.core.server.LargeServerMessage;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java
index 76a8653..b034660 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/LargeServerMessageInSync.java
@@ -20,7 +20,7 @@ import java.nio.ByteBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.persistence.StorageManager;
import org.apache.activemq.artemis.core.persistence.StorageManager.LargeMessageExtension;
import org.apache.activemq.artemis.core.replication.ReplicatedLargeMessage;
@@ -62,7 +62,7 @@ public final class LargeServerMessageInSync implements ReplicatedLargeMessage
buffer.rewind();
int bytesRead = appendFile.read(buffer);
if (bytesRead > 0)
- mainSeqFile.writeInternal(buffer);
+ mainSeqFile.writeDirect(buffer, false);
if (bytesRead < buffer.capacity())
{
break;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java
index 32eca26..a8e8e2a 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/OperationContextImpl.java
@@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.journal.impl.SimpleWaitIOCallback;
import org.apache.activemq.artemis.core.persistence.OperationContext;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
@@ -134,7 +134,7 @@ public class OperationContextImpl implements OperationContext
checkTasks();
}
- public void executeOnCompletion(final IOAsyncTask completion)
+ public void executeOnCompletion(final IOCallback completion)
{
if (errorCode != -1)
{
@@ -219,7 +219,7 @@ public class OperationContextImpl implements OperationContext
/**
* @param task
*/
- private void execute(final IOAsyncTask task)
+ private void execute(final IOCallback task)
{
executorsPending.incrementAndGet();
try
@@ -243,7 +243,7 @@ public class OperationContextImpl implements OperationContext
}
catch (Throwable e)
{
- ActiveMQServerLogger.LOGGER.errorExecutingIOAsyncTask(e);
+ ActiveMQServerLogger.LOGGER.errorExecutingAIOCallback(e);
executorsPending.decrementAndGet();
task.onError(ActiveMQExceptionType.INTERNAL_ERROR.getCode(),
"It wasn't possible to complete IO operation - " + e.getMessage());
@@ -296,9 +296,9 @@ public class OperationContextImpl implements OperationContext
final int replicationLined;
final int pageLined;
- final IOAsyncTask task;
+ final IOCallback task;
- TaskHolder(final IOAsyncTask task)
+ TaskHolder(final IOCallback task)
{
storeLined = storeLineUp.intValue();
replicationLined = replicationLineUp.intValue();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java
index 303e257..25cd0fc 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageLargeServerMessage.java
@@ -17,7 +17,7 @@
package org.apache.activemq.artemis.core.persistence.impl.nullpm;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.server.LargeServerMessage;
import org.apache.activemq.artemis.core.server.ServerMessage;
import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
index ade2173..d6336d2 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
@@ -27,10 +27,10 @@ import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.message.impl.MessageInternal;
import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -112,7 +112,7 @@ public class NullStorageManager implements StorageManager
}
@Override
- public void executeOnCompletion(final IOAsyncTask runnable)
+ public void executeOnCompletion(final IOCallback runnable)
{
runnable.done();
}
@@ -359,7 +359,7 @@ public class NullStorageManager implements StorageManager
}
@Override
- public void afterCompleteOperations(final IOAsyncTask run)
+ public void afterCompleteOperations(final IOCallback run)
{
run.done();
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
index 12bf669..71a2458 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
@@ -41,8 +41,8 @@ import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
import org.apache.activemq.artemis.api.core.management.ManagementHelper;
import org.apache.activemq.artemis.api.core.management.NotificationType;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.message.impl.MessageImpl;
import org.apache.activemq.artemis.core.paging.PagingManager;
import org.apache.activemq.artemis.core.paging.PagingStore;
@@ -1179,7 +1179,7 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
{
// This will use the same thread if there are no pending operations
// avoiding a context switch on this case
- storageManager.afterCompleteOperations(new IOAsyncTask()
+ storageManager.afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
{
@@ -1249,7 +1249,7 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
queues.addAll(durableQueues);
queues.addAll(nonDurableQueues);
- storageManager.afterCompleteOperations(new IOAsyncTask()
+ storageManager.afterCompleteOperations(new IOCallback()
{
public void onError(int errorCode, String errorMessage)
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
index 109d4fd..a39950e 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
@@ -58,8 +58,8 @@ import javax.transaction.xa.Xid;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
import org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.exception.ActiveMQXAException;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.persistence.StorageManager;
import org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl;
import org.apache.activemq.artemis.core.protocol.core.impl.wireformat.CreateQueueMessage;
@@ -614,7 +614,7 @@ public class ServerSessionPacketHandler implements ChannelHandler
final boolean flush,
final boolean closeChannel)
{
- storageManager.afterCompleteOperations(new IOAsyncTask()
+ storageManager.afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java
index 2723198..d96dbe1 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicatedJournal.java
@@ -26,7 +26,7 @@ import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
import org.apache.activemq.artemis.core.journal.LoaderCallback;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java
index ec16825..afb1e77 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationEndpoint.java
@@ -34,11 +34,11 @@ import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.Journal.JournalState;
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.journal.impl.FileWrapperJournal;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -546,7 +546,7 @@ public final class ReplicationEndpoint implements ChannelHandler, ActiveMQCompon
if (!channel1.isOpen())
{
- channel1.open(1, false);
+ channel1.open();
}
channel1.writeDirect(ByteBuffer.wrap(data), true);
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java
index a2f39c9..905d7a5 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/replication/ReplicationManager.java
@@ -33,7 +33,7 @@ import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.SessionFailureListener;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.persistence.OperationContext;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
index b136990..11e6f61 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
@@ -43,10 +43,10 @@ import io.netty.channel.Channel;
import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.client.impl.ServerLocatorInternal;
import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.paging.cursor.PagePosition;
import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
@@ -522,8 +522,8 @@ public interface ActiveMQServerLogger extends BasicLogger
void lareMessageErrorCopying(@Cause Exception e, LargeServerMessage largeServerMessage);
@LogMessage(level = Logger.Level.WARN)
- @Message(id = 222054, value = "Error on executing IOAsyncTask", format = Message.Format.MESSAGE_FORMAT)
- void errorExecutingIOAsyncTask(@Cause Throwable t);
+ @Message(id = 222054, value = "Error on executing IOCallback", format = Message.Format.MESSAGE_FORMAT)
+ void errorExecutingAIOCallback(@Cause Throwable t);
@LogMessage(level = Logger.Level.WARN)
@Message(id = 222055, value = "Error on deleting duplicate cache", format = Message.Format.MESSAGE_FORMAT)
@@ -1200,7 +1200,7 @@ public interface ActiveMQServerLogger extends BasicLogger
@LogMessage(level = Logger.Level.ERROR)
@Message(id = 224007, value = "page subscription = {0} error={1}", format = Message.Format.MESSAGE_FORMAT)
- void pageSubscriptionError(IOAsyncTask ioAsyncTask, String error);
+ void pageSubscriptionError(IOCallback IOCallback, String error);
@LogMessage(level = Logger.Level.ERROR)
@Message(id = 224008, value = "Failed to store id", format = Message.Format.MESSAGE_FORMAT)
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java
index 57120ff..e22a172 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/LargeServerMessage.java
@@ -17,7 +17,7 @@
package org.apache.activemq.artemis.core.server;
import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.replication.ReplicatedLargeMessage;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java
index 3c0ba41..106158c 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/Redistributor.java
@@ -22,8 +22,8 @@ import java.util.concurrent.Executor;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.persistence.StorageManager;
import org.apache.activemq.artemis.core.postoffice.PostOffice;
import org.apache.activemq.artemis.core.server.Consumer;
@@ -247,7 +247,7 @@ public class Redistributor implements Consumer
tx.commit();
- storageManager.afterCompleteOperations(new IOAsyncTask()
+ storageManager.afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java
index 7adee2e..2d0f3c0 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/AIOFileLockNodeManager.java
@@ -17,10 +17,11 @@
package org.apache.activemq.artemis.core.server.impl;
import java.io.File;
-import java.io.IOException;
import java.nio.channels.FileLock;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
+import org.apache.activemq.artemis.core.io.aio.ActiveMQFileLock;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
/**
* This is using the ActiveMQ Artemis Libaio Native to perform calls to flock on a Linux system. At the
@@ -56,19 +57,15 @@ public final class AIOFileLockNodeManager extends FileLockNodeManager
{
File file = newFileForRegionLock(lockPos);
- int handle = AsynchronousFileImpl.openFile(file.getAbsolutePath());
+ LibaioFile fileControl = LibaioContext.openControlFile(file.getAbsolutePath(), false);
- if (handle < 0)
+ if (!fileControl.lock())
{
- throw new IOException("couldn't open file " + file.getAbsolutePath());
+ fileControl.close();
+ return null;
}
- FileLock lock = AsynchronousFileImpl.lock(handle);
-
- if (lock == null)
- {
- AsynchronousFileImpl.closeFile(handle);
- }
+ FileLock lock = new ActiveMQFileLock(fileControl);
return lock;
@@ -83,21 +80,13 @@ public final class AIOFileLockNodeManager extends FileLockNodeManager
while (!interrupted)
{
- int handle = AsynchronousFileImpl.openFile(file.getAbsolutePath());
-
- if (handle < 0)
- {
- throw new IOException("couldn't open file " + file.getAbsolutePath());
- }
-
- FileLock lockFile = AsynchronousFileImpl.lock(handle);
+ FileLock lockFile = tryLock(liveLockPos);
if (lockFile != null)
{
return lockFile;
}
else
{
- AsynchronousFileImpl.closeFile(handle);
try
{
Thread.sleep(500);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index 0dc85de..9d7e95b 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -19,7 +19,6 @@ package org.apache.activemq.artemis.core.server.impl;
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl;
import org.apache.activemq.artemis.core.config.BridgeConfiguration;
import org.apache.activemq.artemis.core.config.Configuration;
@@ -29,11 +28,10 @@ import org.apache.activemq.artemis.core.config.DivertConfiguration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.filter.Filter;
import org.apache.activemq.artemis.core.filter.impl.FilterImpl;
-import org.apache.activemq.artemis.core.journal.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.SyncSpeedTest;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.management.impl.ActiveMQServerControlImpl;
import org.apache.activemq.artemis.core.paging.PagingManager;
import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
@@ -96,6 +94,7 @@ import org.apache.activemq.artemis.core.settings.impl.ResourceLimitSettings;
import org.apache.activemq.artemis.core.transaction.ResourceManager;
import org.apache.activemq.artemis.core.transaction.impl.ResourceManagerImpl;
import org.apache.activemq.artemis.core.version.Version;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
import org.apache.activemq.artemis.spi.core.protocol.SessionCallback;
@@ -359,7 +358,7 @@ public class ActiveMQServerImpl implements ActiveMQServer
{
manager = new InVMNodeManager(replicatingBackup);
}
- else if (configuration.getJournalType() == JournalType.ASYNCIO && AsynchronousFileImpl.isLoaded())
+ else if (configuration.getJournalType() == JournalType.ASYNCIO && LibaioContext.isLoaded())
{
manager = new AIOFileLockNodeManager(directory, replicatingBackup, configuration.getJournalLockAcquisitionTimeout());
}
@@ -401,13 +400,6 @@ public class ActiveMQServerImpl implements ActiveMQServer
ActiveMQServerLogger.LOGGER.serverStarting((haPolicy.isBackup() ? "backup" : "live"), configuration);
- if (configuration.isRunSyncSpeedTest())
- {
- SyncSpeedTest test = new SyncSpeedTest();
-
- test.run();
- }
-
final boolean wasLive = !haPolicy.isBackup();
if (!haPolicy.isBackup())
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
index 29a4509..92cdbf9 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
@@ -45,8 +45,8 @@ import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
import org.apache.activemq.artemis.api.core.management.ManagementHelper;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.message.impl.MessageImpl;
import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
import org.apache.activemq.artemis.core.paging.cursor.PagedReference;
@@ -2524,7 +2524,7 @@ public class QueueImpl implements Queue
acknowledge(tx, ref);
- storageManager.afterCompleteOperations(new IOAsyncTask()
+ storageManager.afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
index 98b6bb7..49a3926 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
@@ -39,11 +39,11 @@ import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
import org.apache.activemq.artemis.api.core.management.ManagementHelper;
import org.apache.activemq.artemis.api.core.management.ResourceNames;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.client.impl.ClientMessageImpl;
import org.apache.activemq.artemis.core.exception.ActiveMQXAException;
import org.apache.activemq.artemis.core.filter.Filter;
import org.apache.activemq.artemis.core.filter.impl.FilterImpl;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.message.impl.MessageInternal;
import org.apache.activemq.artemis.core.paging.PagingStore;
import org.apache.activemq.artemis.core.persistence.OperationContext;
@@ -1395,7 +1395,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener
public void close(final boolean failed)
{
if (closed) return;
- context.executeOnCompletion(new IOAsyncTask()
+ context.executeOnCompletion(new IOCallback()
{
public void onError(int errorCode, String errorMessage)
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java
index 42aab20..357ce6f 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImpl.java
@@ -23,7 +23,7 @@ import java.util.Date;
import java.util.List;
import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.persistence.StorageManager;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.core.server.Queue;
@@ -197,7 +197,7 @@ public class TransactionImpl implements Transaction
// We use the Callback even for non persistence
// If we are using non-persistence with replication, the replication manager will have
// to execute this runnable in the correct order
- storageManager.afterCompleteOperations(new IOAsyncTask()
+ storageManager.afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
@@ -266,7 +266,7 @@ public class TransactionImpl implements Transaction
// to execute this runnable in the correct order
// This also will only use a different thread if there are any IO pending.
// If the IO finished early by the time we got here, we won't need an executor
- storageManager.afterCompleteOperations(new IOAsyncTask()
+ storageManager.afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
@@ -323,7 +323,7 @@ public class TransactionImpl implements Transaction
// We use the Callback even for non persistence
// If we are using non-persistence with replication, the replication manager will have
// to execute this runnable in the correct order
- storageManager.afterCompleteOperations(new IOAsyncTask()
+ storageManager.afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
index 26e9bb5..4142f1f 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
@@ -67,7 +67,6 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl;
import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal;
import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl;
@@ -78,11 +77,11 @@ import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.apache.activemq.artemis.core.journal.impl.JournalReaderCallback;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.paging.PagingStore;
import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
import org.apache.activemq.artemis.core.postoffice.Binding;
@@ -117,6 +116,7 @@ import org.apache.activemq.artemis.core.server.impl.SharedNothingBackupActivatio
import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManagerImpl;
import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
@@ -574,7 +574,7 @@ public abstract class ActiveMQTestBase extends Assert
public static JournalType getDefaultJournalType()
{
- if (AsynchronousFileImpl.isLoaded())
+ if (LibaioContext.isLoaded())
{
return JournalType.ASYNCIO;
}
@@ -1894,7 +1894,7 @@ public abstract class ActiveMQTestBase extends Assert
JournalImpl messagesJournal = null;
try
{
- SequentialFileFactory messagesFF = new NIOSequentialFileFactory(new File(getJournalDir()), null);
+ SequentialFileFactory messagesFF = new NIOSequentialFileFactory(new File(getJournalDir()), null, 1);
messagesJournal = new JournalImpl(config.getJournalFileSize(),
config.getJournalMinFiles(),
@@ -1940,7 +1940,7 @@ public abstract class ActiveMQTestBase extends Assert
protected HashMap<Integer, AtomicInteger> countJournal(Configuration config) throws Exception
{
final HashMap<Integer, AtomicInteger> recordsType = new HashMap<Integer, AtomicInteger>();
- SequentialFileFactory messagesFF = new NIOSequentialFileFactory(config.getJournalLocation(), null);
+ SequentialFileFactory messagesFF = new NIOSequentialFileFactory(config.getJournalLocation(), null, 1);
JournalImpl messagesJournal = new JournalImpl(config.getJournalFileSize(),
config.getJournalMinFiles(),
@@ -1988,7 +1988,7 @@ public abstract class ActiveMQTestBase extends Assert
if (messageJournal)
{
- ff = new NIOSequentialFileFactory(config.getJournalLocation(), null);
+ ff = new NIOSequentialFileFactory(config.getJournalLocation(), null, 1);
journal = new JournalImpl(config.getJournalFileSize(),
config.getJournalMinFiles(),
0,
@@ -2000,7 +2000,7 @@ public abstract class ActiveMQTestBase extends Assert
}
else
{
- ff = new NIOSequentialFileFactory(config.getBindingsLocation(), null);
+ ff = new NIOSequentialFileFactory(config.getBindingsLocation(), null, 1);
journal = new JournalImpl(1024 * 1024,
2,
config.getJournalCompactMinFiles(),
@@ -2403,31 +2403,31 @@ public abstract class ActiveMQTestBase extends Assert
long timeout = System.currentTimeMillis() + 15000;
- while (AsynchronousFileImpl.getTotalMaxIO() != 0 && System.currentTimeMillis() > timeout)
- {
- try
- {
- Thread.sleep(100);
- }
- catch (Exception ignored)
- {
- }
- }
-
- int invmSize = InVMRegistry.instance.size();
- if (invmSize > 0)
- {
- InVMRegistry.instance.clear();
- log.info(threadDump("Thread dump"));
- fail("invm registry still had acceptors registered");
- }
-
- final int totalMaxIO = AsynchronousFileImpl.getTotalMaxIO();
- if (totalMaxIO != 0)
- {
- AsynchronousFileImpl.resetMaxAIO();
- Assert.fail("test did not close all its files " + totalMaxIO);
- }
+// while (AsynchronousFileImpl.getTotalMaxIO() != 0 && System.currentTimeMillis() > timeout)
+// {
+// try
+// {
+// Thread.sleep(100);
+// }
+// catch (Exception ignored)
+// {
+// }
+// }
+//
+// int invmSize = InVMRegistry.instance.size();
+// if (invmSize > 0)
+// {
+// InVMRegistry.instance.clear();
+// log.info(threadDump("Thread dump"));
+// fail("invm registry still had acceptors registered");
+// }
+//
+// final int totalMaxIO = AsynchronousFileImpl.getTotalMaxIO();
+// if (totalMaxIO != 0)
+// {
+// AsynchronousFileImpl.resetMaxAIO();
+// Assert.fail("test did not close all its files " + totalMaxIO);
+// }
}
private void cleanupPools()
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java
index 4f9dd48..845c9da 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ColocatedActiveMQServer.java
@@ -17,18 +17,17 @@
package org.apache.activemq.artemis.tests.util;
import javax.management.MBeanServer;
-
import java.io.File;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.JournalType;
import org.apache.activemq.artemis.core.server.NodeManager;
import org.apache.activemq.artemis.core.server.impl.AIOFileLockNodeManager;
-import org.apache.activemq.artemis.core.server.impl.FileLockNodeManager;
import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
+import org.apache.activemq.artemis.core.server.impl.FileLockNodeManager;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
@@ -69,7 +68,7 @@ public class ColocatedActiveMQServer extends ActiveMQServerImpl
if (replicatingBackup)
{
NodeManager manager;
- if (getConfiguration().getJournalType() == JournalType.ASYNCIO && AsynchronousFileImpl.isLoaded())
+ if (getConfiguration().getJournalType() == JournalType.ASYNCIO && LibaioContext.isLoaded())
{
return new AIOFileLockNodeManager(directory, replicatingBackup, getConfiguration().getJournalLockAcquisitionTimeout());
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
index a6bce80..4332fbd 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
@@ -37,9 +37,9 @@ import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.filter.Filter;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
import org.apache.activemq.artemis.core.persistence.OperationContext;
import org.apache.activemq.artemis.core.persistence.StorageManager;
@@ -480,7 +480,7 @@ public class HangConsumerTest extends ActiveMQTestBase
server.stop();
- SequentialFileFactory messagesFF = new NIOSequentialFileFactory(server.getConfiguration().getBindingsLocation(), null);
+ SequentialFileFactory messagesFF = new NIOSequentialFileFactory(server.getConfiguration().getBindingsLocation(), null, 1);
JournalImpl messagesJournal = new JournalImpl(1024 * 1024,
2,
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java
index e71189f..cbc2904 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/JournalCrashTest.java
@@ -33,7 +33,7 @@ import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Assert;
@@ -221,7 +221,7 @@ public class JournalCrashTest extends ActiveMQTestBase
*/
private void printJournal() throws Exception
{
- NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getJournalDir()));
+ NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getJournalDir()), 100);
JournalImpl journal = new JournalImpl(ActiveMQDefaultConfiguration.getDefaultJournalFileSize(),
2,
0,
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java
index 4e6191e..9044b28 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LibaioDependencyCheckTest.java
@@ -16,9 +16,9 @@
*/
package org.apache.activemq.artemis.tests.integration.client;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.junit.Test;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
/**
@@ -45,7 +45,7 @@ public class LibaioDependencyCheckTest extends ActiveMQTestBase
{
if (System.getProperties().get("os.name").equals("Linux"))
{
- assertTrue("Libaio is not available on this platform", AsynchronousFileImpl.isLoaded());
+ assertTrue("Libaio is not available on this platform", LibaioContext.isLoaded());
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
index 9d0d4d7..b870639 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
@@ -46,15 +46,15 @@ import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.MessageHandler;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.DivertConfiguration;
import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.paging.PagingManager;
import org.apache.activemq.artemis.core.paging.PagingStore;
@@ -1734,7 +1734,7 @@ public class PagingTest extends ActiveMQTestBase
2,
0,
0,
- new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation()),
+ new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation(), 1),
"activemq-data",
"amq",
1);
@@ -6454,7 +6454,7 @@ public class PagingTest extends ActiveMQTestBase
pageDone.countDown();
}
- public void executeOnCompletion(IOAsyncTask runnable)
+ public void executeOnCompletion(IOCallback runnable)
{
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java
index 460c4df..dea83e6 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/RedeliveryConsumerTest.java
@@ -32,7 +32,7 @@ import org.apache.activemq.artemis.core.journal.LoaderCallback;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
@@ -297,7 +297,7 @@ public class RedeliveryConsumerTest extends ActiveMQTestBase
2,
0,
0,
- new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation()),
+ new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation(), 1),
"activemq-data",
"amq",
1);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java
index ede895f..151e2b4 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/bridge/BridgeTest.java
@@ -45,9 +45,9 @@ import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.CoreQueueConfiguration;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal;
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
import org.apache.activemq.artemis.core.postoffice.DuplicateIDCache;
@@ -1923,7 +1923,7 @@ public class BridgeTest extends ActiveMQTestBase
protected Map<Long, AtomicInteger> loadQueues(ActiveMQServer serverToInvestigate) throws Exception
{
SequentialFileFactory messagesFF = new NIOSequentialFileFactory(serverToInvestigate.getConfiguration()
- .getJournalLocation());
+ .getJournalLocation(), 1);
JournalImpl messagesJournal = new JournalImpl(serverToInvestigate.getConfiguration().getJournalFileSize(),
serverToInvestigate.getConfiguration().getJournalMinFiles(),
[4/9] activemq-artemis git commit: ARTEMIS-163 First pass on the
native AIO refactoring
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.c
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.c b/artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.c
new file mode 100644
index 0000000..b6fcdd3
--- /dev/null
+++ b/artemis-native/src/main/c/org_apache_activemq_artemis_jlibaio_LibaioContext.c
@@ -0,0 +1,710 @@
+/*
+ * 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.
+ */
+
+#ifndef _GNU_SOURCE
+// libaio, O_DIRECT and other things won't be available without this define
+#define _GNU_SOURCE
+#endif
+
+//#define DEBUG
+
+#include <jni.h>
+#include <unistd.h>
+#include <errno.h>
+#include <libaio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "org_apache_activemq_artemis_jlibaio_LibaioContext.h"
+#include "exception_helper.h"
+
+struct io_control {
+ io_context_t ioContext;
+ struct io_event * events;
+
+ jobject thisObject;
+
+ // This is used to make sure we don't return IOCB while something else is using them
+ // this is to guarantee the submits could be done concurrently with polling
+ pthread_mutex_t iocbLock;
+
+ pthread_mutex_t pollLock;
+
+ // a resuable pool of iocb
+ struct iocb ** iocb;
+ int queueSize;
+ int iocbPut;
+ int iocbGet;
+ int used;
+};
+
+jclass submitClass = NULL;
+jmethodID errorMethod = NULL;
+jmethodID doneMethod = NULL;
+jmethodID libaioContextDone = NULL;
+
+jclass libaioContextClass = NULL;
+jclass runtimeExceptionClass = NULL;
+jclass ioExceptionClass = NULL;
+
+// util methods
+void throwRuntimeException(JNIEnv* env, char* message) {
+ (*env)->ThrowNew(env, runtimeExceptionClass, message);
+}
+
+void throwRuntimeExceptionErrorNo(JNIEnv* env, char* message, int errorNumber) {
+ char* allocatedMessage = exceptionMessage(message, errorNumber);
+ (*env)->ThrowNew(env, runtimeExceptionClass, allocatedMessage);
+ free(allocatedMessage);
+}
+
+void throwIOException(JNIEnv* env, char* message) {
+ (*env)->ThrowNew(env, ioExceptionClass, message);
+}
+
+void throwIOExceptionErrorNo(JNIEnv* env, char* message, int errorNumber) {
+ char* allocatedMessage = exceptionMessage(message, errorNumber);
+ (*env)->ThrowNew(env, ioExceptionClass, allocatedMessage);
+ free(allocatedMessage);
+}
+
+void throwOutOfMemoryError(JNIEnv* env) {
+ jclass exceptionClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+ (*env)->ThrowNew(env, exceptionClass, "");
+}
+
+/** Notice: every usage of exceptionMessage needs to release the allocated memory for the sequence of char */
+char* exceptionMessage(char* msg, int error) {
+ if (error < 0) {
+ // some functions return negative values
+ // and it's hard to keep track of when to send -error and when not
+ // this will just take care when things are forgotten
+ // what would generate a proper error
+ error = error * -1;
+ }
+ //strerror is returning a constant, so no need to free anything coming from strerror
+ char* err = strerror(error);
+ char* result = malloc(strlen(msg) + strlen(err) + 1);
+ strcpy(result, msg);
+ strcat(result, err);
+ return result;
+}
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ JNIEnv* env;
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
+ return JNI_ERR;
+ } else {
+ jclass localRuntimeExceptionClass = (*env)->FindClass(env, "java/lang/RuntimeException");
+ if (localRuntimeExceptionClass == NULL) {
+ // pending exception...
+ return JNI_ERR;
+ }
+ runtimeExceptionClass = (jclass) (*env)->NewGlobalRef(env, localRuntimeExceptionClass);
+ if (runtimeExceptionClass == NULL) {
+ // out-of-memory!
+ throwOutOfMemoryError(env);
+ return JNI_ERR;
+ }
+
+ jclass localIoExceptionClass = (*env)->FindClass(env, "java/io/IOException");
+ if (localIoExceptionClass == NULL) {
+ // pending exception...
+ return JNI_ERR;
+ }
+ ioExceptionClass = (jclass) (*env)->NewGlobalRef(env, localIoExceptionClass);
+ if (ioExceptionClass == NULL) {
+ // out-of-memory!
+ throwOutOfMemoryError(env);
+ return JNI_ERR;
+ }
+
+ submitClass = (*env)->FindClass(env, "org/apache/activemq/artemis/jlibaio/SubmitInfo");
+ if (submitClass == NULL) {
+ return JNI_ERR;
+ }
+
+ submitClass = (jclass)(*env)->NewGlobalRef(env, (jobject)submitClass);
+
+ errorMethod = (*env)->GetMethodID(env, submitClass, "onError", "(ILjava/lang/String;)V");
+ if (errorMethod == NULL) {
+ return JNI_ERR;
+ }
+ errorMethod = (jmethodID)(*env)->NewGlobalRef(env, (jobject)(errorMethod));
+
+ doneMethod = (*env)->GetMethodID(env, submitClass, "done", "()V");
+ if (doneMethod == NULL) {
+ return JNI_ERR;
+ }
+ doneMethod = (jmethodID)(*env)->NewGlobalRef(env, (jobject)(doneMethod));
+
+ libaioContextClass = (*env)->FindClass(env, "org/apache/activemq/artemis/jlibaio/LibaioContext");
+ if (libaioContextClass == NULL) {
+ return JNI_ERR;
+ }
+ libaioContextClass = (jclass)(*env)->NewGlobalRef(env, (jobject)libaioContextClass);
+
+ libaioContextDone = (*env)->GetMethodID(env, libaioContextClass, "done", "(Lorg/apache/activemq/artemis/jlibaio/SubmitInfo;)V");
+ if (libaioContextDone == NULL) {
+ return JNI_ERR;
+ }
+ libaioContextDone = (jmethodID)(*env)->NewGlobalRef(env, (jobject)libaioContextDone);
+
+ return JNI_VERSION_1_6;
+ }
+}
+
+void JNI_OnUnload(JavaVM* vm, void* reserved) {
+ JNIEnv* env;
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
+ // Something is wrong but nothing we can do about this :(
+ return;
+ } else {
+ // delete global references so the GC can collect them
+ if (runtimeExceptionClass != NULL) {
+ (*env)->DeleteGlobalRef(env, runtimeExceptionClass);
+ }
+ if (ioExceptionClass != NULL) {
+ (*env)->DeleteGlobalRef(env, ioExceptionClass);
+ }
+
+ // Deleting global refs so their classes can be GCed
+ if (errorMethod != NULL) {
+ (*env)->DeleteGlobalRef(env, (jobject)errorMethod);
+ }
+
+ if (doneMethod != NULL) {
+ (*env)->DeleteGlobalRef(env, (jobject)doneMethod);
+ }
+
+ if (submitClass != NULL) {
+ (*env)->DeleteGlobalRef(env, (jobject)submitClass);
+ }
+
+ if (libaioContextClass != NULL) {
+ (*env)->DeleteGlobalRef(env, (jobject)libaioContextClass);
+ }
+
+ if (libaioContextDone != NULL) {
+ (*env)->DeleteGlobalRef(env, (jobject)libaioContextDone);
+ }
+ }
+}
+
+static inline struct io_control * getIOControl(JNIEnv* env, jobject pointer) {
+ struct io_control * ioControl = (struct io_control *) (*env)->GetDirectBufferAddress(env, pointer);
+ if (ioControl == NULL) {
+ throwRuntimeException(env, "Controller not initialized");
+ }
+ return ioControl;
+}
+
+/**
+ * remove an iocb from the pool of IOCBs. Returns null if full
+ */
+static inline struct iocb * getIOCB(struct io_control * control) {
+ struct iocb * iocb = 0;
+
+ pthread_mutex_lock(&(control->iocbLock));
+
+ #ifdef DEBUG
+ fprintf (stdout, "getIOCB::used=%d, queueSize=%d, get=%d, put=%d\n", control->used, control->queueSize, control->iocbGet, control->iocbPut);
+ #endif
+
+ if (control->used < control->queueSize) {
+ control->used++;
+ iocb = control->iocb[control->iocbGet++];
+
+ if (control->iocbGet >= control->queueSize) {
+ control->iocbGet = 0;
+ }
+ }
+
+ pthread_mutex_unlock(&(control->iocbLock));
+ return iocb;
+}
+
+/**
+ * Put an iocb back on the pool of IOCBs
+ */
+static inline void putIOCB(struct io_control * control, struct iocb * iocbBack) {
+ pthread_mutex_lock(&(control->iocbLock));
+
+ #ifdef DEBUG
+ fprintf (stdout, "putIOCB::used=%d, queueSize=%d, get=%d, put=%d\n", control->used, control->queueSize, control->iocbGet, control->iocbPut);
+ #endif
+
+ control->used--;
+ control->iocb[control->iocbPut++] = iocbBack;
+ if (control->iocbPut >= control->queueSize) {
+ control->iocbPut = 0;
+ }
+ pthread_mutex_unlock(&(control->iocbLock));
+}
+
+static inline void * getBuffer(JNIEnv* env, jobject pointer) {
+ return (*env)->GetDirectBufferAddress(env, pointer);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_lock
+ (JNIEnv * env, jclass clazz, jint handle) {
+ return flock(handle, LOCK_EX | LOCK_NB) == 0;
+}
+
+/**
+ * Everything that is allocated here will be freed at deleteContext when the class is unloaded.
+ */
+JNIEXPORT jobject JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_newContext(JNIEnv* env, jobject thisObject, jint queueSize) {
+ io_context_t libaioContext;
+ int i = 0;
+
+ #ifdef DEBUG
+ fprintf (stdout, "Initializing context\n");
+ #endif
+
+ int res = io_queue_init(queueSize, &libaioContext);
+ if (res) {
+ // Error, so need to release whatever was done before
+ free(libaioContext);
+
+ throwRuntimeExceptionErrorNo(env, "Cannot initialize queue:", res);
+ return NULL;
+ }
+
+ struct iocb ** iocb = (struct iocb **)malloc((sizeof(struct iocb *) * (size_t)queueSize));
+ if (iocb == NULL) {
+ throwOutOfMemoryError(env);
+ return NULL;
+ }
+
+ for (i = 0; i < queueSize; i++) {
+ iocb[i] = (struct iocb *)malloc(sizeof(struct iocb));
+ if (iocb[i] == NULL) {
+ // it's unlikely this would happen at this point
+ // for that reason I'm not cleaning up individual IOCBs here
+ // we could increase support here with a cleanup of any previously allocated iocb
+ // But I'm afraid of adding not needed complexity here
+ throwOutOfMemoryError(env);
+ return NULL;
+ }
+ }
+
+ struct io_control * theControl = (struct io_control *) malloc(sizeof(struct io_control));
+ if (theControl == NULL) {
+ throwOutOfMemoryError(env);
+ return NULL;
+ }
+
+ res = pthread_mutex_init(&(theControl->iocbLock), 0);
+ if (res) {
+ free(theControl);
+ free(libaioContext);
+ throwRuntimeExceptionErrorNo(env, "Can't initialize mutext:", res);
+ return NULL;
+ }
+
+ res = pthread_mutex_init(&(theControl->pollLock), 0);
+ if (res) {
+ free(theControl);
+ free(libaioContext);
+ throwRuntimeExceptionErrorNo(env, "Can't initialize mutext:", res);
+ return NULL;
+ }
+
+ struct io_event * events = (struct io_event *)malloc(sizeof(struct io_event) * (size_t)queueSize);
+
+ theControl->ioContext = libaioContext;
+ theControl->events = events;
+ theControl->iocb = iocb;
+ theControl->queueSize = queueSize;
+ theControl->iocbPut = 0;
+ theControl->iocbGet = 0;
+ theControl->used = 0;
+ theControl->thisObject = (*env)->NewGlobalRef(env, thisObject);
+
+ return (*env)->NewDirectByteBuffer(env, theControl, sizeof(struct io_control));
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_deleteContext(JNIEnv* env, jclass clazz, jobject contextPointer) {
+ int i;
+ struct io_control * theControl = getIOControl(env, contextPointer);
+ if (theControl == NULL) {
+ return;
+ }
+
+ io_queue_release(theControl->ioContext);
+
+ // to make sure the poll has finished
+ pthread_mutex_lock(&(theControl->pollLock));
+ pthread_mutex_unlock(&(theControl->pollLock));
+
+ pthread_mutex_destroy(&(theControl->pollLock));
+ pthread_mutex_destroy(&(theControl->iocbLock));
+
+ // Releasing each individual iocb
+ for (i = 0; i < theControl->queueSize; i++) {
+ free(theControl->iocb[i]);
+ }
+
+ (*env)->DeleteGlobalRef(env, theControl->thisObject);
+
+ free(theControl->iocb);
+ free(theControl->events);
+ free(theControl);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_close(JNIEnv* env, jclass clazz, jint fd) {
+ if (close(fd) < 0) {
+ throwIOExceptionErrorNo(env, "Error closing file:", errno);
+ }
+}
+
+JNIEXPORT int JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_open(JNIEnv* env, jclass clazz,
+ jstring path, jboolean direct) {
+ const char* f_path = (*env)->GetStringUTFChars(env, path, 0);
+
+ int res;
+ if (direct) {
+ res = open(f_path, O_RDWR | O_CREAT | O_DIRECT, 0666);
+ } else {
+ res = open(f_path, O_RDWR | O_CREAT, 0666);
+ }
+
+ (*env)->ReleaseStringUTFChars(env, path, f_path);
+
+ if (res < 0) {
+ throwIOExceptionErrorNo(env, "Cannot open file:", errno);
+ }
+
+ return res;
+}
+
+static inline void submit(JNIEnv * env, struct io_control * theControl, struct iocb * iocb) {
+ int result = io_submit(theControl->ioContext, 1, &iocb);
+
+ if (result < 0) {
+ // Putting the Global Ref and IOCB back in case of a failure
+ (*env)->DeleteGlobalRef(env, (jobject)iocb->data);
+ putIOCB(theControl, iocb);
+
+ throwIOExceptionErrorNo(env, "Error while submitting IO: ", -result);
+ }
+
+ return;
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_submitWrite
+ (JNIEnv * env, jclass clazz, jint fileHandle, jobject contextPointer, jlong position, jint size, jobject bufferWrite, jobject callback) {
+ struct io_control * theControl = getIOControl(env, contextPointer);
+ if (theControl == NULL) {
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf (stdout, "submitWrite position %ld, size %d\n", position, size);
+ #endif
+
+ struct iocb * iocb = getIOCB(theControl);
+
+ if (iocb == NULL) {
+ throwIOException(env, "Not enough space in libaio queue");
+ return;
+ }
+
+ io_prep_pwrite(iocb, fileHandle, getBuffer(env, bufferWrite), (size_t)size, position);
+
+ // The GlobalRef will be deleted when poll is called. this is done so
+ // the vm wouldn't crash if the Callback passed by the user is GCed between submission
+ // and callback.
+ // also as the real intention is to hold the reference until the life cycle is complete
+ iocb->data = (void *) (*env)->NewGlobalRef(env, callback);
+
+ return submit(env, theControl, iocb);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_submitRead
+ (JNIEnv * env, jclass clazz, jint fileHandle, jobject contextPointer, jlong position, jint size, jobject bufferRead, jobject callback) {
+ struct io_control * theControl = getIOControl(env, contextPointer);
+ if (theControl == NULL) {
+ return;
+ }
+
+ struct iocb * iocb = getIOCB(theControl);
+
+ if (iocb == NULL) {
+ throwIOException(env, "Not enough space in libaio queue");
+ return;
+ }
+
+ io_prep_pread(iocb, fileHandle, getBuffer(env, bufferRead), (size_t)size, position);
+
+ // The GlobalRef will be deleted when poll is called. this is done so
+ // the vm wouldn't crash if the Callback passed by the user is GCed between submission
+ // and callback.
+ // also as the real intention is to hold the reference until the life cycle is complete
+ iocb->data = (void *) (*env)->NewGlobalRef(env, callback);
+
+ return submit(env, theControl, iocb);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_blockedPoll
+ (JNIEnv * env, jobject thisObject, jobject contextPointer) {
+
+ #ifdef DEBUG
+ fprintf (stdout, "Running blockedPoll");
+ #endif
+
+ int i;
+ struct io_control * theControl = getIOControl(env, contextPointer);
+ if (theControl == NULL) {
+ return;
+ }
+ int max = theControl->queueSize;
+ pthread_mutex_lock(&(theControl->pollLock));
+
+ for (;;) {
+
+ int result = io_getevents(theControl->ioContext, 1, max, theControl->events, 0);
+
+ if (result < 0)
+ {
+ #ifdef DEBUG
+ fprintf (stdout, "finished blockedPoll rutine with result=%d\n", result);
+ #endif
+ break;
+ }
+ #ifdef DEBUG
+ fprintf (stdout, "blockedPoll returned %d events\n", result);
+ #endif
+
+ for (i = 0; i < result; i++)
+ {
+ #ifdef DEBUG
+ fprintf (stdout, "blockedPoll treading event %d\n", i);
+ #endif
+ struct io_event * event = &(theControl->events[i]);
+ struct iocb * iocbp = event->obj;
+ int eventResult = (int)event->res;
+
+ #ifdef DEBUG
+ fprintf (stdout, "Poll res: %d totalRes=%d\n", eventResult, result);
+ #endif
+
+ if (eventResult < 0) {
+ #ifdef DEBUG
+ fprintf (stdout, "Error: %s\n", strerror(-eventResult));
+ #endif
+
+ jstring jstrError = (*env)->NewStringUTF(env, strerror(-eventResult));
+
+ if (iocbp->data != NULL) {
+ (*env)->CallVoidMethod(env, (jobject)(iocbp->data), errorMethod, (jint)(-eventResult), jstrError);
+ }
+ }
+
+ jobject obj = (jobject)iocbp->data;
+ putIOCB(theControl, iocbp);
+
+ if (obj != NULL) {
+ (*env)->CallVoidMethod(env, theControl->thisObject, libaioContextDone,obj);
+ // We delete the globalRef after the completion of the callback
+ (*env)->DeleteGlobalRef(env, obj);
+ }
+
+ }
+ }
+
+ pthread_mutex_unlock(&(theControl->pollLock));
+
+}
+
+JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_poll
+ (JNIEnv * env, jobject obj, jobject contextPointer, jobjectArray callbacks, jint min, jint max) {
+ int i = 0;
+ struct io_control * theControl = getIOControl(env, contextPointer);
+ if (theControl == NULL) {
+ return 0;
+ }
+
+
+ int result = io_getevents(theControl->ioContext, min, max, theControl->events, 0);
+ int retVal = result;
+
+ for (i = 0; i < result; i++) {
+ struct io_event * event = &(theControl->events[i]);
+ struct iocb * iocbp = event->obj;
+ int eventResult = (int)event->res;
+
+ #ifdef DEBUG
+ fprintf (stdout, "Poll res: %d totalRes=%d\n", eventResult, result);
+ #endif
+
+ if (eventResult < 0) {
+ #ifdef DEBUG
+ fprintf (stdout, "Error: %s\n", strerror(-eventResult));
+ #endif
+
+ jstring jstrError = (*env)->NewStringUTF(env, strerror(-eventResult));
+
+ (*env)->CallVoidMethod(env, (jobject)(iocbp->data), errorMethod, (jint)(-eventResult), jstrError);
+ }
+
+ (*env)->SetObjectArrayElement(env, callbacks, i, (jobject)iocbp->data);
+
+ if (iocbp->data != NULL) {
+ // We delete the globalRef after the completion of the callback
+ (*env)->DeleteGlobalRef(env, (jobject)iocbp->data);
+ }
+
+ putIOCB(theControl, iocbp);
+ }
+
+ return retVal;
+}
+
+JNIEXPORT jobject JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_newAlignedBuffer
+(JNIEnv * env, jclass clazz, jint size, jint alignment) {
+ if (size % alignment != 0) {
+ throwRuntimeException(env, "Buffer size needs to be aligned to passed argument");
+ return NULL;
+ }
+
+ // This will allocate a buffer, aligned by alignment.
+ // Buffers created here need to be manually destroyed by destroyBuffer, or this would leak on the process heap away of Java's GC managed memory
+ // NOTE: this buffer will contain non initialized data, you must fill it up properly
+ void * buffer;
+ int result = posix_memalign(&buffer, (size_t)alignment, (size_t)size);
+
+ if (result) {
+ throwRuntimeExceptionErrorNo(env, "Can't allocate posix buffer:", result);
+ return NULL;
+ }
+
+ memset(buffer, 0, (size_t)size);
+
+ return (*env)->NewDirectByteBuffer(env, buffer, size);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_freeBuffer
+ (JNIEnv * env, jclass clazz, jobject jbuffer) {
+ if (jbuffer == NULL)
+ {
+ throwRuntimeException(env, "Null pointer");
+ return;
+ }
+ void * buffer = (*env)->GetDirectBufferAddress(env, jbuffer);
+ free(buffer);
+}
+
+
+/** It does nothing... just return true to make sure it has all the binary dependencies */
+JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_getNativeVersion
+ (JNIEnv * env, jclass clazz)
+
+{
+ return org_apache_activemq_artemis_jlibaio_LibaioContext_EXPECTED_NATIVE_VERSION;
+}
+
+JNIEXPORT jlong JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_getSize
+ (JNIEnv * env, jclass clazz, jint fd)
+{
+ struct stat statBuffer;
+
+ if (fstat(fd, &statBuffer) < 0)
+ {
+ throwIOExceptionErrorNo(env, "Cannot determine file size:", errno);
+ return -1l;
+ }
+ return statBuffer.st_size;
+}
+
+JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_getBlockSizeFD
+ (JNIEnv * env, jclass clazz, jint fd)
+{
+ struct stat statBuffer;
+
+ if (fstat(fd, &statBuffer) < 0)
+ {
+ throwIOExceptionErrorNo(env, "Cannot determine file size:", errno);
+ return -1l;
+ }
+ return statBuffer.st_blksize;
+}
+
+JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_getBlockSize
+ (JNIEnv * env, jclass clazz, jstring path)
+{
+ const char* f_path = (*env)->GetStringUTFChars(env, path, 0);
+ struct stat statBuffer;
+
+ if (stat(f_path, &statBuffer) < 0)
+ {
+ throwIOExceptionErrorNo(env, "Cannot determine file size:", errno);
+ return -1l;
+ }
+
+ (*env)->ReleaseStringUTFChars(env, path, f_path);
+
+ return statBuffer.st_blksize;
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_fallocate
+ (JNIEnv * env, jclass clazz, jint fd, jlong size)
+{
+ if (fallocate(fd, 0, 0, (off_t) size) < 0)
+ {
+ throwIOExceptionErrorNo(env, "Could not preallocate file", errno);
+ }
+ fsync(fd);
+ lseek (fd, 0, SEEK_SET);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_fill
+ (JNIEnv * env, jclass clazz, jint fd, jlong size)
+{
+ void * preAllocBuffer = 0;
+ if (posix_memalign(&preAllocBuffer, 512, size) != 0)
+ {
+ throwOutOfMemoryError(env);
+ return;
+ }
+ memset(preAllocBuffer, 0, size);
+ lseek (fd, 0, SEEK_SET);
+ write(fd, preAllocBuffer, size);
+ lseek (fd, 0, SEEK_SET);
+ free (preAllocBuffer);
+}
+
+JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_memsetBuffer
+ (JNIEnv *env, jclass clazz, jobject jbuffer, jint size)
+{
+ #ifdef DEBUG
+ fprintf (stdout, "Mem setting buffer with %d bytes\n", size);
+ #endif
+ void * buffer = (*env)->GetDirectBufferAddress(env, jbuffer);
+
+ if (buffer == 0)
+ {
+ throwRuntimeException(env, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
+ return;
+ }
+
+ memset(buffer, 0, (size_t)size);
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/core/libaio/Native.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/core/libaio/Native.java b/artemis-native/src/main/java/org/apache/activemq/artemis/core/libaio/Native.java
deleted file mode 100644
index 51f5da7..0000000
--- a/artemis-native/src/main/java/org/apache/activemq/artemis/core/libaio/Native.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.core.libaio;
-
-import java.nio.ByteBuffer;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-
-public class Native
-{
- // Functions used for locking files .....
- public static native int openFile(String fileName);
-
- public static native void closeFile(int handle);
-
- public static native boolean flock(int handle);
- // Functions used for locking files ^^^^^^^^
-
- public static native void resetBuffer(ByteBuffer directByteBuffer, int size);
-
- public static native void destroyBuffer(ByteBuffer buffer);
-
- public static native ByteBuffer newNativeBuffer(long size);
-
- public static native void newInit(Class someClass);
-
- public static native ByteBuffer init(Class controllerClass, String fileName, int maxIO, Object logger) throws ActiveMQException;
-
- public static native long size0(ByteBuffer handle);
-
- public static native void write(Object thisObject, ByteBuffer handle,
- long sequence,
- long position,
- long size,
- ByteBuffer buffer,
- Object aioPackageCallback) throws ActiveMQException;
-
- /** a direct write to the file without the use of libaio's submit. */
- public static native void writeInternal(ByteBuffer handle, long positionToWrite, long size, ByteBuffer bytes) throws ActiveMQException;
-
- /**
- *This is using org.apache.activemq.artemis.core.asyncio.AIOCallback
- */
- public static native void read(Object thisObject, ByteBuffer handle, long position, long size, ByteBuffer buffer, Object aioPackageCallback) throws ActiveMQException;
-
- public static native void fill(ByteBuffer handle, long position, int blocks, long size, byte fillChar) throws ActiveMQException;
-
- public static native void closeInternal(ByteBuffer handler);
-
- public static native void stopPoller(ByteBuffer handler);
-
- /** A native method that does nothing, and just validate if the ELF dependencies are loaded and on the correct platform as this binary format */
- public static native int getNativeVersion();
-
- /** Poll asynchronous events from internal queues */
- public static native void internalPollEvents(ByteBuffer handler);
-
- // Inner classes ---------------------------------------------------------------------
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java
new file mode 100644
index 0000000..8b45f54
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java
@@ -0,0 +1,446 @@
+/*
+ * 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.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static io.netty.util.internal.ObjectUtil.checkNotNull;
+
+/**
+ * This class is used as an aggregator for the {@link LibaioFile}.
+ * <br>
+ * It holds native data, and it will share a libaio queue that can be used by multiple files.
+ * <br>
+ * You need to use the poll methods to read the result of write and read submissions.
+ * <br>
+ * You also need to use the special buffer created by {@link LibaioFile} as you need special alignments
+ * when dealing with O_DIRECT files.
+ * <br>
+ * A Single controller can server multiple files. There's no need to create one controller per file.
+ * <br>
+ * <a href="https://ext4.wiki.kernel.org/index.php/Clarifying_Direct_IO's_Semantics">Interesting reading for this.</a>
+ */
+public class LibaioContext <Callback extends SubmitInfo> implements Closeable
+{
+
+ private static final AtomicLong totalMaxIO = new AtomicLong(0);
+
+ /**
+ * This definition needs to match Version.h on the native sources.
+ * <br>
+ * Or else the native module won't be loaded because of version mismatches
+ */
+ private static final int EXPECTED_NATIVE_VERSION = 1;
+
+ private static boolean loaded = false;
+
+ public static boolean isLoaded()
+ {
+ return loaded;
+ }
+
+ private static boolean loadLibrary(final String name)
+ {
+ try
+ {
+ System.loadLibrary(name);
+ if (getNativeVersion() != EXPECTED_NATIVE_VERSION)
+ {
+ NativeLogger.LOGGER.incompatibleNativeLibrary();
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ catch (Throwable e)
+ {
+ NativeLogger.LOGGER.debug(name + " -> error loading the native library", e);
+ return false;
+ }
+
+ }
+
+ static
+ {
+ String[] libraries = new String[]{"artemis-native-64", "artemis-native-32"};
+
+ for (String library : libraries)
+ {
+ if (loadLibrary(library))
+ {
+ loaded = true;
+ break;
+ }
+ else
+ {
+ NativeLogger.LOGGER.debug("Library " + library + " not found!");
+ }
+ }
+
+ if (!loaded)
+ {
+ NativeLogger.LOGGER.debug("Couldn't locate LibAIO Wrapper");
+ }
+ }
+
+ /**
+ * This is used to validate leaks on tests.
+ * @return the number of allocated aio, to be used on test checks.
+ */
+ public static long getTotalMaxIO()
+ {
+ return totalMaxIO.get();
+ }
+
+ /**
+ * It will reset all the positions on the buffer to 0, using memset.
+ * @param buffer a native buffer.
+s */
+ public void memsetBuffer(ByteBuffer buffer)
+ {
+ memsetBuffer(buffer, buffer.limit());
+ }
+
+ /**
+ * This is used on tests validating for leaks.
+ */
+ public static void resetMaxAIO()
+ {
+ totalMaxIO.set(0);
+ }
+
+ /**
+ * the native ioContext including the structure created.
+ */
+ private final ByteBuffer ioContext;
+
+ private final AtomicBoolean closed = new AtomicBoolean(false);
+
+ final Semaphore ioSpace;
+
+ final int queueSize;
+
+ /**
+ * The queue size here will use resources defined on the kernel parameter
+ * <a href="https://www.kernel.org/doc/Documentation/sysctl/fs.txt">fs.aio-max-nr</a> .
+ *
+ * @param queueSize the size to be initialize on libaio
+ * io_queue_init which can't be higher than /proc/sys/fs/aio-max-nr.
+ * @param useSemaphore should block on a semaphore avoiding using more submits than what's available.
+ */
+ public LibaioContext(int queueSize, boolean useSemaphore)
+ {
+ try
+ {
+ this.ioContext = newContext(queueSize);
+ }
+ catch (Exception e)
+ {
+ throw e;
+ }
+ this.queueSize = queueSize;
+ totalMaxIO.addAndGet(queueSize);
+ if (useSemaphore)
+ {
+ this.ioSpace = new Semaphore(queueSize);
+ }
+ else
+ {
+ this.ioSpace = null;
+ }
+ }
+
+
+ /**
+ * Documented at {@link LibaioFile#write(long, int, java.nio.ByteBuffer, SubmitInfo)}
+ * @param fd the file descriptor
+ * @param position the write position
+ * @param size number of bytes to use
+ * @param bufferWrite the native buffer
+ * @param callback a callback
+ * @throws IOException in case of error
+ */
+ public void submitWrite(int fd,long position, int size,
+ ByteBuffer bufferWrite, Callback callback) throws IOException
+ {
+ try
+ {
+ if (ioSpace != null)
+ {
+ ioSpace.acquire();
+ }
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ throw new IOException(e.getMessage(), e);
+ }
+ submitWrite(fd, this.ioContext, position, size, bufferWrite, callback);
+ }
+
+ public void submitRead(int fd, long position, int size, ByteBuffer bufferWrite,
+ Callback callback) throws IOException
+ {
+ try
+ {
+ if (ioSpace != null)
+ {
+ ioSpace.acquire();
+ }
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ throw new IOException(e.getMessage(), e);
+ }
+ submitRead(fd, this.ioContext, position, size, bufferWrite, callback);
+ }
+
+
+ /**
+ * This is used to close the libaio queues and cleanup the native data used.
+ * <br>
+ * It is unsafe to close the controller while you have pending writes or files open as
+ * this could cause core dumps or VM crashes.
+ */
+ @Override
+ public void close()
+ {
+ if (!closed.getAndSet(true))
+ {
+ totalMaxIO.addAndGet(-queueSize);
+
+ if (ioContext != null)
+ {
+ deleteContext(ioContext);
+ }
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable
+ {
+ super.finalize();
+ close();
+ }
+
+ /**
+ * It will open a file. If you set the direct flag = false then you won't need to use the special buffer.
+ * Notice: This will create an empty file if the file doesn't already exist.
+ *
+ * @param file the file to be open.
+ * @param direct will set ODIRECT.
+ * @return It will return a LibaioFile instance.
+ * @throws IOException in case of error.
+ */
+ public LibaioFile<Callback> openFile(File file, boolean direct) throws IOException
+ {
+ return openFile(file.getPath(), direct);
+ }
+
+ /**
+ * It will open a file. If you set the direct flag = false then you won't need to use the special buffer.
+ * Notice: This will create an empty file if the file doesn't already exist.
+ *
+ * @param file the file to be open.
+ * @param direct should use O_DIRECT when opening the file.
+ * @return a new open file.
+ * @throws IOException in case of error.
+ */
+ public LibaioFile<Callback> openFile(String file, boolean direct) throws IOException
+ {
+ checkNotNull(file, "path");
+ checkNotNull(ioContext, "IOContext");
+
+ // note: the native layer will throw an IOException in case of errors
+ int res = LibaioContext.open(file, direct);
+
+ return new LibaioFile<>(res, this);
+ }
+
+ /**
+ * It will open a file disassociated with any sort of factory.
+ * This is useful when you won't use reading / writing through libaio like locking files.
+ * @param file a file name
+ * @param direct will use O_DIRECT
+ * @return a new file
+ * @throws IOException in case of error.
+ */
+ public static LibaioFile openControlFile(String file, boolean direct) throws IOException
+ {
+ checkNotNull(file, "path");
+
+ // note: the native layer will throw an IOException in case of errors
+ int res = LibaioContext.open(file, direct);
+
+ return new LibaioFile<>(res, null);
+ }
+
+ /**
+ * It will poll the libaio queue for results. It should block until min is reached
+ * Results are placed on the callback.
+ * <br>
+ * This shouldn't be called concurrently. You should provide your own synchronization if you need more than one
+ * Thread polling for any reason.
+ * <br>
+ * Notice that the native layer will invoke {@link SubmitInfo#onError(int, String)} in case of failures,
+ * but it won't call done method for you.
+ *
+ * @param callbacks area to receive the callbacks passed on submission.The size of this callback has to
+ * be greater than the parameter max.
+ * @param min the minimum number of elements to receive. It will block until this is achieved.
+ * @param max The maximum number of elements to receive.
+ * @return Number of callbacks returned.
+ * @see LibaioFile#write(long, int, java.nio.ByteBuffer, SubmitInfo)
+ * @see LibaioFile#read(long, int, java.nio.ByteBuffer, SubmitInfo)
+ */
+ public int poll(Callback[] callbacks, int min, int max)
+ {
+ int released = poll(ioContext, callbacks, min, max);
+ if (ioSpace != null)
+ {
+ if (released > 0)
+ {
+ ioSpace.release(released);
+ }
+ }
+ return released;
+ }
+
+ /**
+ * It will start polling and will keep doing until the context is closed.
+ * This will call callbacks on {@link SubmitInfo#onError(int, String)} and
+ * {@link SubmitInfo#done()}.
+ * In case of error, both {@link SubmitInfo#onError(int, String)} and
+ * {@link SubmitInfo#done()} are called.
+ */
+ public void poll()
+ {
+ blockedPoll(ioContext);
+ }
+
+ /** Called from the native layer */
+ private void done(SubmitInfo info)
+ {
+ if (ioSpace != null)
+ {
+ ioSpace.release();
+ }
+ info.done();
+ }
+
+ /**
+ * This is the queue for libaio, initialized with queueSize.
+ */
+ private native ByteBuffer newContext(int queueSize);
+
+ /**
+ * Internal method to be used when closing the controller.
+ */
+ private native void deleteContext(ByteBuffer buffer);
+
+ /**
+ * it will return a file descriptor.
+ *
+ * @param path the file name.
+ * @param direct translates as O_DIRECT On open
+ * @return a fd from open C call.
+ */
+ public static native int open(String path, boolean direct);
+
+ static native void close(int fd);
+
+ /**
+ */
+
+ /**
+ * Buffers for O_DIRECT need to use posix_memalign.
+ * <br>
+ * Documented at {@link LibaioFile#newBuffer(int)}.
+ *
+ * @param size needs to be % alignment
+ * @param alignment the alignment used at the dispositive
+ * @return a new native buffer used with posix_memalign
+ */
+ public static native ByteBuffer newAlignedBuffer(int size, int alignment);
+
+ /**
+ * This will call posix free to release the inner buffer allocated at {@link #newAlignedBuffer(int, int)}.
+ * @param buffer a native buffer allocated with {@link #newAlignedBuffer(int, int)}.
+ */
+ public static native void freeBuffer(ByteBuffer buffer);
+
+ /**
+ * Documented at {@link LibaioFile#write(long, int, java.nio.ByteBuffer, SubmitInfo)}.
+ */
+ native void submitWrite(int fd,
+ ByteBuffer libaioContext,
+ long position, int size, ByteBuffer bufferWrite,
+ Callback callback) throws IOException;
+
+ /**
+ * Documented at {@link LibaioFile#read(long, int, java.nio.ByteBuffer, SubmitInfo)}.
+ */
+ native void submitRead(int fd,
+ ByteBuffer libaioContext,
+ long position, int size, ByteBuffer bufferWrite,
+ Callback callback) throws IOException;
+
+ /**
+ * Note: this shouldn't be done concurrently.
+ * This method will block until the min condition is satisfied on the poll.
+ * <p/>
+ * The callbacks will include the original callback sent at submit (read or write).
+ */
+ native int poll(ByteBuffer libaioContext, Callback[] callbacks, int min, int max);
+
+ /**
+ * This method will block as long as the context is open.
+ */
+ native void blockedPoll(ByteBuffer libaioContext);
+
+ static native int getNativeVersion();
+
+ public static native boolean lock(int fd);
+
+ public static native void memsetBuffer(ByteBuffer buffer, int size);
+
+ static native long getSize(int fd);
+
+ static native int getBlockSizeFD(int fd);
+
+ public static int getBlockSize(File path)
+ {
+ return getBlockSize(path.getAbsolutePath());
+ }
+
+ public static native int getBlockSize(String path);
+
+ static native void fallocate(int fd, long size);
+
+ static native void fill(int fd, long size);
+
+ static native void writeInternal(int fd, long position, long size, ByteBuffer bufferWrite) throws IOException;
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioFile.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioFile.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioFile.java
new file mode 100644
index 0000000..bf88d65
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioFile.java
@@ -0,0 +1,152 @@
+/*
+ * 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>
+{
+ 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);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ 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);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/NativeLogger.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/NativeLogger.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/NativeLogger.java
new file mode 100644
index 0000000..449c168
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/NativeLogger.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.jboss.logging.BasicLogger;
+import org.jboss.logging.Logger;
+import org.jboss.logging.annotations.LogMessage;
+import org.jboss.logging.annotations.Message;
+import org.jboss.logging.annotations.MessageLogger;
+
+/**
+ * Logger Code 14
+ *
+ * each message id must be 6 digits long starting with 14, the 3rd digit donates the level so
+ *
+ * INF0 1
+ * WARN 2
+ * DEBUG 3
+ * ERROR 4
+ * TRACE 5
+ * FATAL 6
+ *
+ * so an INFO message would be 1000 to 6000
+ */
+@MessageLogger(projectCode = "jlibaio")
+public interface NativeLogger extends BasicLogger
+{
+ /**
+ * The journal logger.
+ */
+ NativeLogger LOGGER = Logger.getMessageLogger(NativeLogger.class, NativeLogger.class.getPackage().getName());
+
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 1001, value = "You have a native library with a different version than expected", format = Message.Format.MESSAGE_FORMAT)
+ void incompatibleNativeLibrary();
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/SubmitInfo.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/SubmitInfo.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/SubmitInfo.java
new file mode 100644
index 0000000..47feea8
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/SubmitInfo.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+public interface SubmitInfo
+{
+ void onError(int errno, String message);
+
+ void done();
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/package-info.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/package-info.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/package-info.java
new file mode 100644
index 0000000..341fa1c
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/**
+ * This packages handles Linux libaio at a low level.
+ * <br>
+ * Buffers needs to be specially allocated by {@link org.apache.activemq.artemis.jlibaio.LibaioContext#newAlignedBuffer(int, int)}
+ * as they need to be aligned to 512 or 4096 when using Direct files.
+ */
+package org.apache.activemq.artemis.jlibaio;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/util/CallbackCache.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/util/CallbackCache.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/util/CallbackCache.java
new file mode 100644
index 0000000..ec2a630
--- /dev/null
+++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/util/CallbackCache.java
@@ -0,0 +1,93 @@
+/**
+ * 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.util;
+
+
+import org.apache.activemq.artemis.jlibaio.SubmitInfo;
+
+/**
+ * this is an utility class where you can reuse Callbackk objects for your LibaioContext usage.
+ */
+public class CallbackCache<Callback extends SubmitInfo>
+{
+ private final SubmitInfo[] pool;
+
+ private int put = 0;
+ private int get = 0;
+ private int available = 0;
+ private final int size;
+
+ private final Object lock = new Object();
+
+ public CallbackCache(int size)
+ {
+ this.pool = new SubmitInfo[size];
+ this.size = size;
+ }
+
+ public Callback get()
+ {
+ synchronized (lock)
+ {
+ if (available <= 0)
+ {
+ return null;
+ }
+ else
+ {
+ Callback retValue = (Callback)pool[get];
+ pool[get] = null;
+ if (retValue == null)
+ {
+ throw new NullPointerException("You should initialize the pool before using it");
+ }
+ if (retValue != null)
+ {
+ available--;
+ get++;
+ if (get >= size)
+ {
+ get = 0;
+ }
+ }
+ return retValue;
+ }
+ }
+ }
+
+ public CallbackCache put(Callback callback)
+ {
+ if (callback == null)
+ {
+ return null;
+ }
+ synchronized (lock)
+ {
+ if (available < size)
+ {
+ available++;
+ pool[put++] = callback;
+ if (put >= size)
+ {
+ put = 0;
+ }
+ }
+ }
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/CallbackCachelTest.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/CallbackCachelTest.java b/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/CallbackCachelTest.java
new file mode 100644
index 0000000..f62f8e2
--- /dev/null
+++ b/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/CallbackCachelTest.java
@@ -0,0 +1,112 @@
+/**
+ * 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.test;
+
+import java.util.HashSet;
+
+import org.apache.activemq.artemis.jlibaio.util.CallbackCache;
+import org.apache.activemq.artemis.jlibaio.SubmitInfo;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CallbackCachelTest
+{
+ @Test
+ public void testPartiallyInitialized()
+ {
+ CallbackCache<MyPool> pool = new CallbackCache(100);
+
+
+ for (int i = 0; i < 50; i++)
+ {
+ pool.put(new MyPool(i));
+ }
+
+ MyPool value = pool.get();
+
+ Assert.assertNotNull(value);
+
+ pool.put(value);
+
+
+ // add and remove immediately
+ for (int i = 0; i < 777; i++)
+ {
+ pool.put(pool.get());
+ }
+
+
+ HashSet<MyPool> hashValues = new HashSet<>();
+
+
+ MyPool getValue;
+ while ((getValue = pool.get()) != null)
+ {
+ hashValues.add(getValue);
+ }
+
+
+ Assert.assertEquals(50, hashValues.size());
+ }
+
+ static class MyPool implements SubmitInfo
+ {
+ public final int i;
+
+ MyPool(int i)
+ {
+ this.i = i;
+ }
+
+
+ public int getI()
+ {
+ return i;
+ }
+
+ @Override
+ public void onError(int errno, String message)
+ {
+ }
+
+ @Override
+ public void done()
+ {
+
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ MyPool myPool = (MyPool) o;
+
+ if (i != myPool.i) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return i;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/LibaioTest.java
----------------------------------------------------------------------
diff --git a/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/LibaioTest.java b/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/LibaioTest.java
new file mode 100644
index 0000000..e46caf3
--- /dev/null
+++ b/artemis-native/src/test/java/org/apache/activemq/artemis/jlibaio/test/LibaioTest.java
@@ -0,0 +1,859 @@
+/*
+ * 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.test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
+import org.apache.activemq.artemis.jlibaio.SubmitInfo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * This test is using a different package from {@link LibaioFile}
+ * as I need to validate public methods on the API
+ */
+public class LibaioTest
+{
+
+ @BeforeClass
+ public static void testAIO()
+ {
+ Assume.assumeTrue(LibaioContext.isLoaded());
+ }
+
+ /** This is just an arbitrary number for a number of elements you need to pass to the libaio init method
+ * Some of the tests are using half of this number, so if anyone decide to change this please use an even number.
+ */
+ private static final int LIBAIO_QUEUE_SIZE = 50;
+
+ @Rule
+ public TemporaryFolder temporaryFolder;
+
+ public LibaioContext<TestInfo> control;
+
+ @Before
+ public void setUpFactory()
+ {
+ control = new LibaioContext<>(LIBAIO_QUEUE_SIZE, true);
+ }
+
+ @After
+ public void deleteFactory()
+ {
+ control.close();
+ validateLibaio();
+ }
+
+ public void validateLibaio()
+ {
+ Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
+ }
+
+ public LibaioTest()
+ {
+ /*
+ * I didn't use /tmp for three reasons
+ * - Most systems now will use tmpfs which is not compatible with O_DIRECT
+ * - This would fill up /tmp in case of failures.
+ * - target is cleaned up every time you do a mvn clean, so it's safer
+ */
+ File parent = new File("./target");
+ parent.mkdirs();
+ temporaryFolder = new TemporaryFolder(parent);
+ }
+
+ @Test
+ public void testOpen() throws Exception
+ {
+ LibaioFile fileDescriptor = control.openFile(temporaryFolder.newFile("test.bin"), true);
+ fileDescriptor.close();
+ }
+
+ @Test
+ public void testInitAndFallocate() throws Exception
+ {
+ LibaioFile fileDescriptor = control.openFile(temporaryFolder.newFile("test.bin"), true);
+ fileDescriptor.fallocate(1024 * 1024);
+
+ ByteBuffer buffer = fileDescriptor.newBuffer(1024 * 1024);
+ fileDescriptor.read(0, 1024 * 1024, buffer, new TestInfo());
+
+ TestInfo[] callbacks = new TestInfo[1];
+ control.poll(callbacks, 1, 1);
+
+ fileDescriptor.close();
+
+
+ buffer.position(0);
+
+ LibaioFile fileDescriptor2 = control.openFile(temporaryFolder.newFile("test2.bin"), true);
+ fileDescriptor2.fill(1024 * 1024);
+ fileDescriptor2.read(0, 1024 * 1024, buffer, new TestInfo());
+
+ control.poll(callbacks, 1, 1);
+ for (int i = 0; i < 1024 * 1024; i++)
+ {
+ Assert.assertEquals(0, buffer.get());
+ }
+
+ LibaioContext.freeBuffer(buffer);
+ }
+
+ @Test
+ public void testSubmitWriteOnTwoFiles() throws Exception
+ {
+
+ File file1 = temporaryFolder.newFile("test.bin");
+ File file2 = temporaryFolder.newFile("test2.bin");
+
+ fillupFile(file1, LIBAIO_QUEUE_SIZE / 2);
+ fillupFile(file2, LIBAIO_QUEUE_SIZE / 2);
+
+ LibaioFile[] fileDescriptor = new LibaioFile[]{control.openFile(file1, true),
+ control.openFile(file2, true)};
+
+ Assert.assertEquals((LIBAIO_QUEUE_SIZE / 2) * 512, fileDescriptor[0].getSize());
+ Assert.assertEquals((LIBAIO_QUEUE_SIZE / 2) * 512, fileDescriptor[1].getSize());
+ Assert.assertEquals(fileDescriptor[0].getBlockSize(), fileDescriptor[1].getBlockSize());
+ Assert.assertEquals(LibaioContext.getBlockSize(temporaryFolder.getRoot()), LibaioContext.getBlockSize(file1));
+ Assert.assertEquals(LibaioContext.getBlockSize(file1), LibaioContext.getBlockSize(file2));
+ System.out.println("blockSize = " + fileDescriptor[0].getBlockSize());
+ System.out.println("blockSize /tmp= " + LibaioContext.getBlockSize("/tmp"));
+
+ ByteBuffer buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+ try
+ {
+ for (int i = 0; i < 512; i++)
+ {
+ buffer.put((byte) 'a');
+ }
+
+ TestInfo callback = new TestInfo();
+ TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+ for (int i = 0; i < LIBAIO_QUEUE_SIZE / 2; i++)
+ {
+ for (LibaioFile file : fileDescriptor)
+ {
+ file.write(i * 512, 512, buffer, callback);
+ }
+ }
+
+ Assert.assertEquals(LIBAIO_QUEUE_SIZE, control.poll(callbacks, LIBAIO_QUEUE_SIZE, LIBAIO_QUEUE_SIZE));
+
+ for (Object returnedCallback : callbacks)
+ {
+ Assert.assertSame(returnedCallback, callback);
+ }
+
+ for (LibaioFile file : fileDescriptor)
+ {
+ ByteBuffer bigbuffer = LibaioContext.newAlignedBuffer(512 * 25, 512);
+ file.read(0, 512 * 25, bigbuffer, callback);
+ Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+ for (Object returnedCallback : callbacks)
+ {
+ Assert.assertSame(returnedCallback, callback);
+ }
+
+ for (int i = 0; i < 512 * 25; i++)
+ {
+ Assert.assertEquals((byte) 'a', bigbuffer.get());
+ }
+
+ LibaioContext.freeBuffer(bigbuffer);
+
+ file.close();
+ }
+ }
+ finally
+ {
+ LibaioContext.freeBuffer(buffer);
+ }
+ }
+
+ @Test
+ public void testSubmitWriteAndRead() throws Exception
+ {
+ TestInfo callback = new TestInfo();
+
+ TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+ LibaioFile fileDescriptor = control.openFile(temporaryFolder.newFile("test.bin"), true);
+
+ // ByteBuffer buffer = ByteBuffer.allocateDirect(512);
+ ByteBuffer buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+ try
+ {
+ for (int i = 0; i < 512; i++)
+ {
+ buffer.put((byte) 'a');
+ }
+
+ buffer.rewind();
+
+ fileDescriptor.write(0, 512, buffer, callback);
+
+ int retValue = control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE);
+ Assert.assertEquals(1, retValue);
+
+ Assert.assertSame(callback, callbacks[0]);
+
+ LibaioContext.freeBuffer(buffer);
+
+ buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+ for (int i = 0; i < 512; i++)
+ {
+ buffer.put((byte) 'B');
+ }
+
+ fileDescriptor.write(0, 512, buffer, null);
+
+ Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+ buffer.rewind();
+
+ fileDescriptor.read(0, 512, buffer, null);
+
+ Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+ for (int i = 0; i < 512; i++)
+ {
+ Assert.assertEquals('B', buffer.get());
+ }
+ }
+ finally
+ {
+ LibaioContext.freeBuffer(buffer);
+ fileDescriptor.close();
+ }
+ }
+
+ @Test
+ /**
+ * This file is making use of libaio without O_DIRECT
+ * We won't need special buffers on this case.
+ */
+ public void testSubmitWriteAndReadRegularBuffers() throws Exception
+ {
+ TestInfo callback = new TestInfo();
+
+ TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+ File file = temporaryFolder.newFile("test.bin");
+
+ fillupFile(file, LIBAIO_QUEUE_SIZE);
+
+ LibaioFile fileDescriptor = control.openFile(file, false);
+
+ final int BUFFER_SIZE = 50;
+
+ ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
+
+ try
+ {
+ for (int i = 0; i < BUFFER_SIZE; i++)
+ {
+ buffer.put((byte) 'a');
+ }
+
+ buffer.rewind();
+
+ fileDescriptor.write(0, BUFFER_SIZE, buffer, callback);
+
+ int retValue = control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE);
+ System.out.println("Return from poll::" + retValue);
+ Assert.assertEquals(1, retValue);
+
+ Assert.assertSame(callback, callbacks[0]);
+
+ buffer.rewind();
+
+ for (int i = 0; i < BUFFER_SIZE; i++)
+ {
+ buffer.put((byte) 'B');
+ }
+
+ fileDescriptor.write(0, BUFFER_SIZE, buffer, null);
+
+ Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+ buffer.rewind();
+
+ fileDescriptor.read(0, 50, buffer, null);
+
+ Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+ for (int i = 0; i < BUFFER_SIZE; i++)
+ {
+ Assert.assertEquals('B', buffer.get());
+ }
+ }
+ finally
+ {
+ fileDescriptor.close();
+ }
+ }
+
+ @Test
+ public void testSubmitRead() throws Exception
+ {
+
+ TestInfo callback = new TestInfo();
+
+ TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+ File file = temporaryFolder.newFile("test.bin");
+
+ fillupFile(file, LIBAIO_QUEUE_SIZE);
+
+ LibaioFile fileDescriptor = control.openFile(file, true);
+
+ ByteBuffer buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+ final int BUFFER_SIZE = 512;
+ try
+ {
+ for (int i = 0; i < BUFFER_SIZE; i++)
+ {
+ buffer.put((byte) '@');
+ }
+
+ fileDescriptor.write(0, BUFFER_SIZE, buffer, callback);
+ Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+ Assert.assertSame(callback, callbacks[0]);
+
+ buffer.rewind();
+
+ fileDescriptor.read(0, BUFFER_SIZE, buffer, callback);
+
+ Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+ Assert.assertSame(callback, callbacks[0]);
+
+ for (int i = 0; i < BUFFER_SIZE; i++)
+ {
+ Assert.assertEquals('@', buffer.get());
+ }
+ }
+ finally
+ {
+ LibaioContext.freeBuffer(buffer);
+ fileDescriptor.close();
+ }
+ }
+
+ @Test
+ public void testInvalidWrite() throws Exception
+ {
+
+ TestInfo callback = new TestInfo();
+
+ TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+ File file = temporaryFolder.newFile("test.bin");
+
+ fillupFile(file, LIBAIO_QUEUE_SIZE);
+
+ LibaioFile fileDescriptor = control.openFile(file, true);
+
+ try
+ {
+ ByteBuffer buffer = ByteBuffer.allocateDirect(300);
+ for (int i = 0; i < 300; i++)
+ {
+ buffer.put((byte) 'z');
+ }
+
+ fileDescriptor.write(0, 300, buffer, callback);
+
+ Assert.assertEquals(1, control.poll(callbacks, 1, LIBAIO_QUEUE_SIZE));
+
+ Assert.assertTrue(callbacks[0].isError());
+
+ // Error condition
+ Assert.assertSame(callbacks[0], callback);
+
+ System.out.println("Error:" + callbacks[0]);
+
+ buffer = fileDescriptor.newBuffer(512);
+ for (int i = 0; i < 512; i++)
+ {
+ buffer.put((byte) 'z');
+ }
+
+ callback = new TestInfo();
+
+ fileDescriptor.write(0, 512, buffer, callback);
+
+ Assert.assertEquals(1, control.poll(callbacks, 1, 1));
+
+ Assert.assertSame(callback, callbacks[0]);
+
+ fileDescriptor.write(5, 512, buffer, callback);
+
+ Assert.assertEquals(1, control.poll(callbacks, 1, 1));
+
+ Assert.assertTrue(callbacks[0].isError());
+
+ callbacks = null;
+ callback = null;
+
+ TestInfo.checkLeaks();
+ }
+ finally
+ {
+ fileDescriptor.close();
+ }
+ }
+
+ @Test
+ public void testLeaks() throws Exception
+ {
+ File file = temporaryFolder.newFile("test.bin");
+
+ fillupFile(file, LIBAIO_QUEUE_SIZE * 2);
+
+ TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+
+ LibaioFile<TestInfo> fileDescriptor = control.openFile(file, true);
+
+ ByteBuffer bufferWrite = LibaioContext.newAlignedBuffer(512, 512);
+
+ try
+ {
+ for (int i = 0; i < 512; i++)
+ {
+ bufferWrite.put((byte) 'B');
+ }
+
+ for (int j = 0; j < LIBAIO_QUEUE_SIZE * 2; j++)
+ {
+ for (int i = 0; i < LIBAIO_QUEUE_SIZE; i++)
+ {
+ TestInfo countClass = new TestInfo();
+ fileDescriptor.write(i * 512, 512, bufferWrite, countClass);
+ }
+
+ Assert.assertEquals(LIBAIO_QUEUE_SIZE, control.poll(callbacks, LIBAIO_QUEUE_SIZE, LIBAIO_QUEUE_SIZE));
+
+ for (int i = 0; i < LIBAIO_QUEUE_SIZE; i++)
+ {
+ Assert.assertNotNull(callbacks[i]);
+ callbacks[i] = null;
+ }
+ }
+
+ TestInfo.checkLeaks();
+ }
+ finally
+ {
+ LibaioContext.freeBuffer(bufferWrite);
+ }
+ }
+
+ @Test
+ public void testLock() throws Exception
+ {
+ File file = temporaryFolder.newFile("test.bin");
+
+ LibaioFile fileDescriptor = control.openFile(file, true);
+ fileDescriptor.lock();
+
+ fileDescriptor.close();
+ }
+
+ @Test
+ public void testAlloc() throws Exception
+ {
+ File file = temporaryFolder.newFile("test.bin");
+
+ LibaioFile fileDescriptor = control.openFile(file, true);
+ fileDescriptor.fill(10 * 1024 * 1024);
+
+ fileDescriptor.close();
+ }
+
+ @Test
+ public void testReleaseNullBuffer() throws Exception
+ {
+ boolean failed = false;
+ try
+ {
+ LibaioContext.freeBuffer(null);
+ }
+ catch (Exception expected)
+ {
+ failed = true;
+ }
+
+ Assert.assertTrue("Exception happened!", failed);
+
+ }
+
+ @Test
+ public void testMemset() throws Exception
+ {
+
+ ByteBuffer buffer = LibaioContext.newAlignedBuffer(512 * 8, 512);
+
+ for (int i = 0; i < buffer.capacity(); i++)
+ {
+ buffer.put((byte) 'z');
+ }
+
+ buffer.position(0);
+
+ for (int i = 0; i < buffer.capacity(); i++)
+ {
+ Assert.assertEquals((byte) 'z', buffer.get());
+ }
+
+ control.memsetBuffer(buffer);
+
+ buffer.position(0);
+
+ for (int i = 0; i < buffer.capacity(); i++)
+ {
+ Assert.assertEquals((byte) 0, buffer.get());
+ }
+
+ LibaioContext.freeBuffer(buffer);
+
+ }
+
+ @Test
+ public void testIOExceptionConditions() throws Exception
+ {
+ boolean exceptionThrown = false;
+
+ control.close();
+ control = new LibaioContext<>(LIBAIO_QUEUE_SIZE, false);
+ try
+ {
+ // There is no space for a queue this huge, the native layer should throw the exception
+ LibaioContext newController = new LibaioContext(Integer.MAX_VALUE, false);
+ }
+ catch (RuntimeException e)
+ {
+ exceptionThrown = true;
+ }
+
+ Assert.assertTrue(exceptionThrown);
+ exceptionThrown = false;
+
+ try
+ {
+ // this should throw an exception, we shouldn't be able to open a directory!
+ control.openFile(temporaryFolder.getRoot(), true);
+ }
+ catch (IOException expected)
+ {
+ exceptionThrown = true;
+ }
+
+ Assert.assertTrue(exceptionThrown);
+
+ exceptionThrown = false;
+
+ LibaioFile fileDescriptor = control.openFile(temporaryFolder.newFile(), true);
+ fileDescriptor.close();
+ try
+ {
+ fileDescriptor.close();
+ }
+ catch (IOException expected)
+ {
+ exceptionThrown = true;
+ }
+
+ Assert.assertTrue(exceptionThrown);
+
+ fileDescriptor = control.openFile(temporaryFolder.newFile(), true);
+
+ ByteBuffer buffer = fileDescriptor.newBuffer(512);
+
+ try
+ {
+ for (int i = 0; i < 512; i++)
+ {
+ buffer.put((byte) 'a');
+ }
+
+ for (int i = 0; i < LIBAIO_QUEUE_SIZE; i++)
+ {
+ fileDescriptor.write(i * 512, 512, buffer, new TestInfo());
+ }
+
+ boolean ex = false;
+ try
+ {
+ fileDescriptor.write(0, 512, buffer, new TestInfo());
+ }
+ catch (Exception e)
+ {
+ ex = true;
+ }
+
+ Assert.assertTrue(ex);
+
+ TestInfo[] callbacks = new TestInfo[LIBAIO_QUEUE_SIZE];
+ Assert.assertEquals(LIBAIO_QUEUE_SIZE, control.poll(callbacks, LIBAIO_QUEUE_SIZE, LIBAIO_QUEUE_SIZE));
+
+ // it should be possible to write now after queue space being released
+ fileDescriptor.write(0, 512, buffer, new TestInfo());
+ Assert.assertEquals(1, control.poll(callbacks, 1, 100));
+
+ TestInfo errorCallback = new TestInfo();
+ // odd positions will have failures through O_DIRECT
+ fileDescriptor.read(3, 512, buffer, errorCallback);
+ Assert.assertEquals(1, control.poll(callbacks, 1, 50));
+ Assert.assertTrue(callbacks[0].isError());
+ Assert.assertSame(errorCallback, (callbacks[0]));
+
+ // to help GC and the checkLeaks
+ callbacks = null;
+ errorCallback = null;
+
+ TestInfo.checkLeaks();
+
+ exceptionThrown = false;
+ try
+ {
+ LibaioContext.newAlignedBuffer(300, 512);
+ }
+ catch (RuntimeException e)
+ {
+ exceptionThrown = true;
+ }
+
+ Assert.assertTrue(exceptionThrown);
+
+ exceptionThrown = false;
+ try
+ {
+ LibaioContext.newAlignedBuffer(-512, 512);
+ }
+ catch (RuntimeException e)
+ {
+ exceptionThrown = true;
+ }
+
+ Assert.assertTrue(exceptionThrown);
+ }
+ finally
+ {
+ LibaioContext.freeBuffer(buffer);
+ }
+ }
+
+ @Test
+ public void testBlockedCallback() throws Exception
+ {
+ final LibaioContext blockedContext = new LibaioContext(500, true);
+ Thread t = new Thread()
+ {
+ public void run()
+ {
+ blockedContext.poll();
+ }
+ };
+
+ t.start();
+
+
+ int NUMBER_OF_BLOCKS = 5000;
+
+ final CountDownLatch latch = new CountDownLatch(NUMBER_OF_BLOCKS);
+
+ File file = temporaryFolder.newFile("sub-file.txt");
+ LibaioFile aioFile = blockedContext.openFile(file, true);
+ aioFile.fill(NUMBER_OF_BLOCKS * 512);
+
+ final AtomicInteger errors = new AtomicInteger(0);
+
+ class MyCallback implements SubmitInfo
+ {
+ @Override
+ public void onError(int errno, String message)
+ {
+ errors.incrementAndGet();
+ }
+
+ @Override
+ public void done()
+ {
+ latch.countDown();
+ }
+ }
+
+ MyCallback callback = new MyCallback();
+
+ ByteBuffer buffer = LibaioContext.newAlignedBuffer(512, 512);
+
+
+ for (int i = 0; i < 512; i++)
+ {
+ buffer.put((byte)'a');
+ }
+
+ long start = System.currentTimeMillis();
+
+ for (int i = 0; i < NUMBER_OF_BLOCKS; i++)
+ {
+ aioFile.write(i * 512, 512, buffer, callback);
+ }
+
+ long end = System.currentTimeMillis();
+
+ latch.await();
+
+
+ System.out.println("time = " + (end - start) + " writes/second=" + NUMBER_OF_BLOCKS * 1000L / (end - start));
+//
+// MultiThreadAsynchronousFileTest.debug((sync ? "Sync result:" : "Async result:") + " Records/Second = " +
+// MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS *
+// MultiThreadAsynchronousFileTest.NUMBER_OF_LINES *
+// 1000 /
+// (endTime - startTime) +
+// " total time = " +
+// (endTime - startTime) +
+// " total number of records = " +
+// MultiThreadAsynchronousFileTest.NUMBER_OF_THREADS *
+// MultiThreadAsynchronousFileTest.NUMBER_OF_LINES);
+
+ Thread.sleep(100);
+
+ blockedContext.close();
+ t.join();
+ }
+
+ private void fillupFile(File file, int blocks) throws IOException
+ {
+ FileOutputStream fileOutputStream = new FileOutputStream(file);
+ byte[] bufferWrite = new byte[512];
+ for (int i = 0; i < 512; i++)
+ {
+ bufferWrite[i] = (byte) 0;
+ }
+
+ for (int i = 0; i < blocks; i++)
+ {
+ fileOutputStream.write(bufferWrite);
+ }
+
+ fileOutputStream.close();
+ }
+
+
+ static class TestInfo implements SubmitInfo
+ {
+ static AtomicInteger count = new AtomicInteger();
+
+ @Override
+ protected void finalize() throws Throwable
+ {
+ super.finalize();
+ count.decrementAndGet();
+ }
+
+ public static void checkLeaks() throws InterruptedException
+ {
+ for (int i = 0; count.get() != 0 && i < 50; i++)
+ {
+ WeakReference reference = new WeakReference(new Object());
+ while (reference.get() != null)
+ {
+ System.gc();
+ Thread.sleep(100);
+ }
+ }
+ Assert.assertEquals(0, count.get());
+ }
+
+ boolean error = false;
+ String errorMessage;
+ int errno;
+
+ public TestInfo()
+ {
+ count.incrementAndGet();
+ }
+
+ @Override
+ public void onError(int errno, String message)
+ {
+ this.errno = errno;
+ this.errorMessage = message;
+ this.error = true;
+ }
+
+ @Override
+ public void done()
+ {
+ }
+
+ public int getErrno()
+ {
+ return errno;
+ }
+
+ public void setErrno(int errno)
+ {
+ this.errno = errno;
+ }
+
+ public boolean isError()
+ {
+ return error;
+ }
+
+ public void setError(boolean error)
+ {
+ this.error = error;
+ }
+
+ public String getErrorMessage()
+ {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage)
+ {
+ this.errorMessage = errorMessage;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
index 71610b4..f74d6d7 100644
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
@@ -20,6 +20,7 @@ package org.apache.activemq.artemis.core.protocol.proton.plug;
import java.util.concurrent.Executor;
import io.netty.buffer.ByteBuf;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.qpid.proton.amqp.Binary;
import org.apache.qpid.proton.amqp.transport.AmqpError;
import org.apache.qpid.proton.amqp.transport.ErrorCondition;
@@ -30,7 +31,6 @@ import org.apache.qpid.proton.jms.EncodedMessage;
import org.apache.qpid.proton.message.ProtonJMessage;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.protocol.proton.ProtonProtocolManager;
import org.apache.activemq.artemis.core.server.QueueQueryResult;
import org.apache.activemq.artemis.core.server.ServerConsumer;
@@ -275,7 +275,7 @@ public class ProtonSessionIntegrationCallback implements AMQPSessionCallback, Se
serverSession.send(message, false);
- manager.getServer().getStorageManager().afterCompleteOperations(new IOAsyncTask()
+ manager.getServer().getStorageManager().afterCompleteOperations(new IOCallback()
{
@Override
public void done()
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java b/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java
index aa3f9e0..45260d5 100644
--- a/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java
+++ b/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTPublishManager.java
@@ -22,7 +22,7 @@ import io.netty.buffer.EmptyByteBuf;
import io.netty.handler.codec.mqtt.MqttMessageType;
import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.server.ServerConsumer;
import org.apache.activemq.artemis.core.server.ServerMessage;
import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
@@ -183,7 +183,7 @@ public class MQTTPublishManager
private void createMessageAck(final int messageId, final int qos)
{
- session.getServer().getStorageManager().afterCompleteOperations(new IOAsyncTask()
+ session.getServer().getStorageManager().afterCompleteOperations(new IOCallback()
{
@Override
public void done()
[2/9] activemq-artemis git commit: ARTEMIS-163 First pass on the
native AIO refactoring
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java
index 2dc0d38..e49e50b 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOImportExportTest.java
@@ -16,8 +16,8 @@
*/
package org.apache.activemq.artemis.tests.integration.journal;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.junit.BeforeClass;
public class AIOImportExportTest extends NIOImportExportTest
@@ -31,6 +31,6 @@ public class AIOImportExportTest extends NIOImportExportTest
@Override
protected SequentialFileFactory getFileFactory() throws Exception
{
- return new AIOSequentialFileFactory(getTestDirfile());
+ return new AIOSequentialFileFactory(getTestDirfile(), 10);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java
index 39972e7..f1ce785 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalCompactTest.java
@@ -19,8 +19,8 @@ package org.apache.activemq.artemis.tests.integration.journal;
import java.io.File;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
import org.junit.BeforeClass;
@@ -43,7 +43,7 @@ public class AIOJournalCompactTest extends NIOJournalCompactTest
return new AIOSequentialFileFactory(getTestDirfile(),
JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
- 100000,
+ 100000, 10,
false);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java
index acbaac4..59f6b95 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOJournalImplTest.java
@@ -17,10 +17,10 @@
package org.apache.activemq.artemis.tests.integration.journal;
import java.io.File;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestUnit;
import org.junit.Assert;
import org.junit.Before;
@@ -48,7 +48,7 @@ public class AIOJournalImplTest extends JournalImplTestUnit
public void setUp() throws Exception
{
super.setUp();
- if (!AsynchronousFileImpl.isLoaded())
+ if (!LibaioContext.isLoaded())
{
Assert.fail(String.format("libAIO is not loaded on %s %s %s",
System.getProperty("os.name"),
@@ -67,7 +67,7 @@ public class AIOJournalImplTest extends JournalImplTestUnit
file.mkdir();
return new AIOSequentialFileFactory(getTestDirfile(),
- JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO, 1000000,
+ JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO, 1000000, 10,
false);
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java
index 072c820..acc65b1 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/AIOSequentialFileFactoryTest.java
@@ -19,9 +19,9 @@ import java.io.File;
import java.nio.ByteBuffer;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.SequentialFileFactoryTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -38,13 +38,13 @@ public class AIOSequentialFileFactoryTest extends SequentialFileFactoryTestBase
@Override
protected SequentialFileFactory createFactory(String folder)
{
- return new AIOSequentialFileFactory(new File(folder));
+ return new AIOSequentialFileFactory(new File(folder), 10);
}
@Test
public void testBuffer() throws Exception
{
- SequentialFile file = factory.createSequentialFile("filtetmp.log", 10);
+ SequentialFile file = factory.createSequentialFile("filtetmp.log");
file.open();
ByteBuffer buff = factory.newBuffer(10);
Assert.assertEquals(512, buff.limit());
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java
index 1a69dab..c4b1acc 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOBufferedJournalCompactTest.java
@@ -19,8 +19,8 @@ package org.apache.activemq.artemis.tests.integration.journal;
import java.io.File;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
public class NIOBufferedJournalCompactTest extends NIOJournalCompactTest
{
@@ -34,7 +34,7 @@ public class NIOBufferedJournalCompactTest extends NIOJournalCompactTest
file.mkdir();
- return new NIOSequentialFileFactory(getTestDirfile(), true);
+ return new NIOSequentialFileFactory(getTestDirfile(), true, 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java
index d581644..e50143a 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOImportExportTest.java
@@ -17,8 +17,8 @@
package org.apache.activemq.artemis.tests.integration.journal;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.SimpleEncoding;
import org.junit.Test;
@@ -32,7 +32,7 @@ public class NIOImportExportTest extends JournalImplTestBase
@Override
protected SequentialFileFactory getFileFactory() throws Exception
{
- return new NIOSequentialFileFactory(getTestDirfile(), true);
+ return new NIOSequentialFileFactory(getTestDirfile(), true, 1);
}
// Constants -----------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java
index 3e42498..c3148bb 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalCompactTest.java
@@ -31,18 +31,18 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.AbstractJournalUpdateTask;
import org.apache.activemq.artemis.core.journal.impl.JournalCompactor;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.journal.impl.JournalFileImpl;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager;
import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
@@ -72,7 +72,7 @@ public class NIOJournalCompactTest extends JournalImplTestBase
for (int i = 0; i < 5; i++)
{
- SequentialFile file = fileFactory.createSequentialFile("file-" + i + ".tst", 1);
+ SequentialFile file = fileFactory.createSequentialFile("file-" + i + ".tst");
dataFiles.add(new JournalFileImpl(file, 0, JournalImpl.FORMAT_VERSION));
}
@@ -80,7 +80,7 @@ public class NIOJournalCompactTest extends JournalImplTestBase
for (int i = 0; i < 3; i++)
{
- SequentialFile file = fileFactory.createSequentialFile("file-" + i + ".tst.new", 1);
+ SequentialFile file = fileFactory.createSequentialFile("file-" + i + ".tst.new");
newFiles.add(new JournalFileImpl(file, 0, JournalImpl.FORMAT_VERSION));
}
@@ -1825,7 +1825,7 @@ public class NIOJournalCompactTest extends JournalImplTestBase
storage.commit(tx);
- ctx.executeOnCompletion(new IOAsyncTask()
+ ctx.executeOnCompletion(new IOCallback()
{
public void onError(int errorCode, String errorMessage)
{
@@ -1939,7 +1939,7 @@ public class NIOJournalCompactTest extends JournalImplTestBase
@Override
protected SequentialFileFactory getFileFactory() throws Exception
{
- return new NIOSequentialFileFactory(getTestDirfile());
+ return new NIOSequentialFileFactory(getTestDirfile(), 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java
index ad7671f..b4ff147 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOJournalImplTest.java
@@ -21,8 +21,8 @@ import java.io.File;
import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestUnit;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
public class NIOJournalImplTest extends JournalImplTestUnit
{
@@ -39,7 +39,7 @@ public class NIOJournalImplTest extends JournalImplTestUnit
file.mkdir();
- return new NIOSequentialFileFactory(getTestDirfile(), true);
+ return new NIOSequentialFileFactory(getTestDirfile(), true, 1);
}
@Override
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java
index 059bf59..d82b28c 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONoBufferJournalImplTest.java
@@ -19,8 +19,8 @@ package org.apache.activemq.artemis.tests.integration.journal;
import java.io.File;
import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestUnit;
public class NIONoBufferJournalImplTest extends JournalImplTestUnit
@@ -38,7 +38,7 @@ public class NIONoBufferJournalImplTest extends JournalImplTestUnit
file.mkdir();
- return new NIOSequentialFileFactory(new File(getTestDir()), false);
+ return new NIOSequentialFileFactory(new File(getTestDir()), false, 1);
}
@Override
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java
index 717d03c..2072300 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIONonBufferedSequentialFileFactoryTest.java
@@ -17,8 +17,8 @@
package org.apache.activemq.artemis.tests.integration.journal;
import java.io.File;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.SequentialFileFactoryTestBase;
public class NIONonBufferedSequentialFileFactoryTest extends SequentialFileFactoryTestBase
@@ -27,7 +27,7 @@ public class NIONonBufferedSequentialFileFactoryTest extends SequentialFileFacto
@Override
protected SequentialFileFactory createFactory(String folder)
{
- return new NIOSequentialFileFactory(new File(folder), false);
+ return new NIOSequentialFileFactory(new File(folder), false, 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java
index 1ca667b..bcab8e6 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/NIOSequentialFileFactoryTest.java
@@ -17,8 +17,8 @@
package org.apache.activemq.artemis.tests.integration.journal;
import java.io.File;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.SequentialFileFactoryTestBase;
public class NIOSequentialFileFactoryTest extends SequentialFileFactoryTestBase
@@ -27,7 +27,7 @@ public class NIOSequentialFileFactoryTest extends SequentialFileFactoryTestBase
@Override
protected SequentialFileFactory createFactory(String folder)
{
- return new NIOSequentialFileFactory(new File(folder), true);
+ return new NIOSequentialFileFactory(new File(folder), true, 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java
index 5e8587d..7cebc4f 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/journal/ValidateTransactionHealthTest.java
@@ -20,17 +20,17 @@ import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.util.SpawnedVMSupport;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.journal.LoaderCallback;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.junit.Assert;
import org.junit.Test;
@@ -126,7 +126,7 @@ public class ValidateTransactionHealthTest extends ActiveMQTestBase
{
try
{
- if (type.equals("aio") && !AsynchronousFileImpl.isLoaded())
+ if (type.equals("aio") && !LibaioContext.isLoaded())
{
// Using System.out as this output will go towards junit report
System.out.println("AIO not found, test being ignored on this platform");
@@ -381,15 +381,16 @@ public class ValidateTransactionHealthTest extends ActiveMQTestBase
return new AIOSequentialFileFactory(new File(directory),
JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
+ 10,
false);
}
else if (factoryType.equals("nio2"))
{
- return new NIOSequentialFileFactory(new File(directory), true);
+ return new NIOSequentialFileFactory(new File(directory), true, 1);
}
else
{
- return new NIOSequentialFileFactory(new File(directory), false);
+ return new NIOSequentialFileFactory(new File(directory), false, 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
index c8f5d8b..22c9628 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
@@ -16,6 +16,10 @@
*/
package org.apache.activemq.artemis.tests.integration.management;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import java.util.HashMap;
+
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
@@ -32,7 +36,6 @@ import org.apache.activemq.artemis.api.core.management.DivertControl;
import org.apache.activemq.artemis.api.core.management.ObjectNameBuilder;
import org.apache.activemq.artemis.api.core.management.QueueControl;
import org.apache.activemq.artemis.api.core.management.RoleInfo;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.messagecounter.impl.MessageCounterManagerImpl;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
@@ -41,6 +44,7 @@ import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.ActiveMQServers;
import org.apache.activemq.artemis.core.settings.impl.SlowConsumerPolicy;
import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.util.RandomUtil;
import org.apache.activemq.artemis.utils.UUIDGenerator;
import org.apache.activemq.artemis.utils.json.JSONArray;
@@ -49,10 +53,6 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-import java.util.HashMap;
-
public class ActiveMQServerControlTest extends ManagementTestBase
{
@@ -118,7 +118,7 @@ public class ActiveMQServerControlTest extends ManagementTestBase
Assert.assertEquals(conf.isJournalSyncNonTransactional(), serverControl.isJournalSyncNonTransactional());
Assert.assertEquals(conf.getJournalFileSize(), serverControl.getJournalFileSize());
Assert.assertEquals(conf.getJournalMinFiles(), serverControl.getJournalMinFiles());
- if (AsynchronousFileImpl.isLoaded())
+ if (LibaioContext.isLoaded())
{
Assert.assertEquals(conf.getJournalMaxIO_AIO(), serverControl.getJournalMaxIO());
Assert.assertEquals(conf.getJournalBufferSize_AIO(), serverControl.getJournalBufferSize());
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java
index 2990294..d1f4755 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/replication/ReplicationTest.java
@@ -44,18 +44,18 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.config.ClusterConnectionConfiguration;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.ha.SharedStoreSlavePolicyConfiguration;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
import org.apache.activemq.artemis.core.journal.IOCompletion;
import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
import org.apache.activemq.artemis.core.journal.LoaderCallback;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
import org.apache.activemq.artemis.core.journal.impl.JournalFile;
import org.apache.activemq.artemis.core.paging.PagedMessage;
@@ -377,7 +377,7 @@ public final class ReplicationTest extends ActiveMQTestBase
final CountDownLatch latch = new CountDownLatch(1);
- ctx.executeOnCompletion(new IOAsyncTask()
+ ctx.executeOnCompletion(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
{
@@ -402,7 +402,7 @@ public final class ReplicationTest extends ActiveMQTestBase
final CountDownLatch latch2 = new CountDownLatch(1);
// Adding the Task after the exception should still throw an exception
- ctx.executeOnCompletion(new IOAsyncTask()
+ ctx.executeOnCompletion(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
{
@@ -426,7 +426,7 @@ public final class ReplicationTest extends ActiveMQTestBase
final CountDownLatch latch3 = new CountDownLatch(1);
- ctx.executeOnCompletion(new IOAsyncTask()
+ ctx.executeOnCompletion(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
{
@@ -488,7 +488,7 @@ public final class ReplicationTest extends ActiveMQTestBase
private void blockOnReplication(final StorageManager storage, final ReplicationManager manager1) throws Exception
{
final CountDownLatch latch = new CountDownLatch(1);
- storage.afterCompleteOperations(new IOAsyncTask()
+ storage.afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
@@ -518,7 +518,7 @@ public final class ReplicationTest extends ActiveMQTestBase
replicatedJournal.appendPrepareRecord(1, new FakeData(), false);
final CountDownLatch latch = new CountDownLatch(1);
- storage.afterCompleteOperations(new IOAsyncTask()
+ storage.afterCompleteOperations(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
@@ -563,7 +563,7 @@ public final class ReplicationTest extends ActiveMQTestBase
replicatedJournal.appendPrepareRecord(i, new FakeData(), false);
}
- ctx.executeOnCompletion(new IOAsyncTask()
+ ctx.executeOnCompletion(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java
index 6f4b08d..4797e23 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/FileLockTimeoutTest.java
@@ -21,9 +21,9 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.ha.SharedStoreMasterPolicyConfiguration;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
@@ -53,7 +53,7 @@ public class FileLockTimeoutTest extends ActiveMQTestBase
{
Assert.assertTrue(String.format("libAIO is not loaded on %s %s %s", System.getProperty("os.name"),
System.getProperty("os.arch"), System.getProperty("os.version")),
- AsynchronousFileImpl.isLoaded()
+ LibaioContext.isLoaded()
);
}
Configuration config = super.createDefaultInVMConfig()
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java
index 2548b1a..a7f4210 100644
--- a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java
+++ b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/FakeJournalImplTest.java
@@ -16,7 +16,7 @@
*/
package org.apache.activemq.artemis.tests.performance.journal;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
/**
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java
----------------------------------------------------------------------
diff --git a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java
index 11d6186..17bf397 100644
--- a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java
+++ b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/JournalImplTestUnit.java
@@ -15,22 +15,19 @@
* limitations under the License.
*/
package org.apache.activemq.artemis.tests.performance.journal;
-import org.junit.After;
-
-import org.junit.Test;
-
import java.util.ArrayList;
-import org.junit.Assert;
-
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.SimpleEncoding;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
public abstract class JournalImplTestUnit extends JournalImplTestBase
{
@@ -42,7 +39,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
{
super.tearDown();
- Assert.assertEquals(0, AsynchronousFileImpl.getTotalMaxIO());
+ Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
}
@Test
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java
----------------------------------------------------------------------
diff --git a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java
index 7fa9e14..a73a841 100644
--- a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java
+++ b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplAIOTest.java
@@ -17,8 +17,8 @@
package org.apache.activemq.artemis.tests.performance.journal;
import java.io.File;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -51,7 +51,7 @@ public class RealJournalImplAIOTest extends JournalImplTestUnit
file.mkdir();
- return new AIOSequentialFileFactory(getTestDirfile());
+ return new AIOSequentialFileFactory(getTestDirfile(), 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java
----------------------------------------------------------------------
diff --git a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java
index 4d2fbcf..bc0e7c2 100644
--- a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java
+++ b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/journal/RealJournalImplNIOTest.java
@@ -18,8 +18,8 @@ package org.apache.activemq.artemis.tests.performance.journal;
import java.io.File;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
public class RealJournalImplNIOTest extends JournalImplTestUnit
@@ -37,7 +37,7 @@ public class RealJournalImplNIOTest extends JournalImplTestUnit
file.mkdir();
- return new NIOSequentialFileFactory(getTestDirfile());
+ return new NIOSequentialFileFactory(getTestDirfile(), 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java
index a3a9e1f..eddc347 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOAllPossibilitiesCompactStressTest.java
@@ -18,8 +18,8 @@ package org.apache.activemq.artemis.tests.stress.journal;
import java.io.File;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
public class AIOAllPossibilitiesCompactStressTest extends AllPossibilitiesCompactStressTest
@@ -53,7 +53,7 @@ public class AIOAllPossibilitiesCompactStressTest extends AllPossibilitiesCompac
return new AIOSequentialFileFactory(getTestDirfile(),
JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
- 1000000,
+ 1000000, 1000,
false);
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java
index 5b07653..b2a3129 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AIOMultiThreadCompactorStressTest.java
@@ -16,7 +16,7 @@
*/
package org.apache.activemq.artemis.tests.stress.journal;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.server.JournalType;
import org.junit.BeforeClass;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java
index 83ed360..7abc703 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/AddAndRemoveStressTest.java
@@ -23,8 +23,8 @@ import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.core.journal.LoaderCallback;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.junit.Assert;
import org.junit.Test;
@@ -76,7 +76,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
public void testInsertAndLoad() throws Exception
{
- SequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile());
+ SequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
JournalImpl impl = new JournalImpl(10 * 1024 * 1024,
AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
0,
@@ -101,7 +101,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
impl.stop();
- factory = new AIOSequentialFileFactory(getTestDirfile());
+ factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
impl = new JournalImpl(10 * 1024 * 1024,
AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
0,
@@ -127,7 +127,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
impl.stop();
- factory = new AIOSequentialFileFactory(getTestDirfile());
+ factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
impl = new JournalImpl(10 * 1024 * 1024,
AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
0,
@@ -164,7 +164,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
public void testInsertUpdateAndLoad() throws Exception
{
- SequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile());
+ SequentialFileFactory factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
JournalImpl impl = new JournalImpl(10 * 1024 * 1024,
AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
0,
@@ -190,7 +190,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
impl.stop();
- factory = new AIOSequentialFileFactory(getTestDirfile());
+ factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
impl = new JournalImpl(10 * 1024 * 1024, 10, 0, 0, factory, "amq", "amq", 1000);
impl.start();
@@ -209,7 +209,7 @@ public class AddAndRemoveStressTest extends ActiveMQTestBase
impl.stop();
- factory = new AIOSequentialFileFactory(getTestDirfile());
+ factory = new AIOSequentialFileFactory(getTestDirfile(), 1000);
impl = new JournalImpl(10 * 1024 * 1024,
AddAndRemoveStressTest.NUMBER_OF_FILES_ON_JOURNAL,
0,
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java
index 60816b9..49354e4 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/CompactingStressTest.java
@@ -16,6 +16,9 @@
*/
package org.apache.activemq.artemis.tests.stress.journal;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
@@ -24,17 +27,14 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.JournalType;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Assert;
import org.junit.Test;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicInteger;
-
public class CompactingStressTest extends ActiveMQTestBase
{
@@ -69,7 +69,7 @@ public class CompactingStressTest extends ActiveMQTestBase
@Test
public void testCleanupAIO() throws Throwable
{
- if (AsynchronousFileImpl.isLoaded())
+ if (LibaioContext.isLoaded())
{
internalTestCleanup(JournalType.ASYNCIO);
}
@@ -164,7 +164,7 @@ public class CompactingStressTest extends ActiveMQTestBase
@Test
public void testMultiProducerAndCompactAIO() throws Throwable
{
- if (AsynchronousFileImpl.isLoaded())
+ if (LibaioContext.isLoaded())
{
internalTestMultiProducer(JournalType.ASYNCIO);
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java
index 9516700..3675cd8 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/JournalCleanupCompactStressTest.java
@@ -16,26 +16,6 @@
*/
package org.apache.activemq.artemis.tests.stress.journal;
-import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
-import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
-import org.apache.activemq.artemis.tests.util.RandomUtil;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
-import org.apache.activemq.artemis.utils.SimpleIDGenerator;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
@@ -52,6 +32,26 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
+import org.apache.activemq.artemis.core.journal.RecordInfo;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.tests.util.RandomUtil;
+import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
+import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
+import org.apache.activemq.artemis.utils.SimpleIDGenerator;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
public class JournalCleanupCompactStressTest extends ActiveMQTestBase
{
@@ -112,14 +112,14 @@ public class JournalCleanupCompactStressTest extends ActiveMQTestBase
SequentialFileFactory factory;
int maxAIO;
- if (AsynchronousFileImpl.isLoaded())
+ if (LibaioContext.isLoaded())
{
- factory = new AIOSequentialFileFactory(dir);
+ factory = new AIOSequentialFileFactory(dir, 10);
maxAIO = ActiveMQDefaultConfiguration.getDefaultJournalMaxIoAio();
}
else
{
- factory = new NIOSequentialFileFactory(dir, true);
+ factory = new NIOSequentialFileFactory(dir, true, 1);
maxAIO = ActiveMQDefaultConfiguration.getDefaultJournalMaxIoNio();
}
@@ -380,7 +380,7 @@ public class JournalCleanupCompactStressTest extends ActiveMQTestBase
}
journal.appendCommitRecord(txID, true, ctx);
- ctx.executeOnCompletion(new IOAsyncTask()
+ ctx.executeOnCompletion(new IOCallback()
{
public void onError(final int errorCode, final String errorMessage)
@@ -493,7 +493,7 @@ public class JournalCleanupCompactStressTest extends ActiveMQTestBase
}
}
- class DeleteTask implements IOAsyncTask
+ class DeleteTask implements IOCallback
{
final long[] ids;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java
index d351fe5..f7edebe 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/MixupCompactorTestBase.java
@@ -20,9 +20,9 @@ import java.io.File;
import java.io.FilenameFilter;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.utils.ReusableLatch;
import org.apache.activemq.artemis.utils.SimpleIDGenerator;
import org.junit.After;
@@ -241,6 +241,6 @@ public abstract class MixupCompactorTestBase extends JournalImplTestBase
@Override
protected SequentialFileFactory getFileFactory() throws Exception
{
- return new NIOSequentialFileFactory(getTestDirfile());
+ return new NIOSequentialFileFactory(getTestDirfile(), 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java
index 616c4a3..4ad8f4e 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/NIOMultiThreadCompactorStressTest.java
@@ -32,14 +32,14 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.JournalType;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Assert;
import org.junit.Before;
@@ -90,7 +90,7 @@ public class NIOMultiThreadCompactorStressTest extends ActiveMQTestBase
internalTestProduceAndConsume();
stopServer();
- NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getJournalDir()));
+ NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getJournalDir()), 1);
JournalImpl journal = new JournalImpl(ActiveMQDefaultConfiguration.getDefaultJournalFileSize(),
2,
0,
@@ -339,7 +339,7 @@ public class NIOMultiThreadCompactorStressTest extends ActiveMQTestBase
private void setupServer(JournalType journalType) throws Exception
{
- if (!AsynchronousFileImpl.isLoaded())
+ if (!LibaioContext.isLoaded())
{
journalType = JournalType.NIO;
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java
index 385d604..717188a 100644
--- a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java
+++ b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/AIOJournalImplTest.java
@@ -18,8 +18,8 @@ package org.apache.activemq.artemis.tests.timing.core.journal.impl;
import java.io.File;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.AIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
import org.junit.BeforeClass;
public class AIOJournalImplTest extends JournalImplTestUnit
@@ -39,7 +39,7 @@ public class AIOJournalImplTest extends JournalImplTestUnit
file.mkdir();
- return new AIOSequentialFileFactory(getTestDirfile());
+ return new AIOSequentialFileFactory(getTestDirfile(), 10);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java
index 5702d9d..9e1fb68 100644
--- a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java
+++ b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/FakeJournalImplTest.java
@@ -17,7 +17,7 @@
package org.apache.activemq.artemis.tests.timing.core.journal.impl;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
public class FakeJournalImplTest extends JournalImplTestUnit
{
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java
----------------------------------------------------------------------
diff --git a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java
index 0eab830..3ae3255 100644
--- a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java
+++ b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/JournalImplTestUnit.java
@@ -15,19 +15,16 @@
* limitations under the License.
*/
package org.apache.activemq.artemis.tests.timing.core.journal.impl;
-import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
-import org.junit.After;
-
-import org.junit.Test;
-
import java.util.ArrayList;
-import org.junit.Assert;
-
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
import org.apache.activemq.artemis.core.journal.RecordInfo;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
+import org.apache.activemq.artemis.tests.unit.core.journal.impl.JournalImplTestBase;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
public abstract class JournalImplTestUnit extends JournalImplTestBase
{
@@ -39,7 +36,7 @@ public abstract class JournalImplTestUnit extends JournalImplTestBase
{
super.tearDown();
- Assert.assertEquals(0, AsynchronousFileImpl.getTotalMaxIO());
+ Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
}
@Test
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java
----------------------------------------------------------------------
diff --git a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java
index c607493..842ad3b 100644
--- a/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java
+++ b/tests/timing-tests/src/test/java/org/apache/activemq/artemis/tests/timing/core/journal/impl/NIOJournalImplTest.java
@@ -18,8 +18,8 @@ package org.apache.activemq.artemis.tests.timing.core.journal.impl;
import java.io.File;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.tests.unit.UnitTestLogger;
public class NIOJournalImplTest extends JournalImplTestUnit
@@ -31,7 +31,7 @@ public class NIOJournalImplTest extends JournalImplTestUnit
{
File file = new File(getTemporaryDir());
- return new NIOSequentialFileFactory(file);
+ return new NIOSequentialFileFactory(file, 1);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java
index fc17c09..adfccaa 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/asyncio/AIOTestBase.java
@@ -22,9 +22,10 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -37,25 +38,24 @@ public abstract class AIOTestBase extends ActiveMQTestBase
// The AIO Test must use a local filesystem. Sometimes $HOME is on a NFS on
// most enterprise systems
- protected String fileName;
+ protected String fileName = "fileUsedOnNativeTests.log";
@Override
@Before
public void setUp() throws Exception
{
super.setUp();
- fileName = getTestDir() + "/fileUsedOnNativeTests.log";
Assert.assertTrue(String.format("libAIO is not loaded on %s %s %s", System.getProperty("os.name"),
System.getProperty("os.arch"), System.getProperty("os.version")),
- AsynchronousFileImpl.isLoaded());
+ LibaioContext.isLoaded());
}
@Override
@After
public void tearDown() throws Exception
{
- Assert.assertEquals(0, AsynchronousFileImpl.getTotalMaxIO());
+ Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
super.tearDown();
}
@@ -73,12 +73,12 @@ public abstract class AIOTestBase extends ActiveMQTestBase
}
- protected void preAlloc(final AsynchronousFileImpl controller, final long size) throws ActiveMQException
+ protected void preAlloc(final LibaioFile controller, final long size) throws ActiveMQException
{
- controller.fill(0L, 1, size, (byte)0);
+ controller.fill(size);
}
- protected static class CountDownCallback implements AIOCallback
+ protected static class CountDownCallback implements IOCallback
{
private final CountDownLatch latch;
[7/9] activemq-artemis git commit: ARTEMIS-163 First pass on the
native AIO refactoring
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFileFactory.java
new file mode 100644
index 0000000..61cd0fd
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/AbstractSequentialFileFactory.java
@@ -0,0 +1,224 @@
+/*
+ * 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.core.io;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
+
+/**
+ * An abstract SequentialFileFactory containing basic functionality for both AIO and NIO SequentialFactories
+ */
+public abstract class AbstractSequentialFileFactory implements SequentialFileFactory
+{
+
+ // Timeout used to wait executors to shutdown
+ protected static final int EXECUTOR_TIMEOUT = 60;
+
+ protected final File journalDir;
+
+ protected final TimedBuffer timedBuffer;
+
+ protected final int bufferSize;
+
+ protected final long bufferTimeout;
+
+ protected final int maxIO;
+
+ private final IOCriticalErrorListener critialErrorListener;
+
+ /**
+ * Asynchronous writes need to be done at another executor.
+ * This needs to be done at NIO, or else we would have the callers thread blocking for the return.
+ * At AIO this is necessary as context switches on writes would fire flushes at the kernel.
+ * */
+ protected ExecutorService writeExecutor;
+
+ protected AbstractSequentialFileFactory(final File journalDir,
+ final boolean buffered,
+ final int bufferSize,
+ final int bufferTimeout,
+ final int maxIO,
+ final boolean logRates,
+ final IOCriticalErrorListener criticalErrorListener)
+ {
+ this.journalDir = journalDir;
+
+ if (buffered && bufferTimeout > 0)
+ {
+ timedBuffer = new TimedBuffer(bufferSize, bufferTimeout, logRates);
+ }
+ else
+ {
+ timedBuffer = null;
+ }
+ this.bufferSize = bufferSize;
+ this.bufferTimeout = bufferTimeout;
+ this.critialErrorListener = criticalErrorListener;
+ this.maxIO = maxIO;
+ }
+
+ public void stop()
+ {
+ if (timedBuffer != null)
+ {
+ timedBuffer.stop();
+ }
+
+ if (isSupportsCallbacks() && writeExecutor != null)
+ {
+ writeExecutor.shutdown();
+
+ try
+ {
+ if (!writeExecutor.awaitTermination(AbstractSequentialFileFactory.EXECUTOR_TIMEOUT, TimeUnit.SECONDS))
+ {
+ ActiveMQJournalLogger.LOGGER.timeoutOnWriterShutdown(new Exception("trace"));
+ }
+ }
+ catch (InterruptedException e)
+ {
+ throw new ActiveMQInterruptedException(e);
+ }
+ }
+ }
+
+ @Override
+ public File getDirectory()
+ {
+ return journalDir;
+ }
+
+ public void start()
+ {
+ if (timedBuffer != null)
+ {
+ timedBuffer.start();
+ }
+
+ if (isSupportsCallbacks())
+ {
+ writeExecutor = Executors.newSingleThreadExecutor(new ActiveMQThreadFactory("ActiveMQ-Asynchronous-Persistent-Writes" + System.identityHashCode(this),
+ true,
+ AbstractSequentialFileFactory.getThisClassLoader()));
+ }
+ }
+
+ public int getMaxIO()
+ {
+ return maxIO;
+ }
+
+ @Override
+ public void onIOError(Exception exception, String message, SequentialFile file)
+ {
+ if (critialErrorListener != null)
+ {
+ critialErrorListener.onIOException(exception, message, file);
+ }
+ }
+
+ @Override
+ public void activateBuffer(final SequentialFile file)
+ {
+ if (timedBuffer != null)
+ {
+ file.setTimedBuffer(timedBuffer);
+ }
+ }
+
+ public void flush()
+ {
+ if (timedBuffer != null)
+ {
+ timedBuffer.flush();
+ }
+ }
+
+ public void deactivateBuffer()
+ {
+ if (timedBuffer != null)
+ {
+ // When moving to a new file, we need to make sure any pending buffer will be transferred to the buffer
+ timedBuffer.flush();
+ timedBuffer.setObserver(null);
+ }
+ }
+
+ public void releaseBuffer(final ByteBuffer buffer)
+ {
+ }
+
+ /**
+ * Create the directory if it doesn't exist yet
+ */
+ public void createDirs() throws Exception
+ {
+ boolean ok = journalDir.mkdirs();
+ if (!ok)
+ {
+ throw new IOException("Failed to create directory " + journalDir);
+ }
+ }
+
+ public List<String> listFiles(final String extension) throws Exception
+ {
+ FilenameFilter fnf = new FilenameFilter()
+ {
+ public boolean accept(final File file, final String name)
+ {
+ return name.endsWith("." + extension);
+ }
+ };
+
+ String[] fileNames = journalDir.list(fnf);
+
+ if (fileNames == null)
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ return Arrays.asList(fileNames);
+ }
+
+ private static ClassLoader getThisClassLoader()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return AbstractSequentialFileFactory.class.getClassLoader();
+ }
+ });
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/DummyCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/DummyCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/DummyCallback.java
new file mode 100644
index 0000000..ce21f2a
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/DummyCallback.java
@@ -0,0 +1,49 @@
+/*
+ * 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.core.io;
+
+import org.apache.activemq.artemis.core.journal.impl.SyncIOCompletion;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+
+public class DummyCallback extends SyncIOCompletion
+{
+ private static final DummyCallback instance = new DummyCallback();
+
+ public static DummyCallback getInstance()
+ {
+ return DummyCallback.instance;
+ }
+
+ public void done()
+ {
+ }
+
+ public void onError(final int errorCode, final String errorMessage)
+ {
+ ActiveMQJournalLogger.LOGGER.errorWritingData(new Exception(errorMessage), errorMessage, errorCode);
+ }
+
+ @Override
+ public void waitCompletion() throws Exception
+ {
+ }
+
+ @Override
+ public void storeLineUp()
+ {
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCallback.java
new file mode 100644
index 0000000..41470e4
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCallback.java
@@ -0,0 +1,33 @@
+/*
+ * 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.core.io;
+
+/**
+ * The interface used for AIO Callbacks.
+ */
+public interface IOCallback
+{
+ /**
+ * Method for sync notifications. When this callback method is called, there is a guarantee the data is written on the disk.
+ * <br><b>Note:</b><i>Leave this method as soon as possible, or you would be blocking the whole notification thread</i> */
+ void done();
+
+ /**
+ * Method for error notifications.
+ * Observation: The whole file will be probably failing if this happens. Like, if you delete the file, you will start to get errors for these operations*/
+ void onError(int errorCode, String errorMessage);
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCriticalErrorListener.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCriticalErrorListener.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCriticalErrorListener.java
new file mode 100644
index 0000000..f2da3e8
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOCriticalErrorListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.core.io;
+
+/**
+ * TODO Merge this with IOExceptionListener
+ */
+public interface IOCriticalErrorListener
+{
+ void onIOException(Exception code, String message, SequentialFile file);
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOExceptionListener.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOExceptionListener.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOExceptionListener.java
new file mode 100644
index 0000000..5c855e5
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/IOExceptionListener.java
@@ -0,0 +1,22 @@
+/*
+ * 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.core.io;
+
+public interface IOExceptionListener
+{
+ void onIOException(Exception exception, String message);
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFile.java
new file mode 100644
index 0000000..cb9d070
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFile.java
@@ -0,0 +1,116 @@
+/*
+ * 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.core.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.core.journal.EncodingSupport;
+import org.apache.activemq.artemis.core.io.buffer.TimedBuffer;
+
+public interface SequentialFile
+{
+
+ boolean isOpen();
+
+ boolean exists();
+
+ void open() throws Exception;
+
+ /**
+ * The maximum number of simultaneous writes accepted
+ * @param maxIO
+ * @throws Exception
+ */
+ void open(int maxIO, boolean useExecutor) throws Exception;
+
+ boolean fits(int size);
+
+ int getAlignment() throws Exception;
+
+ int calculateBlockStart(int position) throws Exception;
+
+ String getFileName();
+
+ void fill(int size) throws Exception;
+
+ void delete() throws IOException, InterruptedException, ActiveMQException;
+
+ void write(ActiveMQBuffer bytes, boolean sync, IOCallback callback) throws Exception;
+
+ void write(ActiveMQBuffer bytes, boolean sync) throws Exception;
+
+ void write(EncodingSupport bytes, boolean sync, IOCallback callback) throws Exception;
+
+ void write(EncodingSupport bytes, boolean sync) throws Exception;
+
+ /**
+ * Write directly to the file without using any buffer
+ * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
+ * NIO). To be safe, use a buffer from the corresponding
+ * {@link SequentialFileFactory#newBuffer(int)}.
+ */
+ void writeDirect(ByteBuffer bytes, boolean sync, IOCallback callback);
+
+ /**
+ * Write directly to the file without using intermediate any buffer
+ * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
+ * NIO). To be safe, use a buffer from the corresponding
+ * {@link SequentialFileFactory#newBuffer(int)}.
+ */
+ void writeDirect(ByteBuffer bytes, boolean sync) throws Exception;
+
+ /**
+ * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
+ * NIO). To be safe, use a buffer from the corresponding
+ * {@link SequentialFileFactory#newBuffer(int)}.
+ */
+ int read(ByteBuffer bytes, IOCallback callback) throws Exception;
+
+ /**
+ * @param bytes the ByteBuffer must be compatible with the SequentialFile implementation (AIO or
+ * NIO). To be safe, use a buffer from the corresponding
+ * {@link SequentialFileFactory#newBuffer(int)}.
+ */
+ int read(ByteBuffer bytes) throws Exception;
+
+ void position(long pos) throws IOException;
+
+ long position();
+
+ void close() throws Exception;
+
+ void sync() throws IOException;
+
+ long size() throws Exception;
+
+ void renameTo(String newFileName) throws Exception;
+
+ SequentialFile cloneFile();
+
+ void copyTo(SequentialFile newFileName) throws Exception;
+
+ void setTimedBuffer(TimedBuffer buffer);
+
+ /**
+ * Returns a native File of the file underlying this sequential file.
+ */
+ File getJavaFile();
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFileFactory.java
new file mode 100644
index 0000000..b9a72ca
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/SequentialFileFactory.java
@@ -0,0 +1,91 @@
+/*
+ * 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.core.io;
+
+import java.io.File;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ *
+ * A SequentialFileFactory
+ */
+public interface SequentialFileFactory
+{
+ SequentialFile createSequentialFile(String fileName);
+
+ int getMaxIO();
+
+ /**
+ * Lists files that end with the given extension.
+ * <p>
+ * This method inserts a ".' before the extension.
+ * @param extension
+ * @return
+ * @throws Exception
+ */
+ List<String> listFiles(String extension) throws Exception;
+
+ boolean isSupportsCallbacks();
+
+ /** The SequentialFile will call this method when a disk IO Error happens during the live phase. */
+ void onIOError(Exception exception, String message, SequentialFile file);
+
+ /** used for cases where you need direct buffer outside of the journal context.
+ * This is because the native layer has a method that can be reused in certain cases like paging */
+ ByteBuffer allocateDirectBuffer(int size);
+
+ /** used for cases where you need direct buffer outside of the journal context.
+ * This is because the native layer has a method that can be reused in certain cases like paging */
+ void releaseDirectBuffer(ByteBuffer buffer);
+
+ /**
+ * Note: You need to release the buffer if is used for reading operations. You don't need to do
+ * it if using writing operations (AIO Buffer Lister will take of writing operations)
+ * @param size
+ * @return the allocated ByteBuffer
+ */
+ ByteBuffer newBuffer(int size);
+
+ void releaseBuffer(ByteBuffer buffer);
+
+ void activateBuffer(SequentialFile file);
+
+ void deactivateBuffer();
+
+ // To be used in tests only
+ ByteBuffer wrapBuffer(byte[] bytes);
+
+ int getAlignment();
+
+ int calculateBlockSize(int bytes);
+
+ File getDirectory();
+
+ void clearBuffer(ByteBuffer buffer);
+
+ void start();
+
+ void stop();
+
+ /**
+ * Creates the directory if it does not exist yet.
+ */
+ void createDirs() throws Exception;
+
+ void flush();
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFile.java
new file mode 100644
index 0000000..7503681
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFile.java
@@ -0,0 +1,333 @@
+/*
+ * 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.core.io.aio;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.PriorityQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQNativeIOError;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.AbstractSequentialFile;
+import org.apache.activemq.artemis.core.io.DummyCallback;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.journal.impl.SimpleWaitIOCallback;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
+import org.apache.activemq.artemis.utils.ReusableLatch;
+
+public class AIOSequentialFile extends AbstractSequentialFile
+{
+ private boolean opened = false;
+
+ private LibaioFile aioFile;
+
+ private final AIOSequentialFileFactory aioFactory;
+
+ private final ReusableLatch pendingCallbacks = new ReusableLatch();
+
+ /**
+ * Used to determine the next writing sequence
+ */
+ private final AtomicLong nextWritingSequence = new AtomicLong(0);
+
+ /**
+ * AIO can't guarantee ordering over callbacks.
+ * <br>
+ * We use this {@link PriorityQueue} to hold values until they are in order
+ */
+ final PriorityQueue<AIOSequentialFileFactory.AIOSequentialCallback> pendingCallbackList = new PriorityQueue<>();
+
+ /**
+ * Used to determine the next writing sequence.
+ * This is accessed from a single thread (the Poller Thread)
+ */
+ private long nextReadSequence = 0;
+
+
+ public AIOSequentialFile(final AIOSequentialFileFactory factory,
+ final int bufferSize,
+ final long bufferTimeoutMilliseconds,
+ final File directory,
+ final String fileName,
+ final Executor writerExecutor)
+ {
+ super(directory, fileName, factory, writerExecutor);
+ this.aioFactory = factory;
+ }
+
+ public boolean isOpen()
+ {
+ return opened;
+ }
+
+ public int getAlignment()
+ {
+ checkOpened();
+
+ return aioFile.getBlockSize();
+ }
+
+ public int calculateBlockStart(final int position)
+ {
+ int alignment = getAlignment();
+
+ int pos = (position / alignment + (position % alignment != 0 ? 1 : 0)) * alignment;
+
+ return pos;
+ }
+
+ public SequentialFile cloneFile()
+ {
+ return new AIOSequentialFile(aioFactory,
+ -1,
+ -1,
+ getFile().getParentFile(),
+ getFile().getName(),
+ writerExecutor);
+ }
+
+ @Override
+ public synchronized void close() throws IOException, InterruptedException, ActiveMQException
+ {
+ if (!opened)
+ {
+ return;
+ }
+
+ super.close();
+
+ if (!pendingCallbacks.await(10, TimeUnit.SECONDS))
+ {
+ factory.onIOError(new IOException("Timeout on close"), "Timeout on close", this);
+ }
+
+ opened = false;
+
+ timedBuffer = null;
+
+ aioFile.close();
+ aioFile = null;
+ }
+
+
+ public synchronized void fill(final int size) throws Exception
+ {
+ checkOpened();
+ aioFile.fill(size);
+
+ fileSize = aioFile.getSize();
+ }
+
+ public void open() throws Exception
+ {
+ open(aioFactory.getMaxIO(), true);
+ }
+
+ public synchronized void open(final int maxIO, final boolean useExecutor) throws ActiveMQException
+ {
+ opened = true;
+
+ try
+ {
+ aioFile = aioFactory.libaioContext.openFile(getFile(), true);
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(e, e.getMessage(), this);
+ throw new ActiveMQNativeIOError(e.getMessage(), e);
+ }
+
+ position.set(0);
+
+ fileSize = aioFile.getSize();
+ }
+
+ public int read(final ByteBuffer bytes, final IOCallback callback) throws ActiveMQException
+ {
+ checkOpened();
+ int bytesToRead = bytes.limit();
+
+ long positionToRead = position.getAndAdd(bytesToRead);
+
+ bytes.rewind();
+
+ try
+ {
+ // We don't send the buffer to the callback on read,
+ // because we want the buffer available.
+ // Sending it through the callback would make it released
+ aioFile.read(positionToRead, bytesToRead, bytes, getCallback(callback, null));
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(e, e.getMessage(), this);
+ throw new ActiveMQNativeIOError(e.getMessage(), e);
+ }
+
+ return bytesToRead;
+ }
+
+ public int read(final ByteBuffer bytes) throws Exception
+ {
+ SimpleWaitIOCallback waitCompletion = new SimpleWaitIOCallback();
+
+ int bytesRead = read(bytes, waitCompletion);
+
+ waitCompletion.waitCompletion();
+
+ return bytesRead;
+ }
+
+ public void writeDirect(final ByteBuffer bytes, final boolean sync) throws Exception
+ {
+ if (sync)
+ {
+ SimpleWaitIOCallback completion = new SimpleWaitIOCallback();
+
+ writeDirect(bytes, true, completion);
+
+ completion.waitCompletion();
+ }
+ else
+ {
+ writeDirect(bytes, false, DummyCallback.getInstance());
+ }
+ }
+
+ /**
+ *
+ * Note: Parameter sync is not used on AIO
+ * */
+ public void writeDirect(final ByteBuffer bytes, final boolean sync, final IOCallback callback)
+ {
+ checkOpened();
+
+ final int bytesToWrite = factory.calculateBlockSize(bytes.limit());
+
+ final long positionToWrite = position.getAndAdd(bytesToWrite);
+
+ AIOSequentialFileFactory.AIOSequentialCallback runnableCallback = getCallback(callback, bytes);
+ runnableCallback.initWrite(positionToWrite, bytesToWrite);
+ if (writerExecutor != null)
+ {
+ writerExecutor.execute(runnableCallback);
+ }
+ else
+ {
+ runnableCallback.run();
+ }
+ }
+
+
+
+ AIOSequentialFileFactory.AIOSequentialCallback getCallback(IOCallback originalCallback, ByteBuffer buffer)
+ {
+ AIOSequentialFileFactory.AIOSequentialCallback callback = aioFactory.getCallback();
+ callback.init(this.nextWritingSequence.getAndIncrement(), originalCallback, aioFile, this, buffer);
+ pendingCallbacks.countUp();
+ return callback;
+ }
+
+
+ void done(AIOSequentialFileFactory.AIOSequentialCallback callback)
+ {
+ if (callback.writeSequence == -1)
+ {
+ callback.sequentialDone();
+ pendingCallbacks.countDown();
+ }
+
+
+ if (callback.writeSequence == nextReadSequence)
+ {
+ nextReadSequence++;
+ callback.sequentialDone();
+ pendingCallbacks.countDown();
+ flushCallbacks();
+ }
+ else
+ {
+ pendingCallbackList.add(callback);
+ }
+
+ }
+
+ private void flushCallbacks()
+ {
+ while (!pendingCallbackList.isEmpty() && pendingCallbackList.peek().writeSequence == nextReadSequence)
+ {
+ AIOSequentialFileFactory.AIOSequentialCallback callback = pendingCallbackList.poll();
+ callback.sequentialDone();
+ nextReadSequence++;
+ pendingCallbacks.countDown();
+ }
+ }
+
+ public void sync()
+ {
+ throw new UnsupportedOperationException("This method is not supported on AIO");
+ }
+
+ public long size() throws Exception
+ {
+ if (aioFile == null)
+ {
+ return getFile().length();
+ }
+ else
+ {
+ return aioFile.getSize();
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return "AIOSequentialFile:" + getFile().getAbsolutePath();
+ }
+
+ // Protected methods
+ // -----------------------------------------------------------------------------------------------------
+
+ @Override
+ protected ByteBuffer newBuffer(int size, int limit)
+ {
+ size = factory.calculateBlockSize(size);
+ limit = factory.calculateBlockSize(limit);
+
+ ByteBuffer buffer = factory.newBuffer(size);
+ buffer.limit(limit);
+ return buffer;
+ }
+
+ // Private methods
+ // -----------------------------------------------------------------------------------------------------
+
+ private void checkOpened()
+ {
+ if (aioFile == null || !opened)
+ {
+ throw new NullPointerException("File not opened, file=null");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java
new file mode 100644
index 0000000..39dad2f
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java
@@ -0,0 +1,531 @@
+/*
+ * 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.core.io.aio;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
+import org.apache.activemq.artemis.core.io.AbstractSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
+import org.apache.activemq.artemis.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
+import org.apache.activemq.artemis.jlibaio.SubmitInfo;
+import org.apache.activemq.artemis.jlibaio.util.CallbackCache;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
+
+public final class AIOSequentialFileFactory extends AbstractSequentialFileFactory
+{
+ private static final boolean trace = ActiveMQJournalLogger.LOGGER.isTraceEnabled();
+
+ private final ReuseBuffersController buffersControl = new ReuseBuffersController();
+
+ private volatile boolean reuseBuffers = true;
+
+ private ExecutorService pollerExecutor;
+
+ volatile LibaioContext<AIOSequentialCallback> libaioContext;
+
+ private final CallbackCache<AIOSequentialCallback> callbackPool;
+
+ private final AtomicBoolean running = new AtomicBoolean(false);
+
+ // This method exists just to make debug easier.
+ // I could replace log.trace by log.info temporarily while I was debugging
+ // Journal
+ private static void trace(final String message)
+ {
+ ActiveMQJournalLogger.LOGGER.trace(message);
+ }
+
+ public AIOSequentialFileFactory(final File journalDir, int maxIO)
+ {
+ this(journalDir,
+ JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
+ JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
+ maxIO,
+ false,
+ null);
+ }
+
+ public AIOSequentialFileFactory(final File journalDir, final IOCriticalErrorListener listener, int maxIO)
+ {
+ this(journalDir,
+ JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO,
+ JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO,
+ maxIO,
+ false,
+ listener);
+ }
+
+ public AIOSequentialFileFactory(final File journalDir,
+ final int bufferSize,
+ final int bufferTimeout,
+ final int maxIO,
+ final boolean logRates)
+ {
+ this(journalDir, bufferSize, bufferTimeout, maxIO, logRates, null);
+ }
+
+ public AIOSequentialFileFactory(final File journalDir,
+ final int bufferSize,
+ final int bufferTimeout,
+ final int maxIO,
+ final boolean logRates,
+ final IOCriticalErrorListener listener)
+ {
+ super(journalDir, true, bufferSize, bufferTimeout, maxIO, logRates, listener);
+ callbackPool = new CallbackCache<>(maxIO);
+ }
+
+ public AIOSequentialCallback getCallback()
+ {
+ AIOSequentialCallback callback = callbackPool.get();
+ if (callback == null)
+ {
+ callback = new AIOSequentialCallback();
+ }
+
+ return callback;
+ }
+
+ public void enableBufferReuse()
+ {
+ this.reuseBuffers = true;
+ }
+
+ public void disableBufferReuse()
+ {
+ this.reuseBuffers = false;
+ }
+
+
+ public SequentialFile createSequentialFile(final String fileName)
+ {
+ return new AIOSequentialFile(this,
+ bufferSize,
+ bufferTimeout,
+ journalDir,
+ fileName,
+ writeExecutor);
+ }
+
+ public boolean isSupportsCallbacks()
+ {
+ return true;
+ }
+
+ public static boolean isSupported()
+ {
+ return LibaioContext.isLoaded();
+ }
+
+ public ByteBuffer allocateDirectBuffer(final int size)
+ {
+
+ int blocks = size / 512;
+ if (size % 512 != 0)
+ {
+ blocks++;
+ }
+
+ // The buffer on AIO has to be a multiple of 512
+ ByteBuffer buffer = LibaioContext.newAlignedBuffer(blocks * 512, 512);
+
+ buffer.limit(size);
+
+ return buffer;
+ }
+
+ public void releaseDirectBuffer(final ByteBuffer buffer)
+ {
+ LibaioContext.freeBuffer(buffer);
+ }
+
+ public ByteBuffer newBuffer(int size)
+ {
+ if (size % 512 != 0)
+ {
+ size = (size / 512 + 1) * 512;
+ }
+
+ return buffersControl.newBuffer(size);
+ }
+
+ public void clearBuffer(final ByteBuffer directByteBuffer)
+ {
+ directByteBuffer.position(0);
+ libaioContext.memsetBuffer(directByteBuffer);
+ }
+
+ public int getAlignment()
+ {
+ return 512;
+ }
+
+ // For tests only
+ public ByteBuffer wrapBuffer(final byte[] bytes)
+ {
+ ByteBuffer newbuffer = newBuffer(bytes.length);
+ newbuffer.put(bytes);
+ return newbuffer;
+ }
+
+ public int calculateBlockSize(final int position)
+ {
+ int alignment = getAlignment();
+
+ int pos = (position / alignment + (position % alignment != 0 ? 1 : 0)) * alignment;
+
+ return pos;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.activemq.artemis.core.io.SequentialFileFactory#releaseBuffer(java.nio.ByteBuffer)
+ */
+ @Override
+ public synchronized void releaseBuffer(final ByteBuffer buffer)
+ {
+ LibaioContext.freeBuffer(buffer);
+ }
+
+ @Override
+ public void start()
+ {
+ if (running.compareAndSet(false, true))
+ {
+ super.start();
+
+ this.libaioContext = new LibaioContext(maxIO, true);
+
+ this.running.set(true);
+
+ pollerExecutor = Executors.newCachedThreadPool(new ActiveMQThreadFactory("ActiveMQ-AIO-poller-pool" + System.identityHashCode(this),
+ true,
+ AIOSequentialFileFactory.getThisClassLoader()));
+
+ pollerExecutor.execute(new PollerRunnable());
+ }
+
+ }
+
+ @Override
+ public void stop()
+ {
+ if (this.running.compareAndSet(true, false))
+ {
+ buffersControl.stop();
+
+ libaioContext.close();
+ libaioContext = null;
+
+ if (pollerExecutor != null)
+ {
+ pollerExecutor.shutdown();
+
+ try
+ {
+ if (!pollerExecutor.awaitTermination(AbstractSequentialFileFactory.EXECUTOR_TIMEOUT, TimeUnit.SECONDS))
+ {
+ ActiveMQJournalLogger.LOGGER.timeoutOnPollerShutdown(new Exception("trace"));
+ }
+ }
+ catch (InterruptedException e)
+ {
+ throw new ActiveMQInterruptedException(e);
+ }
+ }
+
+ super.stop();
+ }
+ }
+
+ @Override
+ protected void finalize()
+ {
+ stop();
+ }
+
+ /**
+ * The same callback is used for Runnable executor.
+ * This way we can save some memory over the pool.
+ */
+ public class AIOSequentialCallback implements SubmitInfo, Runnable, Comparable<AIOSequentialCallback>
+ {
+ IOCallback callback;
+ boolean error = false;
+ AIOSequentialFile sequentialFile;
+ ByteBuffer buffer;
+ LibaioFile libaioFile;
+ String errorMessage;
+ int errorCode = -1;
+ long writeSequence;
+
+ long position;
+ int bytes;
+
+ @Override
+ public String toString()
+ {
+ return "AIOSequentialCallback{" +
+ "error=" + error +
+ ", errorMessage='" + errorMessage + '\'' +
+ ", errorCode=" + errorCode +
+ ", writeSequence=" + writeSequence +
+ ", position=" + position +
+ '}';
+ }
+
+ public AIOSequentialCallback initWrite(long positionToWrite, int bytesToWrite)
+ {
+ this.position = positionToWrite;
+ this.bytes = bytesToWrite;
+ return this;
+ }
+
+ public void run()
+ {
+ try
+ {
+ libaioFile.write(position, bytes, buffer, this);
+ }
+ catch (IOException e)
+ {
+ callback.onError(-1, e.getMessage());
+ }
+ }
+
+ public int compareTo(AIOSequentialCallback other)
+ {
+ if (this == other || this.writeSequence == other.writeSequence)
+ {
+ return 0;
+ }
+ else if (other.writeSequence < this.writeSequence)
+ {
+ return 1;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ public AIOSequentialCallback init(long writeSequence, IOCallback IOCallback, LibaioFile libaioFile, AIOSequentialFile sequentialFile, ByteBuffer usedBuffer)
+ {
+ this.callback = IOCallback;
+ this.sequentialFile = sequentialFile;
+ this.error = false;
+ this.buffer = usedBuffer;
+ this.libaioFile = libaioFile;
+ this.writeSequence = writeSequence;
+ this.errorMessage = null;
+ return this;
+ }
+
+ @Override
+ public void onError(int errno, String message)
+ {
+ this.error = true;
+ this.errorCode = errno;
+ this.errorMessage = message;
+ }
+
+ /**
+ * this is called by libaio.
+ */
+ public void done()
+ {
+ this.sequentialFile.done(this);
+ }
+
+ /**
+ * This is callbed by the AIOSequentialFile, after determined the callbacks were returned in sequence
+ */
+ public void sequentialDone()
+ {
+
+ if (error)
+ {
+ callback.onError(errorCode, errorMessage);
+ errorMessage = null;
+ }
+ else
+ {
+ if (callback != null)
+ {
+ callback.done();
+ }
+
+ if (buffer != null && reuseBuffers)
+ {
+ buffersControl.bufferDone(buffer);
+ }
+
+ callbackPool.put(AIOSequentialCallback.this);
+ }
+ }
+ }
+
+ private class PollerRunnable implements Runnable
+ {
+ public void run()
+ {
+ libaioContext.poll();
+ }
+ }
+
+ /**
+ * Class that will control buffer-reuse
+ */
+ private class ReuseBuffersController
+ {
+ private volatile long bufferReuseLastTime = System.currentTimeMillis();
+
+ private final ConcurrentLinkedQueue<ByteBuffer> reuseBuffersQueue = new ConcurrentLinkedQueue<ByteBuffer>();
+
+ private boolean stopped = false;
+
+ public ByteBuffer newBuffer(final int size)
+ {
+ // if a new buffer wasn't requested in 10 seconds, we clear the queue
+ // This is being done this way as we don't need another Timeout Thread
+ // just to cleanup this
+ if (bufferSize > 0 && System.currentTimeMillis() - bufferReuseLastTime > 10000)
+ {
+ if (AIOSequentialFileFactory.trace)
+ {
+ AIOSequentialFileFactory.trace("Clearing reuse buffers queue with " + reuseBuffersQueue.size() +
+ " elements");
+ }
+
+ bufferReuseLastTime = System.currentTimeMillis();
+
+ clearPoll();
+ }
+
+ // if a buffer is bigger than the configured-bufferSize, we just create a new
+ // buffer.
+ if (size > bufferSize)
+ {
+ return LibaioContext.newAlignedBuffer(size, 512);
+ }
+ else
+ {
+ // We need to allocate buffers following the rules of the storage
+ // being used (AIO/NIO)
+ int alignedSize = calculateBlockSize(size);
+
+ // Try getting a buffer from the queue...
+ ByteBuffer buffer = reuseBuffersQueue.poll();
+
+ if (buffer == null)
+ {
+ // if empty create a new one.
+ buffer = LibaioContext.newAlignedBuffer(size, 512);
+
+ buffer.limit(alignedSize);
+ }
+ else
+ {
+ clearBuffer(buffer);
+
+ // set the limit of the buffer to the bufferSize being required
+ buffer.limit(alignedSize);
+ }
+
+ buffer.rewind();
+
+ return buffer;
+ }
+ }
+
+ public synchronized void stop()
+ {
+ stopped = true;
+ clearPoll();
+ }
+
+ public synchronized void clearPoll()
+ {
+ ByteBuffer reusedBuffer;
+
+ while ((reusedBuffer = reuseBuffersQueue.poll()) != null)
+ {
+ releaseBuffer(reusedBuffer);
+ }
+ }
+
+ public void bufferDone(final ByteBuffer buffer)
+ {
+ synchronized (this)
+ {
+
+ if (stopped)
+ {
+ releaseBuffer(buffer);
+ }
+ else
+ {
+ bufferReuseLastTime = System.currentTimeMillis();
+
+ // If a buffer has any other than the configured bufferSize, the buffer
+ // will be just sent to GC
+ if (buffer.capacity() == bufferSize)
+ {
+ reuseBuffersQueue.offer(buffer);
+ }
+ else
+ {
+ releaseBuffer(buffer);
+ }
+ }
+ }
+ }
+ }
+
+ private static ClassLoader getThisClassLoader()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return AIOSequentialFileFactory.class.getClassLoader();
+ }
+ });
+
+ }
+
+ @Override
+ public String toString()
+ {
+ return AIOSequentialFileFactory.class.getSimpleName() + "(buffersControl.stopped=" + buffersControl.stopped +
+ "):" + super.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/ActiveMQFileLock.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/ActiveMQFileLock.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/ActiveMQFileLock.java
new file mode 100644
index 0000000..a184244
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/ActiveMQFileLock.java
@@ -0,0 +1,47 @@
+/*
+ * 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.core.io.aio;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+
+import org.apache.activemq.artemis.jlibaio.LibaioFile;
+
+public class ActiveMQFileLock extends FileLock
+{
+
+ private final LibaioFile file;
+
+ public ActiveMQFileLock(final LibaioFile handle)
+ {
+ super((FileChannel)null, 0, 0, false);
+ this.file = handle;
+ }
+
+ @Override
+ public boolean isValid()
+ {
+ return true;
+ }
+
+ @Override
+ public void release() throws IOException
+ {
+ file.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBuffer.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBuffer.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBuffer.java
new file mode 100644
index 0000000..a61569a
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBuffer.java
@@ -0,0 +1,558 @@
+/*
+ * 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.core.io.buffer;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
+import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.journal.EncodingSupport;
+import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+
+public class TimedBuffer
+{
+ // Constants -----------------------------------------------------
+
+ // The number of tries on sleep before switching to spin
+ public static final int MAX_CHECKS_ON_SLEEP = 20;
+
+ // Attributes ----------------------------------------------------
+
+ private TimedBufferObserver bufferObserver;
+
+ // If the TimedBuffer is idle - i.e. no records are being added, then it's pointless the timer flush thread
+ // in spinning and checking the time - and using up CPU in the process - this semaphore is used to
+ // prevent that
+ private final Semaphore spinLimiter = new Semaphore(1);
+
+ private CheckTimer timerRunnable = new CheckTimer();
+
+ private final int bufferSize;
+
+ private final ActiveMQBuffer buffer;
+
+ private int bufferLimit = 0;
+
+ private List<IOCallback> callbacks;
+
+ private volatile int timeout;
+
+ // used to measure sync requests. When a sync is requested, it shouldn't take more than timeout to happen
+ private volatile boolean pendingSync = false;
+
+ private Thread timerThread;
+
+ private volatile boolean started;
+
+ // We use this flag to prevent flush occurring between calling checkSize and addBytes
+ // CheckSize must always be followed by it's corresponding addBytes otherwise the buffer
+ // can get in an inconsistent state
+ private boolean delayFlush;
+
+ // for logging write rates
+
+ private final boolean logRates;
+
+ private final AtomicLong bytesFlushed = new AtomicLong(0);
+
+ private final AtomicLong flushesDone = new AtomicLong(0);
+
+ private Timer logRatesTimer;
+
+ private TimerTask logRatesTimerTask;
+
+ private boolean useSleep = true;
+
+ // no need to be volatile as every access is synchronized
+ private boolean spinning = false;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+
+ public TimedBuffer(final int size, final int timeout, final boolean logRates)
+ {
+ bufferSize = size;
+
+ this.logRates = logRates;
+
+ if (logRates)
+ {
+ logRatesTimer = new Timer(true);
+ }
+ // Setting the interval for nano-sleeps
+
+ buffer = ActiveMQBuffers.fixedBuffer(bufferSize);
+
+ buffer.clear();
+
+ bufferLimit = 0;
+
+ callbacks = new ArrayList<IOCallback>();
+
+ this.timeout = timeout;
+ }
+
+ // for Debug purposes
+ public synchronized boolean isUseSleep()
+ {
+ return useSleep;
+ }
+
+ public synchronized void setUseSleep(boolean useSleep)
+ {
+ this.useSleep = useSleep;
+ }
+
+ public synchronized void start()
+ {
+ if (started)
+ {
+ return;
+ }
+
+ // Need to start with the spin limiter acquired
+ try
+ {
+ spinLimiter.acquire();
+ }
+ catch (InterruptedException e)
+ {
+ throw new ActiveMQInterruptedException(e);
+ }
+
+ timerRunnable = new CheckTimer();
+
+ timerThread = new Thread(timerRunnable, "activemq-buffer-timeout");
+
+ timerThread.start();
+
+ if (logRates)
+ {
+ logRatesTimerTask = new LogRatesTimerTask();
+
+ logRatesTimer.scheduleAtFixedRate(logRatesTimerTask, 2000, 2000);
+ }
+
+ started = true;
+ }
+
+ public void stop()
+ {
+ if (!started)
+ {
+ return;
+ }
+
+ flush();
+
+ bufferObserver = null;
+
+ timerRunnable.close();
+
+ spinLimiter.release();
+
+ if (logRates)
+ {
+ logRatesTimerTask.cancel();
+ }
+
+ while (timerThread.isAlive())
+ {
+ try
+ {
+ timerThread.join();
+ }
+ catch (InterruptedException e)
+ {
+ throw new ActiveMQInterruptedException(e);
+ }
+ }
+
+ started = false;
+ }
+
+ public synchronized void setObserver(final TimedBufferObserver observer)
+ {
+ if (bufferObserver != null)
+ {
+ flush();
+ }
+
+ bufferObserver = observer;
+ }
+
+ /**
+ * Verify if the size fits the buffer
+ *
+ * @param sizeChecked
+ */
+ public synchronized boolean checkSize(final int sizeChecked)
+ {
+ if (!started)
+ {
+ throw new IllegalStateException("TimedBuffer is not started");
+ }
+
+ if (sizeChecked > bufferSize)
+ {
+ throw new IllegalStateException("Can't write records bigger than the bufferSize(" + bufferSize +
+ ") on the journal");
+ }
+
+ if (bufferLimit == 0 || buffer.writerIndex() + sizeChecked > bufferLimit)
+ {
+ // Either there is not enough space left in the buffer for the sized record
+ // Or a flush has just been performed and we need to re-calcualate bufferLimit
+
+ flush();
+
+ delayFlush = true;
+
+ final int remainingInFile = bufferObserver.getRemainingBytes();
+
+ if (sizeChecked > remainingInFile)
+ {
+ return false;
+ }
+ else
+ {
+ // There is enough space in the file for this size
+
+ // Need to re-calculate buffer limit
+
+ bufferLimit = Math.min(remainingInFile, bufferSize);
+
+ return true;
+ }
+ }
+ else
+ {
+ delayFlush = true;
+
+ return true;
+ }
+ }
+
+ public synchronized void addBytes(final ActiveMQBuffer bytes, final boolean sync, final IOCallback callback)
+ {
+ addBytes(new ByteArrayEncoding(bytes.toByteBuffer().array()), sync, callback);
+ }
+
+ public synchronized void addBytes(final EncodingSupport bytes, final boolean sync, final IOCallback callback)
+ {
+ if (!started)
+ {
+ throw new IllegalStateException("TimedBuffer is not started");
+ }
+
+ delayFlush = false;
+
+ bytes.encode(buffer);
+
+ callbacks.add(callback);
+
+ if (sync)
+ {
+ pendingSync = true;
+
+ startSpin();
+ }
+
+ }
+
+ public void flush()
+ {
+ flush(false);
+ }
+
+ /**
+ * force means the Journal is moving to a new file. Any pending write need to be done immediately
+ * or data could be lost
+ */
+ public void flush(final boolean force)
+ {
+ synchronized (this)
+ {
+ if (!started)
+ {
+ throw new IllegalStateException("TimedBuffer is not started");
+ }
+
+ if ((force || !delayFlush) && buffer.writerIndex() > 0)
+ {
+ int pos = buffer.writerIndex();
+
+ if (logRates)
+ {
+ bytesFlushed.addAndGet(pos);
+ }
+
+ ByteBuffer bufferToFlush = bufferObserver.newBuffer(bufferSize, pos);
+
+ // Putting a byteArray on a native buffer is much faster, since it will do in a single native call.
+ // Using bufferToFlush.put(buffer) would make several append calls for each byte
+ // We also transfer the content of this buffer to the native file's buffer
+
+ bufferToFlush.put(buffer.toByteBuffer().array(), 0, pos);
+
+ bufferObserver.flushBuffer(bufferToFlush, pendingSync, callbacks);
+
+ stopSpin();
+
+ pendingSync = false;
+
+ // swap the instance as the previous callback list is being used asynchronously
+ callbacks = new LinkedList<IOCallback>();
+
+ buffer.clear();
+
+ bufferLimit = 0;
+
+ flushesDone.incrementAndGet();
+ }
+ }
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+ private class LogRatesTimerTask extends TimerTask
+ {
+ private boolean closed;
+
+ private long lastExecution;
+
+ private long lastBytesFlushed;
+
+ private long lastFlushesDone;
+
+ @Override
+ public synchronized void run()
+ {
+ if (!closed)
+ {
+ long now = System.currentTimeMillis();
+
+ long bytesF = bytesFlushed.get();
+ long flushesD = flushesDone.get();
+
+ if (lastExecution != 0)
+ {
+ double rate = 1000 * (double) (bytesF - lastBytesFlushed) / (now - lastExecution);
+ ActiveMQJournalLogger.LOGGER.writeRate(rate, (long) (rate / (1024 * 1024)));
+ double flushRate = 1000 * (double) (flushesD - lastFlushesDone) / (now - lastExecution);
+ ActiveMQJournalLogger.LOGGER.flushRate(flushRate);
+ }
+
+ lastExecution = now;
+
+ lastBytesFlushed = bytesF;
+
+ lastFlushesDone = flushesD;
+ }
+ }
+
+ @Override
+ public synchronized boolean cancel()
+ {
+ closed = true;
+
+ return super.cancel();
+ }
+ }
+
+ private class CheckTimer implements Runnable
+ {
+ private volatile boolean closed = false;
+
+ int checks = 0;
+ int failedChecks = 0;
+ long timeBefore = 0;
+
+ final int sleepMillis = timeout / 1000000; // truncates
+ final int sleepNanos = timeout % 1000000;
+
+
+ public void run()
+ {
+ long lastFlushTime = 0;
+
+ while (!closed)
+ {
+ // We flush on the timer if there are pending syncs there and we've waited at least one
+ // timeout since the time of the last flush.
+ // Effectively flushing "resets" the timer
+ // On the timeout verification, notice that we ignore the timeout check if we are using sleep
+
+ if (pendingSync)
+ {
+ if (isUseSleep())
+ {
+ // if using sleep, we will always flush
+ flush();
+ lastFlushTime = System.nanoTime();
+ }
+ else if (bufferObserver != null && System.nanoTime() > lastFlushTime + timeout)
+ {
+ // if not using flush we will spin and do the time checks manually
+ flush();
+ lastFlushTime = System.nanoTime();
+ }
+
+ }
+
+ sleepIfPossible();
+
+ try
+ {
+ spinLimiter.acquire();
+
+ Thread.yield();
+
+ spinLimiter.release();
+ }
+ catch (InterruptedException e)
+ {
+ throw new ActiveMQInterruptedException(e);
+ }
+ }
+ }
+
+ /**
+ * We will attempt to use sleep only if the system supports nano-sleep
+ * we will on that case verify up to MAX_CHECKS if nano sleep is behaving well.
+ * if more than 50% of the checks have failed we will cancel the sleep and just use regular spin
+ */
+ private void sleepIfPossible()
+ {
+ if (isUseSleep())
+ {
+ if (checks < MAX_CHECKS_ON_SLEEP)
+ {
+ timeBefore = System.nanoTime();
+ }
+
+ try
+ {
+ sleep(sleepMillis, sleepNanos);
+ }
+ catch (InterruptedException e)
+ {
+ throw new ActiveMQInterruptedException(e);
+ }
+ catch (Exception e)
+ {
+ setUseSleep(false);
+ ActiveMQJournalLogger.LOGGER.warn(e.getMessage() + ", disabling sleep on TimedBuffer, using spin now", e);
+ }
+
+ if (checks < MAX_CHECKS_ON_SLEEP)
+ {
+ long realTimeSleep = System.nanoTime() - timeBefore;
+
+ // I'm letting the real time to be up to 50% than the requested sleep.
+ if (realTimeSleep > timeout * 1.5)
+ {
+ failedChecks++;
+ }
+
+ if (++checks >= MAX_CHECKS_ON_SLEEP)
+ {
+ if (failedChecks > MAX_CHECKS_ON_SLEEP * 0.5)
+ {
+ ActiveMQJournalLogger.LOGGER.debug("Thread.sleep with nano seconds is not working as expected, Your kernel possibly doesn't support real time. the Journal TimedBuffer will spin for timeouts");
+ setUseSleep(false);
+ }
+ }
+ }
+ }
+ }
+
+ public void close()
+ {
+ closed = true;
+ }
+ }
+
+ /**
+ * Sub classes (tests basically) can use this to override how the sleep is being done
+ *
+ * @param sleepMillis
+ * @param sleepNanos
+ * @throws InterruptedException
+ */
+ protected void sleep(int sleepMillis, int sleepNanos) throws InterruptedException
+ {
+ Thread.sleep(sleepMillis, sleepNanos);
+ }
+
+ /**
+ * Sub classes (tests basically) can use this to override disabling spinning
+ */
+ protected void stopSpin()
+ {
+ if (spinning)
+ {
+ try
+ {
+ // We acquire the spinLimiter semaphore - this prevents the timer flush thread unnecessarily spinning
+ // when the buffer is inactive
+ spinLimiter.acquire();
+ }
+ catch (InterruptedException e)
+ {
+ throw new ActiveMQInterruptedException(e);
+ }
+
+ spinning = false;
+ }
+ }
+
+
+ /**
+ * Sub classes (tests basically) can use this to override disabling spinning
+ */
+ protected void startSpin()
+ {
+ if (!spinning)
+ {
+ spinLimiter.release();
+
+ spinning = true;
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBufferObserver.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBufferObserver.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBufferObserver.java
new file mode 100644
index 0000000..7a9659f
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/buffer/TimedBufferObserver.java
@@ -0,0 +1,53 @@
+/*
+ * 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.core.io.buffer;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.apache.activemq.artemis.core.io.IOCallback;
+
+
+public interface TimedBufferObserver
+{
+
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+
+ void flushBuffer(ByteBuffer buffer, boolean syncRequested, List<IOCallback> callbacks);
+
+ /** Return the number of remaining bytes that still fit on the observer (file) */
+ int getRemainingBytes();
+
+ ByteBuffer newBuffer(int size, int limit);
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFile.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFile.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFile.java
new file mode 100644
index 0000000..d20045e
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFile.java
@@ -0,0 +1,393 @@
+/*
+ * 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.core.io.nio;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
+import org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.AbstractSequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.journal.ActiveMQJournalBundle;
+import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
+
+public final class NIOSequentialFile extends AbstractSequentialFile
+{
+ private FileChannel channel;
+
+ private RandomAccessFile rfile;
+
+ /**
+ * The write semaphore here is only used when writing asynchronously
+ */
+ private Semaphore maxIOSemaphore;
+
+ private final int defaultMaxIO;
+
+ private int maxIO;
+
+ public NIOSequentialFile(final SequentialFileFactory factory,
+ final File directory,
+ final String file,
+ final int maxIO,
+ final Executor writerExecutor)
+ {
+ super(directory, file, factory, writerExecutor);
+ defaultMaxIO = maxIO;
+ }
+
+ public int getAlignment()
+ {
+ return 1;
+ }
+
+ public int calculateBlockStart(final int position)
+ {
+ return position;
+ }
+
+ public synchronized boolean isOpen()
+ {
+ return channel != null;
+ }
+
+ /**
+ * this.maxIO represents the default maxIO.
+ * Some operations while initializing files on the journal may require a different maxIO
+ */
+ public synchronized void open() throws IOException
+ {
+ open(defaultMaxIO, true);
+ }
+
+ public void open(final int maxIO, final boolean useExecutor) throws IOException
+ {
+ try
+ {
+ rfile = new RandomAccessFile(getFile(), "rw");
+
+ channel = rfile.getChannel();
+
+ fileSize = channel.size();
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+ throw e;
+ }
+
+ if (writerExecutor != null && useExecutor)
+ {
+ maxIOSemaphore = new Semaphore(maxIO);
+ this.maxIO = maxIO;
+ }
+ }
+
+ public void fill(final int size) throws IOException
+ {
+ ByteBuffer bb = ByteBuffer.allocate(size);
+
+ bb.limit(size);
+ bb.position(0);
+
+ try
+ {
+ channel.position(0);
+ channel.write(bb);
+ channel.force(false);
+ channel.position(0);
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+ throw e;
+ }
+
+ fileSize = channel.size();
+ }
+
+ @Override
+ public synchronized void close() throws IOException, InterruptedException, ActiveMQException
+ {
+ super.close();
+
+ if (maxIOSemaphore != null)
+ {
+ while (!maxIOSemaphore.tryAcquire(maxIO, 60, TimeUnit.SECONDS))
+ {
+ ActiveMQJournalLogger.LOGGER.errorClosingFile(getFileName());
+ }
+ }
+
+ maxIOSemaphore = null;
+ try
+ {
+ if (channel != null)
+ {
+ channel.close();
+ }
+
+ if (rfile != null)
+ {
+ rfile.close();
+ }
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+ throw e;
+ }
+ channel = null;
+
+ rfile = null;
+
+ notifyAll();
+ }
+
+ public int read(final ByteBuffer bytes) throws Exception
+ {
+ return read(bytes, null);
+ }
+
+ public synchronized int read(final ByteBuffer bytes, final IOCallback callback) throws IOException,
+ ActiveMQIllegalStateException
+ {
+ try
+ {
+ if (channel == null)
+ {
+ throw new ActiveMQIllegalStateException("File " + this.getFileName() + " has a null channel");
+ }
+ int bytesRead = channel.read(bytes);
+
+ if (callback != null)
+ {
+ callback.done();
+ }
+
+ bytes.flip();
+
+ return bytesRead;
+ }
+ catch (IOException e)
+ {
+ if (callback != null)
+ {
+ callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getLocalizedMessage());
+ }
+
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+
+ throw e;
+ }
+ }
+
+ public void sync() throws IOException
+ {
+ if (channel != null)
+ {
+ try
+ {
+ channel.force(false);
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+ throw e;
+ }
+ }
+ }
+
+ public long size() throws IOException
+ {
+ if (channel == null)
+ {
+ return getFile().length();
+ }
+
+ try
+ {
+ return channel.size();
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+ throw e;
+ }
+ }
+
+ @Override
+ public void position(final long pos) throws IOException
+ {
+ try
+ {
+ super.position(pos);
+ channel.position(pos);
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+ throw e;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return "NIOSequentialFile " + getFile();
+ }
+
+ public SequentialFile cloneFile()
+ {
+ return new NIOSequentialFile(factory, directory, getFileName(), maxIO, writerExecutor);
+ }
+
+ public void writeDirect(final ByteBuffer bytes, final boolean sync, final IOCallback callback)
+ {
+ if (callback == null)
+ {
+ throw new NullPointerException("callback parameter need to be set");
+ }
+
+ try
+ {
+ internalWrite(bytes, sync, callback);
+ }
+ catch (Exception e)
+ {
+ callback.onError(ActiveMQExceptionType.GENERIC_EXCEPTION.getCode(), e.getMessage());
+ }
+ }
+
+ public void writeDirect(final ByteBuffer bytes, final boolean sync) throws Exception
+ {
+ internalWrite(bytes, sync, null);
+ }
+
+ public void writeInternal(final ByteBuffer bytes) throws Exception
+ {
+ internalWrite(bytes, true, null);
+ }
+
+ @Override
+ protected ByteBuffer newBuffer(int size, final int limit)
+ {
+ // For NIO, we don't need to allocate a buffer the entire size of the timed buffer, unlike AIO
+
+ size = limit;
+
+ return super.newBuffer(size, limit);
+ }
+
+ private void internalWrite(final ByteBuffer bytes, final boolean sync, final IOCallback callback) throws IOException, ActiveMQIOErrorException, InterruptedException
+ {
+ if (!isOpen())
+ {
+ if (callback != null)
+ {
+ callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), "File not opened");
+ }
+ else
+ {
+ throw ActiveMQJournalBundle.BUNDLE.fileNotOpened();
+ }
+ return;
+ }
+
+ position.addAndGet(bytes.limit());
+
+ if (maxIOSemaphore == null || callback == null)
+ {
+ // if maxIOSemaphore == null, that means we are not using executors and the writes are synchronous
+ try
+ {
+ doInternalWrite(bytes, sync, callback);
+ }
+ catch (IOException e)
+ {
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), this);
+ }
+ }
+ else
+ {
+ // This is a flow control on writing, just like maxAIO on libaio
+ maxIOSemaphore.acquire();
+
+ writerExecutor.execute(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ try
+ {
+ doInternalWrite(bytes, sync, callback);
+ }
+ catch (IOException e)
+ {
+ ActiveMQJournalLogger.LOGGER.errorSubmittingWrite(e);
+ factory.onIOError(new ActiveMQIOErrorException(e.getMessage(), e), e.getMessage(), NIOSequentialFile.this);
+ callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getMessage());
+ }
+ catch (Throwable e)
+ {
+ ActiveMQJournalLogger.LOGGER.errorSubmittingWrite(e);
+ callback.onError(ActiveMQExceptionType.IO_ERROR.getCode(), e.getMessage());
+ }
+ }
+ finally
+ {
+ maxIOSemaphore.release();
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * @param bytes
+ * @param sync
+ * @param callback
+ * @throws IOException
+ * @throws Exception
+ */
+ private void doInternalWrite(final ByteBuffer bytes, final boolean sync, final IOCallback callback) throws IOException
+ {
+ channel.write(bytes);
+
+ if (sync)
+ {
+ sync();
+ }
+
+ if (callback != null)
+ {
+ callback.done();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFileFactory.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFileFactory.java
new file mode 100644
index 0000000..e64e405
--- /dev/null
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/nio/NIOSequentialFileFactory.java
@@ -0,0 +1,168 @@
+/*
+ * 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.core.io.nio;
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+
+import org.apache.activemq.artemis.core.io.AbstractSequentialFileFactory;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.SequentialFile;
+import org.apache.activemq.artemis.core.journal.impl.JournalConstants;
+
+public class NIOSequentialFileFactory extends AbstractSequentialFileFactory
+{
+ public NIOSequentialFileFactory(final File journalDir, final int maxIO)
+ {
+ this(journalDir, null, maxIO);
+ }
+
+ public NIOSequentialFileFactory(final File journalDir, final IOCriticalErrorListener listener, final int maxIO)
+ {
+ this(journalDir,
+ false,
+ JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO,
+ JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO,
+ maxIO,
+ false,
+ listener);
+ }
+
+ public NIOSequentialFileFactory(final File journalDir, final boolean buffered, final int maxIO)
+ {
+ this(journalDir, buffered, null, maxIO);
+ }
+
+ public NIOSequentialFileFactory(final File journalDir,
+ final boolean buffered,
+ final IOCriticalErrorListener listener, final int maxIO)
+ {
+ this(journalDir,
+ buffered,
+ JournalConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO,
+ JournalConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO,
+ maxIO,
+ false,
+ listener);
+ }
+
+ public NIOSequentialFileFactory(final File journalDir,
+ final boolean buffered,
+ final int bufferSize,
+ final int bufferTimeout,
+ final int maxIO,
+ final boolean logRates)
+ {
+ this(journalDir, buffered, bufferSize, bufferTimeout, maxIO, logRates, null);
+ }
+
+ public NIOSequentialFileFactory(final File journalDir,
+ final boolean buffered,
+ final int bufferSize,
+ final int bufferTimeout,
+ final int maxIO,
+ final boolean logRates,
+ final IOCriticalErrorListener listener)
+ {
+ super(journalDir, buffered, bufferSize, bufferTimeout, maxIO, logRates, listener);
+ }
+
+ public SequentialFile createSequentialFile(final String fileName)
+ {
+ return new NIOSequentialFile(this, journalDir, fileName, maxIO, writeExecutor);
+ }
+
+ public boolean isSupportsCallbacks()
+ {
+ return timedBuffer != null;
+ }
+
+
+ public ByteBuffer allocateDirectBuffer(final int size)
+ {
+ // Using direct buffer, as described on https://jira.jboss.org/browse/HORNETQ-467
+ ByteBuffer buffer2 = null;
+ try
+ {
+ buffer2 = ByteBuffer.allocateDirect(size);
+ }
+ catch (OutOfMemoryError error)
+ {
+ // This is a workaround for the way the JDK will deal with native buffers.
+ // the main portion is outside of the VM heap
+ // and the JDK will not have any reference about it to take GC into account
+ // so we force a GC and try again.
+ WeakReference<Object> obj = new WeakReference<Object>(new Object());
+ try
+ {
+ long timeout = System.currentTimeMillis() + 5000;
+ while (System.currentTimeMillis() > timeout && obj.get() != null)
+ {
+ System.gc();
+ Thread.sleep(100);
+ }
+ }
+ catch (InterruptedException e)
+ {
+ }
+
+ buffer2 = ByteBuffer.allocateDirect(size);
+
+ }
+ return buffer2;
+ }
+
+ public void releaseDirectBuffer(ByteBuffer buffer)
+ {
+ // nothing we can do on this case. we can just have good faith on GC
+ }
+
+ public ByteBuffer newBuffer(final int size)
+ {
+ return ByteBuffer.allocate(size);
+ }
+
+ public void clearBuffer(final ByteBuffer buffer)
+ {
+ final int limit = buffer.limit();
+ buffer.rewind();
+
+ for (int i = 0; i < limit; i++)
+ {
+ buffer.put((byte)0);
+ }
+
+ buffer.rewind();
+ }
+
+ public ByteBuffer wrapBuffer(final byte[] bytes)
+ {
+ return ByteBuffer.wrap(bytes);
+ }
+
+ public int getAlignment()
+ {
+ return 1;
+ }
+
+ public int calculateBlockSize(final int bytes)
+ {
+ return bytes;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOAsyncTask.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOAsyncTask.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOAsyncTask.java
deleted file mode 100644
index 09c80ca..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/IOAsyncTask.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.core.journal;
-
-import org.apache.activemq.artemis.core.asyncio.AIOCallback;
-
-/**
- * This class is just a direct extension of AIOCallback.
- * Just to avoid the direct dependency of org.apache.activemq.artemis.core.asynciio.AIOCallback from the journal.
- */
-public interface IOAsyncTask extends AIOCallback
-{
-}
[5/9] activemq-artemis git commit: ARTEMIS-163 First pass on the
native AIO refactoring
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/SyncSpeedTest.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/SyncSpeedTest.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/SyncSpeedTest.java
deleted file mode 100644
index 0c982dc..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/SyncSpeedTest.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executors;
-
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.SequentialFile;
-import org.apache.activemq.artemis.core.journal.SequentialFileFactory;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-/**
- * A SyncSpeedTest
- *
- * This class just provides some diagnostics on how fast your disk can sync
- * Useful when determining performance issues
- */
-public class SyncSpeedTest
-{
- public static void main(final String[] args)
- {
- try
- {
- new SyncSpeedTest().testScaleAIO();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- protected SequentialFileFactory fileFactory;
-
- public boolean AIO = true;
-
- protected void setupFactory()
- {
- if (AIO)
- {
- fileFactory = new AIOSequentialFileFactory(new File("."), 0, 0, false, null);
- }
- else
- {
- fileFactory = new NIOSequentialFileFactory(new File("."), false, 0, 0, false, null);
- }
- }
-
- protected SequentialFile createSequentialFile(final String fileName)
- {
- if (AIO)
- {
- return new AIOSequentialFile(fileFactory,
- 0,
- 0,
- new File("."),
- fileName,
- 100000,
- null,
- null,
- Executors.newSingleThreadExecutor());
- }
- else
- {
- return new NIOSequentialFile(fileFactory, new File("."), fileName, 1000, null);
- }
- }
-
- public void run2() throws Exception
- {
- setupFactory();
-
- int recordSize = 128 * 1024;
-
- while (true)
- {
- System.out.println("** record size is " + recordSize);
-
- int warmup = 500;
-
- int its = 500;
-
- int fileSize = (its + warmup) * recordSize;
-
- SequentialFile file = createSequentialFile("sync-speed-test.dat");
-
- if (file.exists())
- {
- file.delete();
- }
-
- file.open();
-
- file.fill(0, fileSize, (byte)'X');
-
- if (!AIO)
- {
- file.sync();
- }
-
- ByteBuffer bb1 = generateBuffer(recordSize, (byte)'h');
-
- long start = 0;
-
- for (int i = 0; i < its + warmup; i++)
- {
- if (i == warmup)
- {
- start = System.currentTimeMillis();
- }
-
- bb1.rewind();
-
- file.writeDirect(bb1, true);
- }
-
- long end = System.currentTimeMillis();
-
- double rate = 1000 * (double)its / (end - start);
-
- double throughput = recordSize * rate;
-
- System.out.println("Rate of " + rate + " syncs per sec");
- System.out.println("Throughput " + throughput + " bytes per sec");
- System.out.println("*************");
-
- recordSize *= 2;
- }
- }
-
- public void run() throws Exception
- {
- int recordSize = 256;
-
- while (true)
- {
- System.out.println("** record size is " + recordSize);
-
- int warmup = 500;
-
- int its = 500;
-
- int fileSize = (its + warmup) * recordSize;
-
- File file = new File("sync-speed-test.dat");
-
- if (file.exists())
- {
- if (!file.delete())
- {
- ActiveMQJournalLogger.LOGGER.errorDeletingFile(file);
- }
- }
-
- boolean created = file.createNewFile();
- if (!created)
- throw new IOException("could not create file " + file);
-
- RandomAccessFile rfile = new RandomAccessFile(file, "rw");
-
- FileChannel channel = rfile.getChannel();
-
- ByteBuffer bb = generateBuffer(fileSize, (byte)'x');
-
- write(bb, channel, fileSize);
-
- channel.force(true);
-
- channel.position(0);
-
- ByteBuffer bb1 = generateBuffer(recordSize, (byte)'h');
-
- long start = 0;
-
- for (int i = 0; i < its + warmup; i++)
- {
- if (i == warmup)
- {
- start = System.currentTimeMillis();
- }
-
- bb1.flip();
- channel.write(bb1);
- channel.force(false);
- }
-
- long end = System.currentTimeMillis();
-
- double rate = 1000 * (double)its / (end - start);
-
- double throughput = recordSize * rate;
-
- System.out.println("Rate of " + rate + " syncs per sec");
- System.out.println("Throughput " + throughput + " bytes per sec");
-
- recordSize *= 2;
- }
- }
-
- public void testScaleAIO() throws Exception
- {
- setupFactory();
-
- final int recordSize = 1024;
-
- System.out.println("** record size is " + recordSize);
-
- final int its = 10;
-
- for (int numThreads = 1; numThreads <= 10; numThreads++)
- {
-
- int fileSize = its * recordSize * numThreads;
-
- final SequentialFile file = createSequentialFile("sync-speed-test.dat");
-
- if (file.exists())
- {
- file.delete();
- }
-
- file.open();
-
- file.fill(0, fileSize, (byte)'X');
-
- if (!AIO)
- {
- file.sync();
- }
-
- final CountDownLatch latch = new CountDownLatch(its * numThreads);
-
- class MyIOAsyncTask implements IOAsyncTask
- {
- public void done()
- {
- latch.countDown();
- }
-
- public void onError(final int errorCode, final String errorMessage)
- {
-
- }
- }
-
- final MyIOAsyncTask task = new MyIOAsyncTask();
-
- class MyRunner implements Runnable
- {
- private final ByteBuffer bb1;
-
- MyRunner()
- {
- bb1 = generateBuffer(recordSize, (byte)'h');
- }
-
- public void run()
- {
- for (int i = 0; i < its; i++)
- {
- bb1.rewind();
-
- file.writeDirect(bb1, true, task);
- // try
- // {
- // file.writeDirect(bb1, true);
- // }
- // catch (Exception e)
- // {
- // e.printStackTrace();
- // }
- }
- }
- }
-
- Set<Thread> threads = new HashSet<Thread>();
-
- for (int i = 0; i < numThreads; i++)
- {
- MyRunner runner = new MyRunner();
-
- Thread t = new Thread(runner);
-
- threads.add(t);
- }
-
- long start = System.currentTimeMillis();
-
- for (Thread t : threads)
- {
- ActiveMQJournalLogger.LOGGER.startingThread();
- t.start();
- }
-
- for (Thread t : threads)
- {
- t.join();
- }
-
- latch.await();
-
- long end = System.currentTimeMillis();
-
- double rate = 1000 * (double)its * numThreads / (end - start);
-
- double throughput = recordSize * rate;
-
- System.out.println("For " + numThreads + " threads:");
- System.out.println("Rate of " + rate + " records per sec");
- System.out.println("Throughput " + throughput + " bytes per sec");
- System.out.println("*************");
- }
- }
-
- private void write(final ByteBuffer buffer, final FileChannel channel, final int size) throws Exception
- {
- buffer.flip();
-
- channel.write(buffer);
- }
-
- private ByteBuffer generateBuffer(final int size, final byte ch)
- {
- ByteBuffer bb = ByteBuffer.allocateDirect(size);
-
- for (int i = 0; i < size; i++)
- {
- bb.put(ch);
- }
-
- return bb;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBuffer.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBuffer.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBuffer.java
deleted file mode 100644
index 45d4b62..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBuffer.java
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
-import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-import org.apache.activemq.artemis.core.journal.impl.dataformat.ByteArrayEncoding;
-import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
-
-public class TimedBuffer
-{
- // Constants -----------------------------------------------------
-
- // The number of tries on sleep before switching to spin
- public static final int MAX_CHECKS_ON_SLEEP = 20;
-
- // Attributes ----------------------------------------------------
-
- private TimedBufferObserver bufferObserver;
-
- // If the TimedBuffer is idle - i.e. no records are being added, then it's pointless the timer flush thread
- // in spinning and checking the time - and using up CPU in the process - this semaphore is used to
- // prevent that
- private final Semaphore spinLimiter = new Semaphore(1);
-
- private CheckTimer timerRunnable = new CheckTimer();
-
- private final int bufferSize;
-
- private final ActiveMQBuffer buffer;
-
- private int bufferLimit = 0;
-
- private List<IOAsyncTask> callbacks;
-
- private volatile int timeout;
-
- // used to measure sync requests. When a sync is requested, it shouldn't take more than timeout to happen
- private volatile boolean pendingSync = false;
-
- private Thread timerThread;
-
- private volatile boolean started;
-
- // We use this flag to prevent flush occurring between calling checkSize and addBytes
- // CheckSize must always be followed by it's corresponding addBytes otherwise the buffer
- // can get in an inconsistent state
- private boolean delayFlush;
-
- // for logging write rates
-
- private final boolean logRates;
-
- private final AtomicLong bytesFlushed = new AtomicLong(0);
-
- private final AtomicLong flushesDone = new AtomicLong(0);
-
- private Timer logRatesTimer;
-
- private TimerTask logRatesTimerTask;
-
- private boolean useSleep = true;
-
- // no need to be volatile as every access is synchronized
- private boolean spinning = false;
-
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- // Public --------------------------------------------------------
-
- public TimedBuffer(final int size, final int timeout, final boolean logRates)
- {
- bufferSize = size;
-
- this.logRates = logRates;
-
- if (logRates)
- {
- logRatesTimer = new Timer(true);
- }
- // Setting the interval for nano-sleeps
-
- buffer = ActiveMQBuffers.fixedBuffer(bufferSize);
-
- buffer.clear();
-
- bufferLimit = 0;
-
- callbacks = new ArrayList<IOAsyncTask>();
-
- this.timeout = timeout;
- }
-
- // for Debug purposes
- public synchronized boolean isUseSleep()
- {
- return useSleep;
- }
-
- public synchronized void setUseSleep(boolean useSleep)
- {
- this.useSleep = useSleep;
- }
-
- public synchronized void start()
- {
- if (started)
- {
- return;
- }
-
- // Need to start with the spin limiter acquired
- try
- {
- spinLimiter.acquire();
- }
- catch (InterruptedException e)
- {
- throw new ActiveMQInterruptedException(e);
- }
-
- timerRunnable = new CheckTimer();
-
- timerThread = new Thread(timerRunnable, "activemq-buffer-timeout");
-
- timerThread.start();
-
- if (logRates)
- {
- logRatesTimerTask = new LogRatesTimerTask();
-
- logRatesTimer.scheduleAtFixedRate(logRatesTimerTask, 2000, 2000);
- }
-
- started = true;
- }
-
- public void stop()
- {
- if (!started)
- {
- return;
- }
-
- flush();
-
- bufferObserver = null;
-
- timerRunnable.close();
-
- spinLimiter.release();
-
- if (logRates)
- {
- logRatesTimerTask.cancel();
- }
-
- while (timerThread.isAlive())
- {
- try
- {
- timerThread.join();
- }
- catch (InterruptedException e)
- {
- throw new ActiveMQInterruptedException(e);
- }
- }
-
- started = false;
- }
-
- public synchronized void setObserver(final TimedBufferObserver observer)
- {
- if (bufferObserver != null)
- {
- flush();
- }
-
- bufferObserver = observer;
- }
-
- /**
- * Verify if the size fits the buffer
- *
- * @param sizeChecked
- */
- public synchronized boolean checkSize(final int sizeChecked)
- {
- if (!started)
- {
- throw new IllegalStateException("TimedBuffer is not started");
- }
-
- if (sizeChecked > bufferSize)
- {
- throw new IllegalStateException("Can't write records bigger than the bufferSize(" + bufferSize +
- ") on the journal");
- }
-
- if (bufferLimit == 0 || buffer.writerIndex() + sizeChecked > bufferLimit)
- {
- // Either there is not enough space left in the buffer for the sized record
- // Or a flush has just been performed and we need to re-calcualate bufferLimit
-
- flush();
-
- delayFlush = true;
-
- final int remainingInFile = bufferObserver.getRemainingBytes();
-
- if (sizeChecked > remainingInFile)
- {
- return false;
- }
- else
- {
- // There is enough space in the file for this size
-
- // Need to re-calculate buffer limit
-
- bufferLimit = Math.min(remainingInFile, bufferSize);
-
- return true;
- }
- }
- else
- {
- delayFlush = true;
-
- return true;
- }
- }
-
- public synchronized void addBytes(final ActiveMQBuffer bytes, final boolean sync, final IOAsyncTask callback)
- {
- addBytes(new ByteArrayEncoding(bytes.toByteBuffer().array()), sync, callback);
- }
-
- public synchronized void addBytes(final EncodingSupport bytes, final boolean sync, final IOAsyncTask callback)
- {
- if (!started)
- {
- throw new IllegalStateException("TimedBuffer is not started");
- }
-
- delayFlush = false;
-
- bytes.encode(buffer);
-
- callbacks.add(callback);
-
- if (sync)
- {
- pendingSync = true;
-
- startSpin();
- }
-
- }
-
- public void flush()
- {
- flush(false);
- }
-
- /**
- * force means the Journal is moving to a new file. Any pending write need to be done immediately
- * or data could be lost
- */
- public void flush(final boolean force)
- {
- synchronized (this)
- {
- if (!started)
- {
- throw new IllegalStateException("TimedBuffer is not started");
- }
-
- if ((force || !delayFlush) && buffer.writerIndex() > 0)
- {
- int pos = buffer.writerIndex();
-
- if (logRates)
- {
- bytesFlushed.addAndGet(pos);
- }
-
- ByteBuffer bufferToFlush = bufferObserver.newBuffer(bufferSize, pos);
-
- // Putting a byteArray on a native buffer is much faster, since it will do in a single native call.
- // Using bufferToFlush.put(buffer) would make several append calls for each byte
- // We also transfer the content of this buffer to the native file's buffer
-
- bufferToFlush.put(buffer.toByteBuffer().array(), 0, pos);
-
- bufferObserver.flushBuffer(bufferToFlush, pendingSync, callbacks);
-
- stopSpin();
-
- pendingSync = false;
-
- // swap the instance as the previous callback list is being used asynchronously
- callbacks = new LinkedList<IOAsyncTask>();
-
- buffer.clear();
-
- bufferLimit = 0;
-
- flushesDone.incrementAndGet();
- }
- }
- }
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- // Inner classes -------------------------------------------------
-
- private class LogRatesTimerTask extends TimerTask
- {
- private boolean closed;
-
- private long lastExecution;
-
- private long lastBytesFlushed;
-
- private long lastFlushesDone;
-
- @Override
- public synchronized void run()
- {
- if (!closed)
- {
- long now = System.currentTimeMillis();
-
- long bytesF = bytesFlushed.get();
- long flushesD = flushesDone.get();
-
- if (lastExecution != 0)
- {
- double rate = 1000 * (double) (bytesF - lastBytesFlushed) / (now - lastExecution);
- ActiveMQJournalLogger.LOGGER.writeRate(rate, (long) (rate / (1024 * 1024)));
- double flushRate = 1000 * (double) (flushesD - lastFlushesDone) / (now - lastExecution);
- ActiveMQJournalLogger.LOGGER.flushRate(flushRate);
- }
-
- lastExecution = now;
-
- lastBytesFlushed = bytesF;
-
- lastFlushesDone = flushesD;
- }
- }
-
- @Override
- public synchronized boolean cancel()
- {
- closed = true;
-
- return super.cancel();
- }
- }
-
- private class CheckTimer implements Runnable
- {
- private volatile boolean closed = false;
-
- int checks = 0;
- int failedChecks = 0;
- long timeBefore = 0;
-
- final int sleepMillis = timeout / 1000000; // truncates
- final int sleepNanos = timeout % 1000000;
-
-
- public void run()
- {
- long lastFlushTime = 0;
-
- while (!closed)
- {
- // We flush on the timer if there are pending syncs there and we've waited at least one
- // timeout since the time of the last flush.
- // Effectively flushing "resets" the timer
- // On the timeout verification, notice that we ignore the timeout check if we are using sleep
-
- if (pendingSync)
- {
- if (isUseSleep())
- {
- // if using sleep, we will always flush
- flush();
- lastFlushTime = System.nanoTime();
- }
- else if (bufferObserver != null && System.nanoTime() > lastFlushTime + timeout)
- {
- // if not using flush we will spin and do the time checks manually
- flush();
- lastFlushTime = System.nanoTime();
- }
-
- }
-
- sleepIfPossible();
-
- try
- {
- spinLimiter.acquire();
-
- Thread.yield();
-
- spinLimiter.release();
- }
- catch (InterruptedException e)
- {
- throw new ActiveMQInterruptedException(e);
- }
- }
- }
-
- /**
- * We will attempt to use sleep only if the system supports nano-sleep
- * we will on that case verify up to MAX_CHECKS if nano sleep is behaving well.
- * if more than 50% of the checks have failed we will cancel the sleep and just use regular spin
- */
- private void sleepIfPossible()
- {
- if (isUseSleep())
- {
- if (checks < MAX_CHECKS_ON_SLEEP)
- {
- timeBefore = System.nanoTime();
- }
-
- try
- {
- sleep(sleepMillis, sleepNanos);
- }
- catch (InterruptedException e)
- {
- throw new ActiveMQInterruptedException(e);
- }
- catch (Exception e)
- {
- setUseSleep(false);
- ActiveMQJournalLogger.LOGGER.warn(e.getMessage() + ", disabling sleep on TimedBuffer, using spin now", e);
- }
-
- if (checks < MAX_CHECKS_ON_SLEEP)
- {
- long realTimeSleep = System.nanoTime() - timeBefore;
-
- // I'm letting the real time to be up to 50% than the requested sleep.
- if (realTimeSleep > timeout * 1.5)
- {
- failedChecks++;
- }
-
- if (++checks >= MAX_CHECKS_ON_SLEEP)
- {
- if (failedChecks > MAX_CHECKS_ON_SLEEP * 0.5)
- {
- ActiveMQJournalLogger.LOGGER.debug("Thread.sleep with nano seconds is not working as expected, Your kernel possibly doesn't support real time. the Journal TimedBuffer will spin for timeouts");
- setUseSleep(false);
- }
- }
- }
- }
- }
-
- public void close()
- {
- closed = true;
- }
- }
-
- /**
- * Sub classes (tests basically) can use this to override how the sleep is being done
- *
- * @param sleepMillis
- * @param sleepNanos
- * @throws InterruptedException
- */
- protected void sleep(int sleepMillis, int sleepNanos) throws InterruptedException
- {
- Thread.sleep(sleepMillis, sleepNanos);
- }
-
- /**
- * Sub classes (tests basically) can use this to override disabling spinning
- */
- protected void stopSpin()
- {
- if (spinning)
- {
- try
- {
- // We acquire the spinLimiter semaphore - this prevents the timer flush thread unnecessarily spinning
- // when the buffer is inactive
- spinLimiter.acquire();
- }
- catch (InterruptedException e)
- {
- throw new ActiveMQInterruptedException(e);
- }
-
- spinning = false;
- }
- }
-
-
- /**
- * Sub classes (tests basically) can use this to override disabling spinning
- */
- protected void startSpin()
- {
- if (!spinning)
- {
- spinLimiter.release();
-
- spinning = true;
- }
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBufferObserver.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBufferObserver.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBufferObserver.java
deleted file mode 100644
index f219f08..0000000
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TimedBufferObserver.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.core.journal.impl;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
-
-public interface TimedBufferObserver
-{
-
- // Constants -----------------------------------------------------
-
- // Attributes ----------------------------------------------------
-
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- // Public --------------------------------------------------------
-
- void flushBuffer(ByteBuffer buffer, boolean syncRequested, List<IOAsyncTask> callbacks);
-
- /** Return the number of remaining bytes that still fit on the observer (file) */
- int getRemainingBytes();
-
- ByteBuffer newBuffer(int size, int limit);
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- // Inner classes -------------------------------------------------
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java
index 4035202..140927e 100644
--- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java
+++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/journal/impl/TransactionCallback.java
@@ -18,10 +18,10 @@ package org.apache.activemq.artemis.core.journal.impl;
import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.activemq.artemis.core.journal.IOAsyncTask;
+import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.utils.ReusableLatch;
-public class TransactionCallback implements IOAsyncTask
+public class TransactionCallback implements IOCallback
{
private final ReusableLatch countLatch = new ReusableLatch();
@@ -33,7 +33,7 @@ public class TransactionCallback implements IOAsyncTask
private int done = 0;
- private volatile IOAsyncTask delegateCompletion;
+ private volatile IOCallback delegateCompletion;
public void countUp()
{
@@ -46,7 +46,7 @@ public class TransactionCallback implements IOAsyncTask
countLatch.countDown();
if (++done == up.get() && delegateCompletion != null)
{
- final IOAsyncTask delegateToCall = delegateCompletion;
+ final IOCallback delegateToCall = delegateCompletion;
// We need to set the delegateCompletion to null first or blocking commits could miss a callback
// What would affect mainly tests
delegateCompletion = null;
@@ -81,7 +81,7 @@ public class TransactionCallback implements IOAsyncTask
/**
* @return the delegateCompletion
*/
- public IOAsyncTask getDelegateCompletion()
+ public IOCallback getDelegateCompletion()
{
return delegateCompletion;
}
@@ -89,7 +89,7 @@ public class TransactionCallback implements IOAsyncTask
/**
* @param delegateCompletion the delegateCompletion to set
*/
- public void setDelegateCompletion(final IOAsyncTask delegateCompletion)
+ public void setDelegateCompletion(final IOCallback delegateCompletion)
{
this.delegateCompletion = delegateCompletion;
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-journal/src/test/java/org/apache/activemq/artemis/core/io/aio/CallbackOrderTest.java
----------------------------------------------------------------------
diff --git a/artemis-journal/src/test/java/org/apache/activemq/artemis/core/io/aio/CallbackOrderTest.java b/artemis-journal/src/test/java/org/apache/activemq/artemis/core/io/aio/CallbackOrderTest.java
new file mode 100644
index 0000000..82d4502
--- /dev/null
+++ b/artemis-journal/src/test/java/org/apache/activemq/artemis/core/io/aio/CallbackOrderTest.java
@@ -0,0 +1,97 @@
+/**
+ * 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.core.io.aio;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/** This will emulate callbacks out of order from libaio*/
+public class CallbackOrderTest
+{
+
+ @Rule
+ public TemporaryFolder temporaryFolder;
+
+ public CallbackOrderTest()
+ {
+ File parent = new File("./target");
+ parent.mkdirs();
+ temporaryFolder = new TemporaryFolder(parent);
+ }
+
+ /** This method will make sure callbacks will come back in order even when out order from libaio */
+ @Test
+ public void testCallbackOutOfOrder() throws Exception
+ {
+ AIOSequentialFileFactory factory = new AIOSequentialFileFactory(temporaryFolder.getRoot(), 100);
+ AIOSequentialFile file = (AIOSequentialFile)factory.createSequentialFile("test.bin");
+
+ final AtomicInteger count = new AtomicInteger(0);
+
+ IOCallback callback = new IOCallback()
+ {
+ @Override
+ public void done()
+ {
+ count.incrementAndGet();
+ }
+
+ @Override
+ public void onError(int errorCode, String errorMessage)
+ {
+
+ }
+ };
+
+ ArrayList<AIOSequentialFileFactory.AIOSequentialCallback> list = new ArrayList<>();
+
+ // We will repeat the teset a few times, increasing N
+ // to increase possibility of issues due to reuse of callbacks
+ for (int n = 1; n < 100; n++)
+ {
+ System.out.println("n = " + n);
+ int N = n;
+ count.set(0);
+ list.clear();
+ for (int i = 0; i < N; i++)
+ {
+ list.add(file.getCallback(callback, null));
+ }
+
+
+ for (int i = N - 1; i >= 0; i--)
+ {
+ list.get(i).done();
+ }
+
+ Assert.assertEquals(N, count.get());
+ Assert.assertEquals(0, file.pendingCallbackList.size());
+ Assert.assertTrue(file.pendingCallbackList.isEmpty());
+ }
+
+ factory.stop();
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java
----------------------------------------------------------------------
diff --git a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java
index 78154b6..bae871e 100644
--- a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java
+++ b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ActiveMQCreatePlugin.java
@@ -250,6 +250,7 @@ public class ActiveMQCreatePlugin extends AbstractMojo
add(listCommands, "--failover-on-shutdown");
}
+ add(listCommands, "--no-sync-test");
add(listCommands, "--verbose");
add(listCommands, instance.getAbsolutePath());
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/bin/libartemis-native-32.so
----------------------------------------------------------------------
diff --git a/artemis-native/bin/libartemis-native-32.so b/artemis-native/bin/libartemis-native-32.so
index 7178069..df4b560 100755
Binary files a/artemis-native/bin/libartemis-native-32.so and b/artemis-native/bin/libartemis-native-32.so differ
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/bin/libartemis-native-64.so
----------------------------------------------------------------------
diff --git a/artemis-native/bin/libartemis-native-64.so b/artemis-native/bin/libartemis-native-64.so
index 1c4983c..aec757a 100755
Binary files a/artemis-native/bin/libartemis-native-64.so and b/artemis-native/bin/libartemis-native-64.so differ
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/pom.xml
----------------------------------------------------------------------
diff --git a/artemis-native/pom.xml b/artemis-native/pom.xml
index abd5f0d..0206166 100644
--- a/artemis-native/pom.xml
+++ b/artemis-native/pom.xml
@@ -32,6 +32,30 @@
<artifactId>artemis-commons</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging-processor</artifactId>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.logmanager</groupId>
+ <artifactId>jboss-logmanager</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AIOController.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AIOController.cpp b/artemis-native/src/main/c/AIOController.cpp
deleted file mode 100644
index a61bf04..0000000
--- a/artemis-native/src/main/c/AIOController.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.
- */
-
-
-#include <string>
-#include "AIOController.h"
-#include "JavaUtilities.h"
-#include "JAIODatatypes.h"
-
-AIOController::AIOController(std::string fileName, int maxIO) : logger(0), fileOutput(fileName, this, maxIO)
-{
-}
-
-void AIOController::log(THREAD_CONTEXT threadContext, short level, const char * message)
-{
- jmethodID methodID = 0;
-
- switch (level)
- {
- case 0: methodID = loggerError; break;
- case 1: methodID = loggerWarn; break;
- case 2: methodID = loggerInfo; break;
- case 3: methodID = loggerDebug; break;
- default: methodID = loggerDebug; break;
- }
-
-#ifdef DEBUG
- fprintf (stderr,"Callig log methodID=%ld, message=%s, logger=%ld, threadContext = %ld\n", (long) methodID, message, (long) logger, (long) threadContext); fflush(stderr);
-#endif
- threadContext->CallVoidMethod(logger,methodID,threadContext->NewStringUTF(message));
-}
-
-
-void AIOController::destroy(THREAD_CONTEXT context)
-{
- if (logger != 0)
- {
- context->DeleteGlobalRef(logger);
- }
-}
-
-/*
- * level = 0-error, 1-warn, 2-info, 3-debug
- */
-
-
-AIOController::~AIOController()
-{
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AIOController.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AIOController.h b/artemis-native/src/main/c/AIOController.h
deleted file mode 100644
index 913565f..0000000
--- a/artemis-native/src/main/c/AIOController.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- */
-
-
-#ifndef AIOCONTROLLER_H_
-#define AIOCONTROLLER_H_
-#include <jni.h>
-#include <string>
-#include "JAIODatatypes.h"
-#include "AsyncFile.h"
-
-class AIOController
-{
-public:
- jmethodID done;
- jmethodID error;
-
- jobject logger;
-
- jmethodID loggerError;
- jmethodID loggerWarn;
- jmethodID loggerDebug;
- jmethodID loggerInfo;
-
- /*
- * level = 0-error, 1-warn, 2-info, 3-debug
- */
- void log(THREAD_CONTEXT threadContext, short level, const char * message);
-
- AsyncFile fileOutput;
-
- void destroy(THREAD_CONTEXT context);
-
- AIOController(std::string fileName, int maxIO);
- virtual ~AIOController();
-};
-#endif /*AIOCONTROLLER_H_*/
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AIOException.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AIOException.h b/artemis-native/src/main/c/AIOException.h
deleted file mode 100644
index 98745a2..0000000
--- a/artemis-native/src/main/c/AIOException.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.
- */
-
-
-
-#ifndef AIOEXCEPTION_H_
-#define AIOEXCEPTION_H_
-
-#include <exception>
-#include <string>
-
-
-#define NATIVE_ERROR_INTERNAL 200
-#define NATIVE_ERROR_INVALID_BUFFER 201
-#define NATIVE_ERROR_NOT_ALIGNED 202
-#define NATIVE_ERROR_CANT_INITIALIZE_AIO 203
-#define NATIVE_ERROR_CANT_RELEASE_AIO 204
-#define NATIVE_ERROR_CANT_OPEN_CLOSE_FILE 205
-#define NATIVE_ERROR_CANT_ALLOCATE_QUEUE 206
-#define NATIVE_ERROR_PREALLOCATE_FILE 208
-#define NATIVE_ERROR_ALLOCATE_MEMORY 209
-#define NATIVE_ERROR_IO 006
-#define NATIVE_ERROR_AIO_FULL 211
-
-
-class AIOException : public std::exception
-{
-private:
- int errorCode;
- std::string message;
-public:
- AIOException(int _errorCode, std::string _message) throw() : errorCode(_errorCode), message(_message)
- {
- errorCode = _errorCode;
- message = _message;
- }
-
- AIOException(int _errorCode, const char * _message) throw ()
- {
- message = std::string(_message);
- errorCode = _errorCode;
- }
-
- virtual ~AIOException() throw()
- {
-
- }
-
- int inline getErrorCode()
- {
- return errorCode;
- }
-
- const char* what() const throw()
- {
- return message.data();
- }
-
-};
-
-#endif /*AIOEXCEPTION_H_*/
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AsyncFile.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AsyncFile.cpp b/artemis-native/src/main/c/AsyncFile.cpp
deleted file mode 100644
index 2385a0d..0000000
--- a/artemis-native/src/main/c/AsyncFile.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-
-#include <stdlib.h>
-#include <list>
-#include <iostream>
-#include <sstream>
-#include <memory.h>
-#include <errno.h>
-#include <libaio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include "AsyncFile.h"
-#include "AIOController.h"
-#include "AIOException.h"
-#include "pthread.h"
-#include "LockClass.h"
-#include "CallbackAdapter.h"
-#include "LockClass.h"
-
-//#define DEBUG
-
-#define WAIT_FOR_SPOT 10000
-#define TRIES_BEFORE_WARN 0
-#define TRIES_BEFORE_ERROR 500
-
-
-std::string io_error(int rc)
-{
- std::stringstream buffer;
-
- if (rc == -ENOSYS)
- buffer << "AIO not in this kernel";
- else
- buffer << "Error:= " << strerror((int)-rc);
-
- return buffer.str();
-}
-
-
-AsyncFile::AsyncFile(std::string & _fileName, AIOController * _controller, int _maxIO) : aioContext(0), events(0), fileHandle(0), controller(_controller), pollerRunning(0)
-{
- ::pthread_mutex_init(&fileMutex,0);
- ::pthread_mutex_init(&pollerMutex,0);
-
- maxIO = _maxIO;
- fileName = _fileName;
- if (io_queue_init(maxIO, &aioContext))
- {
- throw AIOException(NATIVE_ERROR_CANT_INITIALIZE_AIO, "Can't initialize aio, out of AIO Handlers");
- }
-
- fileHandle = ::open(fileName.data(), O_RDWR | O_CREAT | O_DIRECT, 0666);
- if (fileHandle < 0)
- {
- io_queue_release(aioContext);
- throw AIOException(NATIVE_ERROR_CANT_OPEN_CLOSE_FILE, "Can't open file");
- }
-
-#ifdef DEBUG
- fprintf (stderr,"File Handle %d", fileHandle);
-#endif
-
- events = (struct io_event *)malloc (maxIO * sizeof (struct io_event));
-
- if (events == 0)
- {
- throw AIOException (NATIVE_ERROR_CANT_ALLOCATE_QUEUE, "Can't allocate ioEvents");
- }
-
-}
-
-AsyncFile::~AsyncFile()
-{
- if (io_queue_release(aioContext))
- {
- throw AIOException(NATIVE_ERROR_CANT_RELEASE_AIO,"Can't release aio");
- }
- if (::close(fileHandle))
- {
- throw AIOException(NATIVE_ERROR_CANT_OPEN_CLOSE_FILE,"Can't close file");
- }
- free(events);
- ::pthread_mutex_destroy(&fileMutex);
- ::pthread_mutex_destroy(&pollerMutex);
-}
-
-int isException (THREAD_CONTEXT threadContext)
-{
- return JNI_ENV(threadContext)->ExceptionOccurred() != 0;
-}
-
-void AsyncFile::pollEvents(THREAD_CONTEXT threadContext)
-{
-
- LockClass lock(&pollerMutex);
- pollerRunning=1;
-
-
- while (pollerRunning)
- {
- if (isException(threadContext))
- {
- return;
- }
- int result = io_getevents(this->aioContext, 1, maxIO, events, 0);
-
-
-#ifdef DEBUG
- fprintf (stderr, "poll, pollerRunning=%d\n", pollerRunning); fflush(stderr);
-#endif
-
- if (result > 0)
- {
-
-#ifdef DEBUG
- fprintf (stdout, "Received %d events\n", result);
- fflush(stdout);
-#endif
- }
-
- for (int i=0; i<result; i++)
- {
-
- struct iocb * iocbp = events[i].obj;
-
- if (iocbp->data == (void *) -1)
- {
- pollerRunning = 0;
-#ifdef DEBUG
- controller->log(threadContext, 2, "Received poller request to stop");
-#endif
- }
- else
- {
- CallbackAdapter * adapter = (CallbackAdapter *) iocbp->data;
-
- long result = events[i].res;
- if (result < 0)
- {
- std::string strerror = io_error((int)result);
- adapter->onError(threadContext, result, strerror);
- }
- else
- {
- adapter->done(threadContext);
- }
- }
-
- delete iocbp;
- }
- }
-#ifdef DEBUG
- controller->log(threadContext, 2, "Poller finished execution");
-#endif
-}
-
-
-void AsyncFile::preAllocate(THREAD_CONTEXT , off_t position, int blocks, size_t size, int fillChar)
-{
-
- if (size % ALIGNMENT != 0)
- {
- throw AIOException (NATIVE_ERROR_PREALLOCATE_FILE, "You can only pre allocate files in multiples of 512");
- }
-
- void * preAllocBuffer = 0;
- if (posix_memalign(&preAllocBuffer, 512, size))
- {
- throw AIOException(NATIVE_ERROR_ALLOCATE_MEMORY, "Error on posix_memalign");
- }
-
- memset(preAllocBuffer, fillChar, size);
-
-
- if (::lseek (fileHandle, position, SEEK_SET) < 0) throw AIOException (11, "Error positioning the file");
-
- for (int i=0; i<blocks; i++)
- {
- if (::write(fileHandle, preAllocBuffer, size)<0)
- {
- throw AIOException (NATIVE_ERROR_PREALLOCATE_FILE, "Error pre allocating the file");
- }
- }
-
- if (::lseek (fileHandle, position, SEEK_SET) < 0) throw AIOException (NATIVE_ERROR_IO, "Error positioning the file");
-
- free (preAllocBuffer);
-}
-
-
-/** Write directly to the file without using libaio queue */
-void AsyncFile::writeInternal(THREAD_CONTEXT, long position, size_t size, void *& buffer)
-{
- if (::lseek (fileHandle, position, SEEK_SET) < 0) throw AIOException (11, "Error positioning the file");
-
- if (::write(fileHandle, buffer, size)<0)
- {
- throw AIOException (NATIVE_ERROR_IO, "Error writing file");
- }
-
- if (::fsync(fileHandle) < 0)
- {
- throw AIOException (NATIVE_ERROR_IO, "Error on synchronizing file");
- }
-
-
-}
-
-
-void AsyncFile::write(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer, CallbackAdapter *& adapter)
-{
-
- struct iocb * iocb = new struct iocb();
- ::io_prep_pwrite(iocb, fileHandle, buffer, size, position);
- iocb->data = (void *) adapter;
-
- int tries = 0;
- int result = 0;
-
- while ((result = ::io_submit(aioContext, 1, &iocb)) == (-EAGAIN))
- {
-#ifdef DEBUG
- fprintf (stderr, "Retrying block as iocb was full (retry=%d)\n", tries);
-#endif
- tries ++;
- if (tries > TRIES_BEFORE_WARN)
- {
-#ifdef DEBUG
- fprintf (stderr, "Warning level on retries, informing logger (retry=%d)\n", tries);
-#endif
- controller->log(threadContext, 1, "You should consider expanding AIOLimit if this message appears too many times");
- }
-
- if (tries > TRIES_BEFORE_ERROR)
- {
-#ifdef DEBUG
- fprintf (stderr, "Error level on retries, throwing exception (retry=%d)\n", tries);
-#endif
- throw AIOException(NATIVE_ERROR_AIO_FULL, "Too many retries (500) waiting for a valid iocb block, please increase MAX_IO limit");
- }
- ::usleep(WAIT_FOR_SPOT);
- }
-
- if (result<0)
- {
- std::stringstream str;
- str<< "Problem on submit block, errorCode=" << result;
- throw AIOException (NATIVE_ERROR_IO, str.str());
- }
-}
-
-void AsyncFile::read(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer, CallbackAdapter *& adapter)
-{
-
- struct iocb * iocb = new struct iocb();
- ::io_prep_pread(iocb, fileHandle, buffer, size, position);
- iocb->data = (void *) adapter;
-
- int tries = 0;
- int result = 0;
-
- while ((result = ::io_submit(aioContext, 1, &iocb)) == (-EAGAIN))
- {
-#ifdef DEBUG
- fprintf (stderr, "Retrying block as iocb was full (retry=%d)\n", tries);
-#endif
- tries ++;
- if (tries > TRIES_BEFORE_WARN)
- {
-#ifdef DEBUG
- fprintf (stderr, "Warning level on retries, informing logger (retry=%d)\n", tries);
-#endif
- controller->log(threadContext, 1, "You should consider expanding AIOLimit if this message appears too many times");
- }
-
- if (tries > TRIES_BEFORE_ERROR)
- {
-#ifdef DEBUG
- fprintf (stderr, "Error level on retries, throwing exception (retry=%d)\n", tries);
-#endif
- throw AIOException(NATIVE_ERROR_AIO_FULL, "Too many retries (500) waiting for a valid iocb block, please increase MAX_IO limit");
- }
- ::usleep(WAIT_FOR_SPOT);
- }
-
- if (result<0)
- {
- std::stringstream str;
- str<< "Problem on submit block, errorCode=" << result;
- throw AIOException (NATIVE_ERROR_IO, str.str());
- }
-}
-
-long AsyncFile::getSize()
-{
- struct stat statBuffer;
-
- if (fstat(fileHandle, &statBuffer) < 0)
- {
- return -1l;
- }
- return statBuffer.st_size;
-}
-
-
-void AsyncFile::stopPoller(THREAD_CONTEXT threadContext)
-{
- pollerRunning = 0;
-
-
- struct iocb * iocb = new struct iocb();
- ::io_prep_pwrite(iocb, fileHandle, 0, 0, 0);
- iocb->data = (void *) -1;
-
- int result = 0;
-
- while ((result = ::io_submit(aioContext, 1, &iocb)) == (-EAGAIN))
- {
- fprintf(stderr, "Couldn't send request to stop poller, trying again");
- controller->log(threadContext, 1, "Couldn't send request to stop poller, trying again");
- ::usleep(WAIT_FOR_SPOT);
- }
-
- // Waiting the Poller to finish (by giving up the lock)
- LockClass lock(&pollerMutex);
-}
-
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/AsyncFile.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/AsyncFile.h b/artemis-native/src/main/c/AsyncFile.h
deleted file mode 100644
index 71281c9..0000000
--- a/artemis-native/src/main/c/AsyncFile.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef FILEOUTPUT_H_
-#define FILEOUTPUT_H_
-
-#include <string>
-#include <libaio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include "JAIODatatypes.h"
-#include "AIOException.h"
-
-class AIOController;
-
-class CallbackAdapter;
-
-/** Author: Clebert Suconic at Redhat dot com*/
-class AsyncFile
-{
-private:
- io_context_t aioContext;
- struct io_event *events;
- int fileHandle;
- std::string fileName;
-
- pthread_mutex_t fileMutex;
- pthread_mutex_t pollerMutex;
-
- AIOController * controller;
-
- bool pollerRunning;
-
- int maxIO;
-
-public:
- AsyncFile(std::string & _fileName, AIOController * controller, int maxIO);
- virtual ~AsyncFile();
-
- void write(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer, CallbackAdapter *& adapter);
-
- /** Write directly to the file without using libaio queue */
- void writeInternal(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer);
-
- void read(THREAD_CONTEXT threadContext, long position, size_t size, void *& buffer, CallbackAdapter *& adapter);
-
- int getHandle()
- {
- return fileHandle;
- }
-
- long getSize();
-
- inline void * newBuffer(int size)
- {
- void * buffer = 0;
- if (::posix_memalign(&buffer, 512, size))
- {
- throw AIOException(NATIVE_ERROR_ALLOCATE_MEMORY, "Error on posix_memalign");
- }
- return buffer;
-
- }
-
- inline void destroyBuffer(void * buffer)
- {
- ::free(buffer);
- }
-
-
- // Finishes the polling thread (if any) and return
- void stopPoller(THREAD_CONTEXT threadContext);
- void preAllocate(THREAD_CONTEXT threadContext, off_t position, int blocks, size_t size, int fillChar);
-
- void pollEvents(THREAD_CONTEXT threadContext);
-
-};
-
-#endif /*FILEOUTPUT_H_*/
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/CMakeLists.txt b/artemis-native/src/main/c/CMakeLists.txt
index 0a45fd6..beef8da 100644
--- a/artemis-native/src/main/c/CMakeLists.txt
+++ b/artemis-native/src/main/c/CMakeLists.txt
@@ -30,35 +30,21 @@ endif()
# you may want to remove this next line for debugging
# -O3 would make inline debug hard
+#ADD_DEFINITIONS("-O3 -Wall -z execstack")
ADD_DEFINITIONS("-O3 -Wall")
-#ADD_DEFINITIONS("-fdump-tree-all -Wall -pg -g -mstack-protector-guard=guard")
+#ADD_DEFINITIONS("-fdump-tree-all -Wall -pg -g")
find_library(LIBAIO NAMES aio)
INCLUDE_DIRECTORIES(. ${JNI_INCLUDE_DIRS})
ADD_CUSTOM_COMMAND(
- OUTPUT org_apache_activemq_artemis_core_libaio_Native.h
- COMMAND javah -cp ../java/ org.apache.activemq.artemis.core.libaio.Native
- DEPENDS ../java/org/apache/activemq/artemis/core/libaio/Native.java
+ OUTPUT org_apache_activemq_artemis_jlibaio_LibaioContext.h
+ COMMAND javah -cp ../java/ org.apache.activemq.artemis.jlibaio.LibaioContext
+ DEPENDS ../java/org/apache/activemq/artemis/jlibaio/LibaioContext.java
)
-ADD_LIBRARY(artemis-native SHARED
- AIOController.cpp
- AIOController.h
- AIOException.h
- AsyncFile.cpp
- AsyncFile.h
- CallbackAdapter.h
- JAIODatatypes.h
- JavaUtilities.cpp
- JavaUtilities.h
- JNI_AsynchronousFileImpl.cpp
- JNICallbackAdapter.cpp
- JNICallbackAdapter.h
- LockClass.h
- Version.h
- org_apache_activemq_artemis_core_libaio_Native.h)
+ADD_LIBRARY(artemis-native SHARED org_apache_activemq_artemis_jlibaio_LibaioContext.c org_apache_activemq_artemis_jlibaio_LibaioContext.h exception_helper.h)
target_link_libraries(artemis-native aio)
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/CallbackAdapter.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/CallbackAdapter.h b/artemis-native/src/main/c/CallbackAdapter.h
deleted file mode 100644
index e8b67da..0000000
--- a/artemis-native/src/main/c/CallbackAdapter.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef BUFFERADAPTER_H_
-#define BUFFERADAPTER_H_
-
-#include <iostream>
-
-#include "JAIODatatypes.h"
-
-class CallbackAdapter
-{
-private:
-
-public:
- CallbackAdapter()
- {
-
- }
- virtual ~CallbackAdapter()
- {
-
- }
-
- virtual void done(THREAD_CONTEXT ) = 0;
- virtual void onError(THREAD_CONTEXT , long , std::string )=0;
-};
-#endif /*BUFFERADAPTER_H_*/
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JAIODatatypes.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JAIODatatypes.h b/artemis-native/src/main/c/JAIODatatypes.h
deleted file mode 100644
index b611c2b..0000000
--- a/artemis-native/src/main/c/JAIODatatypes.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef JAIODATATYPES_H_
-#define JAIODATATYPES_H_
-
-#include <jni.h>
-
-#define THREAD_CONTEXT JNIEnv *&
-#define JNI_ENV(pointer) pointer
-#define ALIGNMENT 512
-
-
-#endif /*JAIODATATYPES_H_*/
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JNICallbackAdapter.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JNICallbackAdapter.cpp b/artemis-native/src/main/c/JNICallbackAdapter.cpp
deleted file mode 100644
index 0f4cef4..0000000
--- a/artemis-native/src/main/c/JNICallbackAdapter.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.
- */
-
-#include <jni.h>
-#include "JNICallbackAdapter.h"
-#include <iostream>
-#include "JavaUtilities.h"
-
-jobject nullObj = NULL;
-
-JNICallbackAdapter::JNICallbackAdapter(AIOController * _controller, jlong _sequence, jobject _callback, jobject _fileController, jobject _bufferReference, short _isRead) : CallbackAdapter()
-{
- controller = _controller;
-
- sequence = _sequence;
-
- callback = _callback;
-
- fileController = _fileController;
-
- bufferReference = _bufferReference;
-
- isRead = _isRead;
-
-}
-
-JNICallbackAdapter::~JNICallbackAdapter()
-{
-}
-
-void JNICallbackAdapter::done(THREAD_CONTEXT threadContext)
-{
- JNI_ENV(threadContext)->CallVoidMethod(fileController, controller->done, callback, sequence, isRead ? nullObj : bufferReference);
-
- release(threadContext);
-}
-
-void JNICallbackAdapter::onError(THREAD_CONTEXT threadContext, long errorCode, std::string error)
-{
- controller->log(threadContext, 0, "Libaio event generated errors, callback object was informed about it");
-
- jstring strError = JNI_ENV(threadContext)->NewStringUTF(error.data());
-
- JNI_ENV(threadContext)->CallVoidMethod(fileController, controller->error, callback, sequence, isRead ? nullObj : bufferReference, (jint)errorCode, strError);
-
- release(threadContext);
-}
-
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JNICallbackAdapter.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JNICallbackAdapter.h b/artemis-native/src/main/c/JNICallbackAdapter.h
deleted file mode 100644
index 5d32620..0000000
--- a/artemis-native/src/main/c/JNICallbackAdapter.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef JNIBUFFERADAPTER_H_
-#define JNIBUFFERADAPTER_H_
-
-#include <iostream>
-
-#include "CallbackAdapter.h"
-#include "AIOController.h"
-#include "JAIODatatypes.h"
-
-
-class JNICallbackAdapter : public CallbackAdapter
-{
-private:
-
- AIOController * controller;
-
- jobject callback;
-
- jobject fileController;
-
- jobject bufferReference;
-
- jlong sequence;
-
- // Is this a read operation
- short isRead;
-
- void release(THREAD_CONTEXT threadContext)
- {
- JNI_ENV(threadContext)->DeleteGlobalRef(callback);
- JNI_ENV(threadContext)->DeleteGlobalRef(fileController);
- JNI_ENV(threadContext)->DeleteGlobalRef(bufferReference);
- delete this;
- return;
- }
-
-
-public:
- // _ob must be a global Reference (use createGloblReferente before calling the constructor)
- JNICallbackAdapter(AIOController * _controller, jlong sequence, jobject _callback, jobject _fileController, jobject _bufferReference, short _isRead);
- virtual ~JNICallbackAdapter();
-
- void done(THREAD_CONTEXT threadContext);
-
- void onError(THREAD_CONTEXT , long , std::string );
-
-
-};
-#endif /*JNIBUFFERADAPTER_H_*/
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JNI_AsynchronousFileImpl.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JNI_AsynchronousFileImpl.cpp b/artemis-native/src/main/c/JNI_AsynchronousFileImpl.cpp
deleted file mode 100644
index 0334a7c..0000000
--- a/artemis-native/src/main/c/JNI_AsynchronousFileImpl.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * 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.
- */
-
-#include <jni.h>
-#include <stdlib.h>
-#include <iostream>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string>
-#include <time.h>
-#include <sys/file.h>
-
-#include "org_apache_activemq_artemis_core_libaio_Native.h"
-
-
-#include "JavaUtilities.h"
-#include "AIOController.h"
-#include "JNICallbackAdapter.h"
-#include "AIOException.h"
-#include "Version.h"
-
-
-// This value is set here globally, to avoid passing stuff on stack between java and the native layer on every sleep call
-struct timespec nanoTime;
-
-inline AIOController * getController(JNIEnv *env, jobject & controllerAddress)
-{
- return (AIOController *) env->GetDirectBufferAddress(controllerAddress);
-}
-
-/* Inaccessible static: log */
-/* Inaccessible static: totalMaxIO */
-/* Inaccessible static: loaded */
-/* Inaccessible static: EXPECTED_NATIVE_VERSION */
-/*
- * Class: org.apache.activemq.artemis_core_asyncio_impl_AsynchronousFileImpl
- * Method: openFile
- * Signature: (Ljava/lang/String;)I
- */
-JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_openFile
- (JNIEnv * env , jclass , jstring jstrFileName)
-{
- std::string fileName = convertJavaString(env, jstrFileName);
-
- return open(fileName.data(), O_RDWR | O_CREAT, 0666);
-}
-
-/*
- * Class: org.apache.activemq.artemis_core_asyncio_impl_AsynchronousFileImpl
- * Method: closeFile
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_closeFile
- (JNIEnv * , jclass , jint handle)
-{
- close(handle);
-}
-
-/*
- * Class: org.apache.activemq.artemis_core_asyncio_impl_AsynchronousFileImpl
- * Method: flock
- * Signature: (I)Z
- */
-JNIEXPORT jboolean JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_flock
- (JNIEnv * , jclass , jint handle)
-{
- return flock(handle, LOCK_EX | LOCK_NB) == 0;
-}
-
-
-
-/*
- * Class: org_jboss_jaio_libaioimpl_LibAIOController
- * Method: init
- * Signature: (Ljava/lang/String;Ljava/lang/Class;)J
- */
-JNIEXPORT jobject JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_init
- (JNIEnv * env, jclass, jclass controllerClazz, jstring jstrFileName, jint maxIO, jobject logger)
-{
- AIOController * controller = 0;
- try
- {
- std::string fileName = convertJavaString(env, jstrFileName);
-
- controller = new AIOController(fileName, (int) maxIO);
- controller->done = env->GetMethodID(controllerClazz,"callbackDone","(Lorg/apache/activemq/artemis/core/asyncio/AIOCallback;JLjava/nio/ByteBuffer;)V");
- if (!controller->done)
- {
- throwException (env, -1, "can't get callbackDone method");
- return 0;
- }
-
- controller->error = env->GetMethodID(controllerClazz, "callbackError", "(Lorg/apache/activemq/artemis/core/asyncio/AIOCallback;JLjava/nio/ByteBuffer;ILjava/lang/String;)V");
- if (!controller->done)
- {
- throwException (env, -1, "can't get callbackError method");
- return 0;
- }
-
- jclass loggerClass = env->GetObjectClass(logger);
-
- if (!(controller->loggerDebug = env->GetMethodID(loggerClass, "debug", "(Ljava/lang/Object;)V"))) return 0;
- if (!(controller->loggerWarn = env->GetMethodID(loggerClass, "warn", "(Ljava/lang/Object;)V"))) return 0;
- if (!(controller->loggerInfo = env->GetMethodID(loggerClass, "info", "(Ljava/lang/Object;)V"))) return 0;
- if (!(controller->loggerError = env->GetMethodID(loggerClass, "error", "(Ljava/lang/Object;)V"))) return 0;
-
- controller->logger = env->NewGlobalRef(logger);
-
- return env->NewDirectByteBuffer(controller, 0);
- }
- catch (AIOException& e){
- if (controller != 0)
- {
- delete controller;
- }
- throwException(env, e.getErrorCode(), e.what());
- return 0;
- }
-}
-
-/**
-* objThis here is passed as a parameter at the java layer. It used to be a JNI this and now it's a java static method
- where the intended reference is now passed as an argument
-*/
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_read
- (JNIEnv *env, jclass, jobject objThis, jobject controllerAddress, jlong position, jlong size, jobject jbuffer, jobject callback)
-{
- try
- {
- AIOController * controller = getController(env, controllerAddress);
- void * buffer = env->GetDirectBufferAddress(jbuffer);
-
- if (buffer == 0)
- {
- throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
- return;
- }
-
- if (((long)buffer) % 512)
- {
- throwException(env, NATIVE_ERROR_NOT_ALIGNED, "Buffer not aligned for use with DMA");
- return;
- }
-
- CallbackAdapter * adapter = new JNICallbackAdapter(controller, -1, env->NewGlobalRef(callback), env->NewGlobalRef(objThis), env->NewGlobalRef(jbuffer), true);
-
- controller->fileOutput.read(env, position, (size_t)size, buffer, adapter);
- }
- catch (AIOException& e)
- {
- throwException(env, e.getErrorCode(), e.what());
- }
-}
-
-
-// Fast memset on buffer
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_resetBuffer
- (JNIEnv *env, jclass, jobject jbuffer, jint size)
-{
- void * buffer = env->GetDirectBufferAddress(jbuffer);
-
- if (buffer == 0)
- {
- throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
- return;
- }
-
- memset(buffer, 0, (size_t)size);
-
-}
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_destroyBuffer
- (JNIEnv * env, jclass, jobject jbuffer)
-{
- if (jbuffer == 0)
- {
- throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Null Buffer");
- return;
- }
- void * buffer = env->GetDirectBufferAddress(jbuffer);
- free(buffer);
-}
-
-JNIEXPORT jobject JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_newNativeBuffer
- (JNIEnv * env, jclass, jlong size)
-{
- try
- {
-
- if (size % ALIGNMENT)
- {
- throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Buffer size needs to be aligned to 512");
- return 0;
- }
-
-
- // This will allocate a buffer, aligned by 512.
- // Buffers created here need to be manually destroyed by destroyBuffer, or this would leak on the process heap away of Java's GC managed memory
- void * buffer = 0;
- if (::posix_memalign(&buffer, 512, size))
- {
- throwException(env, NATIVE_ERROR_INTERNAL, "Error on posix_memalign");
- return 0;
- }
-
- memset(buffer, 0, (size_t)size);
-
- jobject jbuffer = env->NewDirectByteBuffer(buffer, size);
- return jbuffer;
- }
- catch (AIOException& e)
- {
- throwException(env, e.getErrorCode(), e.what());
- return 0;
- }
-}
-
-/**
-* objThis here is passed as a parameter at the java layer. It used to be a JNI this and now it's a java static method
- where the intended reference is now passed as an argument
-*/
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_write
- (JNIEnv *env, jclass, jobject objThis, jobject controllerAddress, jlong sequence, jlong position, jlong size, jobject jbuffer, jobject callback)
-{
- try
- {
- AIOController * controller = getController(env, controllerAddress);
- void * buffer = env->GetDirectBufferAddress(jbuffer);
-
- if (buffer == 0)
- {
- throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
- return;
- }
-
-
- CallbackAdapter * adapter = new JNICallbackAdapter(controller, sequence, env->NewGlobalRef(callback), env->NewGlobalRef(objThis), env->NewGlobalRef(jbuffer), false);
-
- controller->fileOutput.write(env, position, (size_t)size, buffer, adapter);
- }
- catch (AIOException& e)
- {
- throwException(env, e.getErrorCode(), e.what());
- }
-}
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_writeInternal
- (JNIEnv * env, jclass, jobject controllerAddress, jlong positionToWrite, jlong size, jobject jbuffer)
-{
- try
- {
- AIOController * controller = getController(env, controllerAddress);
- void * buffer = env->GetDirectBufferAddress(jbuffer);
-
- if (buffer == 0)
- {
- throwException(env, NATIVE_ERROR_INVALID_BUFFER, "Invalid Buffer used, libaio requires NativeBuffer instead of Java ByteBuffer");
- return;
- }
-
- controller->fileOutput.writeInternal(env, positionToWrite, (size_t)size, buffer);
- }
- catch (AIOException& e)
- {
- throwException(env, e.getErrorCode(), e.what());
- }
-}
-
-
-JNIEXPORT void Java_org_apache_activemq_artemis_core_libaio_Native_internalPollEvents
- (JNIEnv *env, jclass, jobject controllerAddress)
-{
- try
- {
- AIOController * controller = getController(env, controllerAddress);
- controller->fileOutput.pollEvents(env);
- }
- catch (AIOException& e)
- {
- throwException(env, e.getErrorCode(), e.what());
- }
-}
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_stopPoller
- (JNIEnv *env, jclass, jobject controllerAddress)
-{
- try
- {
- AIOController * controller = getController(env, controllerAddress);
- controller->fileOutput.stopPoller(env);
- }
- catch (AIOException& e)
- {
- throwException(env, e.getErrorCode(), e.what());
- }
-}
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_closeInternal
- (JNIEnv *env, jclass, jobject controllerAddress)
-{
- try
- {
- AIOController * controller = getController(env, controllerAddress);
- controller->destroy(env);
- delete controller;
- }
- catch (AIOException& e)
- {
- throwException(env, e.getErrorCode(), e.what());
- }
-}
-
-
-JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_fill
- (JNIEnv * env, jclass, jobject controllerAddress, jlong position, jint blocks, jlong size, jbyte fillChar)
-{
- try
- {
- AIOController * controller = getController(env, controllerAddress);
-
- controller->fileOutput.preAllocate(env, position, blocks, size, fillChar);
-
- }
- catch (AIOException& e)
- {
- throwException(env, e.getErrorCode(), e.what());
- }
-}
-
-
-
-/** It does nothing... just return true to make sure it has all the binary dependencies */
-JNIEXPORT jint JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_getNativeVersion
- (JNIEnv *, jclass)
-
-{
- return _VERSION_NATIVE_AIO;
-}
-
-
-JNIEXPORT jlong JNICALL Java_org_apache_activemq_artemis_core_libaio_Native_size0
- (JNIEnv * env, jclass, jobject controllerAddress)
-{
- try
- {
- AIOController * controller = getController(env, controllerAddress);
-
- long size = controller->fileOutput.getSize();
- if (size < 0)
- {
- throwException(env, NATIVE_ERROR_INTERNAL, "InternalError on Native Layer: method size failed");
- return -1l;
- }
- return size;
- }
- catch (AIOException& e)
- {
- throwException(env, e.getErrorCode(), e.what());
- return -1l;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JavaUtilities.cpp
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JavaUtilities.cpp b/artemis-native/src/main/c/JavaUtilities.cpp
deleted file mode 100644
index 10d6099..0000000
--- a/artemis-native/src/main/c/JavaUtilities.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdio.h>
-#include <iostream>
-#include <string>
-#include "JavaUtilities.h"
-
-
-void throwRuntimeException(JNIEnv * env, const char * message)
-{
- jclass exceptionClass = env->FindClass("java/lang/RuntimeException");
- env->ThrowNew(exceptionClass,message);
-
-}
-
-void throwException(JNIEnv * env, const int code, const char * message)
-{
- jclass exceptionClass = env->FindClass("org/apache/activemq/artemis/api/core/ActiveMQException");
- if (exceptionClass==NULL)
- {
- std::cerr << "Couldn't throw exception message:= " << message << "\n";
- throwRuntimeException (env, "Can't find Exception class");
- return;
- }
-
- jmethodID constructor = env->GetMethodID(exceptionClass, "<init>", "(ILjava/lang/String;)V");
- if (constructor == NULL)
- {
- std::cerr << "Couldn't find the constructor ***";
- throwRuntimeException (env, "Can't find Constructor for Exception");
- return;
- }
-
- jstring strError = env->NewStringUTF(message);
- jthrowable ex = (jthrowable)env->NewObject(exceptionClass, constructor, code, strError);
- env->Throw(ex);
-
-}
-
-std::string convertJavaString(JNIEnv * env, jstring& jstr)
-{
- const char * valueStr = env->GetStringUTFChars(jstr, NULL);
- std::string data(valueStr);
- env->ReleaseStringUTFChars(jstr, valueStr);
- return data;
-}
-
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/JavaUtilities.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/JavaUtilities.h b/artemis-native/src/main/c/JavaUtilities.h
deleted file mode 100644
index 53ba870..0000000
--- a/artemis-native/src/main/c/JavaUtilities.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef JAVAUTILITIES_H_
-#define JAVAUTILITIES_H_
-#include <string>
-#include <jni.h>
-
-void throwException(JNIEnv * env, const int code, const char * message);
-std::string convertJavaString(JNIEnv * env, jstring& jstr);
-
-#endif /*JAVAUTILITIES_H_*/
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/LockClass.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/LockClass.h b/artemis-native/src/main/c/LockClass.h
deleted file mode 100644
index 5259919..0000000
--- a/artemis-native/src/main/c/LockClass.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef LOCKCLASS_H_
-#define LOCKCLASS_H_
-
-#include <pthread.h>
-
-class LockClass
-{
-protected:
- pthread_mutex_t* _m;
-public:
- inline LockClass(pthread_mutex_t* m) : _m(m)
- {
- ::pthread_mutex_lock(_m);
- }
- inline ~LockClass()
- {
- ::pthread_mutex_unlock(_m);
- }
-};
-
-
-#endif /*LOCKCLASS_H_*/
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/Version.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/Version.h b/artemis-native/src/main/c/Version.h
deleted file mode 100644
index 5b521b3..0000000
--- a/artemis-native/src/main/c/Version.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _VERSION_NATIVE_AIO
-
-// This definition needs to match org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl.EXPECTED_NATIVE_VERSION
-// Or else the native module won't be loaded because of version mismatches
-#define _VERSION_NATIVE_AIO 52
-#endif
-
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6fe9e0eb/artemis-native/src/main/c/exception_helper.h
----------------------------------------------------------------------
diff --git a/artemis-native/src/main/c/exception_helper.h b/artemis-native/src/main/c/exception_helper.h
new file mode 100644
index 0000000..d8c7707
--- /dev/null
+++ b/artemis-native/src/main/c/exception_helper.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2015 The Netty Project
+ *
+ * The Netty Project 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.
+ */
+
+void throwRuntimeException(JNIEnv* env, char* message);
+void throwRuntimeExceptionErrorNo(JNIEnv* env, char* message, int errorNumber);
+void throwIOException(JNIEnv* env, char* message);
+void throwIOExceptionErrorNo(JNIEnv* env, char* message, int errorNumber);
+void throwClosedChannelException(JNIEnv* env);
+void throwOutOfMemoryError(JNIEnv* env);
+char* exceptionMessage(char* msg, int error);
[9/9] activemq-artemis git commit: merging #98 - ARTEMIS-163
Simplification of the native layer
Posted by an...@apache.org.
merging #98 - ARTEMIS-163 Simplification of the native layer
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/8182f8bd
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/8182f8bd
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/8182f8bd
Branch: refs/heads/master
Commit: 8182f8bd2d1b7d9165fd300d37b4dca75194acc5
Parents: 661f695 6fe9e0e
Author: Andy Taylor <an...@gmail.com>
Authored: Thu Jul 30 10:07:18 2015 +0100
Committer: Andy Taylor <an...@gmail.com>
Committed: Thu Jul 30 10:07:18 2015 +0100
----------------------------------------------------------------------
.gitignore | 2 +-
CMakeLists.txt | 18 +
README.md | 2 +-
.../activemq/artemis/cli/commands/Create.java | 90 +-
.../cli/commands/tools/CompactJournal.java | 6 +-
.../cli/commands/tools/DecodeJournal.java | 4 +-
.../cli/commands/tools/EncodeJournal.java | 6 +-
.../cli/commands/tools/XmlDataExporter.java | 6 +-
.../cli/commands/util/SyncCalculation.java | 190 ++++
.../artemis/cli/commands/etc/broker.xml | 1 +
.../commands/etc/journal-buffer-settings.txt | 8 +
.../apache/activemq/cli/test/ArtemisTest.java | 23 +-
.../activemq/cli/test/StreamClassPathTest.java | 1 +
.../artemis/api/core/ActiveMQNativeIOError.java | 5 +
.../journal/JMSJournalStorageManagerImpl.java | 6 +-
.../artemis/core/asyncio/AIOCallback.java | 33 -
.../artemis/core/asyncio/AsynchronousFile.java | 58 -
.../artemis/core/asyncio/BufferCallback.java | 27 -
.../core/asyncio/IOExceptionListener.java | 22 -
.../core/asyncio/impl/ActiveMQFileLock.java | 47 -
.../core/asyncio/impl/AsynchronousFileImpl.java | 822 --------------
.../artemis/core/io/AbstractSequentialFile.java | 407 +++++++
.../core/io/AbstractSequentialFileFactory.java | 224 ++++
.../activemq/artemis/core/io/DummyCallback.java | 49 +
.../activemq/artemis/core/io/IOCallback.java | 33 +
.../core/io/IOCriticalErrorListener.java | 25 +
.../artemis/core/io/IOExceptionListener.java | 22 +
.../artemis/core/io/SequentialFile.java | 116 ++
.../artemis/core/io/SequentialFileFactory.java | 91 ++
.../artemis/core/io/aio/AIOSequentialFile.java | 333 ++++++
.../core/io/aio/AIOSequentialFileFactory.java | 531 +++++++++
.../artemis/core/io/aio/ActiveMQFileLock.java | 47 +
.../artemis/core/io/buffer/TimedBuffer.java | 558 ++++++++++
.../core/io/buffer/TimedBufferObserver.java | 53 +
.../artemis/core/io/nio/NIOSequentialFile.java | 393 +++++++
.../core/io/nio/NIOSequentialFileFactory.java | 168 +++
.../artemis/core/journal/IOAsyncTask.java | 27 -
.../artemis/core/journal/IOCompletion.java | 4 +-
.../core/journal/IOCriticalErrorListener.java | 22 -
.../activemq/artemis/core/journal/Journal.java | 1 +
.../artemis/core/journal/SequentialFile.java | 129 ---
.../core/journal/SequentialFileFactory.java | 89 --
.../core/journal/impl/AIOSequentialFile.java | 326 ------
.../journal/impl/AIOSequentialFileFactory.java | 358 ------
.../journal/impl/AbstractJournalUpdateTask.java | 8 +-
.../journal/impl/AbstractSequentialFile.java | 407 -------
.../impl/AbstractSequentialFileFactory.java | 218 ----
.../core/journal/impl/DummyCallback.java | 48 -
.../core/journal/impl/FileWrapperJournal.java | 2 +-
.../artemis/core/journal/impl/JournalBase.java | 1 +
.../core/journal/impl/JournalCompactor.java | 6 +-
.../artemis/core/journal/impl/JournalFile.java | 2 +-
.../core/journal/impl/JournalFileImpl.java | 2 +-
.../journal/impl/JournalFilesRepository.java | 8 +-
.../artemis/core/journal/impl/JournalImpl.java | 28 +-
.../core/journal/impl/NIOSequentialFile.java | 404 -------
.../journal/impl/NIOSequentialFileFactory.java | 168 ---
.../core/journal/impl/SyncSpeedTest.java | 354 ------
.../artemis/core/journal/impl/TimedBuffer.java | 558 ----------
.../core/journal/impl/TimedBufferObserver.java | 52 -
.../core/journal/impl/TransactionCallback.java | 12 +-
.../artemis/core/io/aio/CallbackOrderTest.java | 97 ++
.../artemis/maven/ActiveMQCreatePlugin.java | 1 +
artemis-native/bin/libartemis-native-32.so | Bin 44082 -> 22260 bytes
artemis-native/bin/libartemis-native-64.so | Bin 46624 -> 23984 bytes
artemis-native/pom.xml | 24 +
artemis-native/src/main/c/AIOController.cpp | 63 --
artemis-native/src/main/c/AIOController.h | 51 -
artemis-native/src/main/c/AIOException.h | 75 --
artemis-native/src/main/c/AsyncFile.cpp | 348 ------
artemis-native/src/main/c/AsyncFile.h | 93 --
artemis-native/src/main/c/CMakeLists.txt | 26 +-
artemis-native/src/main/c/CallbackAdapter.h | 42 -
artemis-native/src/main/c/JAIODatatypes.h | 28 -
.../src/main/c/JNICallbackAdapter.cpp | 62 --
artemis-native/src/main/c/JNICallbackAdapter.h | 66 --
.../src/main/c/JNI_AsynchronousFileImpl.cpp | 377 -------
artemis-native/src/main/c/JavaUtilities.cpp | 62 --
artemis-native/src/main/c/JavaUtilities.h | 26 -
artemis-native/src/main/c/LockClass.h | 39 -
artemis-native/src/main/c/Version.h | 24 -
artemis-native/src/main/c/exception_helper.h | 23 +
...che_activemq_artemis_jlibaio_LibaioContext.c | 710 ++++++++++++
.../activemq/artemis/core/libaio/Native.java | 74 --
.../activemq/artemis/jlibaio/LibaioContext.java | 446 ++++++++
.../activemq/artemis/jlibaio/LibaioFile.java | 152 +++
.../activemq/artemis/jlibaio/NativeLogger.java | 51 +
.../activemq/artemis/jlibaio/SubmitInfo.java | 25 +
.../activemq/artemis/jlibaio/package-info.java | 24 +
.../artemis/jlibaio/util/CallbackCache.java | 93 ++
.../jlibaio/test/CallbackCachelTest.java | 112 ++
.../artemis/jlibaio/test/LibaioTest.java | 859 +++++++++++++++
.../plug/ProtonSessionIntegrationCallback.java | 4 +-
.../core/protocol/mqtt/MQTTPublishManager.java | 4 +-
.../openwire/OpenWireProtocolManager.java | 4 +-
.../protocol/stomp/StompProtocolManager.java | 4 +-
.../deployers/impl/FileConfigurationParser.java | 2 +-
.../artemis/core/paging/PagingManager.java | 2 +-
.../artemis/core/paging/PagingStore.java | 2 +-
.../artemis/core/paging/PagingStoreFactory.java | 2 +-
.../cursor/impl/PageSubscriptionImpl.java | 6 +-
.../activemq/artemis/core/paging/impl/Page.java | 4 +-
.../core/paging/impl/PagingStoreFactoryNIO.java | 8 +-
.../core/paging/impl/PagingStoreImpl.java | 10 +-
.../core/persistence/OperationContext.java | 4 +-
.../core/persistence/StorageManager.java | 6 +-
.../impl/journal/DescribeJournal.java | 8 +-
.../impl/journal/JournalStorageManager.java | 33 +-
.../impl/journal/LargeServerMessageImpl.java | 2 +-
.../impl/journal/LargeServerMessageInSync.java | 4 +-
.../impl/journal/OperationContextImpl.java | 12 +-
.../nullpm/NullStorageLargeServerMessage.java | 2 +-
.../impl/nullpm/NullStorageManager.java | 8 +-
.../core/postoffice/impl/PostOfficeImpl.java | 6 +-
.../core/ServerSessionPacketHandler.java | 4 +-
.../core/replication/ReplicatedJournal.java | 2 +-
.../core/replication/ReplicationEndpoint.java | 6 +-
.../core/replication/ReplicationManager.java | 2 +-
.../core/server/ActiveMQServerLogger.java | 10 +-
.../artemis/core/server/LargeServerMessage.java | 2 +-
.../core/server/cluster/impl/Redistributor.java | 4 +-
.../server/impl/AIOFileLockNodeManager.java | 29 +-
.../core/server/impl/ActiveMQServerImpl.java | 18 +-
.../artemis/core/server/impl/QueueImpl.java | 4 +-
.../core/server/impl/ServerSessionImpl.java | 4 +-
.../core/transaction/impl/TransactionImpl.java | 8 +-
.../artemis/tests/util/ActiveMQTestBase.java | 66 +-
.../tests/util/ColocatedActiveMQServer.java | 7 +-
.../integration/client/HangConsumerTest.java | 6 +-
.../integration/client/JournalCrashTest.java | 4 +-
.../client/LibaioDependencyCheckTest.java | 4 +-
.../tests/integration/client/PagingTest.java | 8 +-
.../client/RedeliveryConsumerTest.java | 4 +-
.../integration/cluster/bridge/BridgeTest.java | 6 +-
.../journal/AIOImportExportTest.java | 6 +-
.../journal/AIOJournalCompactTest.java | 6 +-
.../integration/journal/AIOJournalImplTest.java | 10 +-
.../journal/AIOSequentialFileFactoryTest.java | 10 +-
.../journal/NIOBufferedJournalCompactTest.java | 6 +-
.../journal/NIOImportExportTest.java | 6 +-
.../journal/NIOJournalCompactTest.java | 16 +-
.../integration/journal/NIOJournalImplTest.java | 6 +-
.../journal/NIONoBufferJournalImplTest.java | 6 +-
...NIONonBufferedSequentialFileFactoryTest.java | 6 +-
.../journal/NIOSequentialFileFactoryTest.java | 6 +-
.../journal/ValidateTransactionHealthTest.java | 15 +-
.../management/ActiveMQServerControlTest.java | 12 +-
.../replication/ReplicationTest.java | 16 +-
.../integration/server/FileLockTimeoutTest.java | 4 +-
.../journal/FakeJournalImplTest.java | 2 +-
.../journal/JournalImplTestUnit.java | 13 +-
.../journal/RealJournalImplAIOTest.java | 6 +-
.../journal/RealJournalImplNIOTest.java | 6 +-
.../AIOAllPossibilitiesCompactStressTest.java | 6 +-
.../AIOMultiThreadCompactorStressTest.java | 2 +-
.../stress/journal/AddAndRemoveStressTest.java | 16 +-
.../stress/journal/CompactingStressTest.java | 12 +-
.../JournalCleanupCompactStressTest.java | 50 +-
.../stress/journal/MixupCompactorTestBase.java | 6 +-
.../NIOMultiThreadCompactorStressTest.java | 8 +-
.../core/journal/impl/AIOJournalImplTest.java | 6 +-
.../core/journal/impl/FakeJournalImplTest.java | 2 +-
.../core/journal/impl/JournalImplTestUnit.java | 15 +-
.../core/journal/impl/NIOJournalImplTest.java | 6 +-
.../tests/unit/core/asyncio/AIOTestBase.java | 18 +-
.../unit/core/asyncio/AsynchronousFileTest.java | 1015 ------------------
.../MultiThreadAsynchronousFileTest.java | 81 +-
.../journal/impl/AlignedJournalImplTest.java | 14 +-
.../unit/core/journal/impl/CleanBufferTest.java | 16 +-
.../core/journal/impl/FakeJournalImplTest.java | 2 +-
.../impl/FakeSequentialFileFactoryTest.java | 2 +-
.../core/journal/impl/FileFactoryTestBase.java | 18 +-
.../core/journal/impl/JournalImplTestBase.java | 6 +-
.../core/journal/impl/JournalImplTestUnit.java | 9 +-
.../unit/core/journal/impl/ReclaimerTest.java | 2 +-
.../impl/SequentialFileFactoryTestBase.java | 52 +-
.../unit/core/journal/impl/TimedBufferTest.java | 26 +-
.../impl/fakes/FakeSequentialFileFactory.java | 84 +-
.../tests/unit/core/paging/impl/PageTest.java | 18 +-
.../core/paging/impl/PagingStoreImplTest.java | 14 +-
.../impl/BatchIDGeneratorUnitTest.java | 4 +-
.../impl/OperationContextUnitTest.java | 8 +-
.../unit/core/server/impl/FileLockTest.java | 4 +-
183 files changed, 6522 insertions(+), 7227 deletions(-)
----------------------------------------------------------------------