// Path: src/test/java/org/sharedmq/test/PerformanceTests.java
// public interface PerformanceTests {
// }
// 
// Path: src/test/java/org/sharedmq/test/TestFolder.java
// public class TestFolder implements Closeable {
// 
//     private final File root;
// 
//     /**
//      * Creates an new folder in the default temporary-file directory.
//      *
//      * @param prefix The prefix for the new folder name.
//      * @param suffix The suffix for the new folder name.
//      * @throws IOException If folder creation fails.
//      */
//     public TestFolder(String prefix, String suffix) throws IOException {
//         root = File.createTempFile(prefix, suffix);
//         if (!root.delete() || !root.mkdir()) {
//             throw new IOException("Failed to prepare test folder.");
//         }
//     }
// 
//     /**
//      * Returns a {@link File} object matching this folder location.
//      */
//     public File getRoot() {
//         return root;
//     }
// 
//     /**
//      * Returns an {@link File} instance for the file with the given name in this test folder.
//      *
//      * @param filename The name of the faile.
//      */
//     public File getFile(String filename) {
//         return new File(root, filename);
//     }
// 
//     /**
//      * Deletes this test folder and all its content.
//      *
//      * @throws IOException
//      */
//     @Override
//     public void close() throws IOException {
// 
//         // A mapped byte buffer and the file mapping that it represents
//         // remain valid until the buffer itself is garbage-collected.
//         System.gc();
// 
//         IOUtils.deleteTree(root);
//     }
// }
// 
// Path: src/test/java/org/sharedmq/test/TestUtils.java
// public static void printResult(String prefix, Stopwatch timer, int operationCount) {
//     printResult(prefix, timer.elapsed(TimeUnit.MILLISECONDS), operationCount);
// }


import com.google.common.base.Stopwatch;
import com.google.common.base.Strings;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.sharedmq.test.PerformanceTests;
import org.sharedmq.test.TestFolder;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.sharedmq.test.TestUtils.printResult;
        final List<Thread> threads = new ArrayList<>();
        final CountDownLatch startLatch = new CountDownLatch(threadCount);

        try (SharedMessageQueue queue = SharedMessageQueue.createQueue(queueFolder, Hours12, Hours12)) {
            for (int threadNum = 0; threadNum < threadCount; threadNum++) {
                threads.add(new Thread(() -> {
                    try {
                        // Thread startup can be slow.
                        // We want all threads to start their job approximately at same time.
                        startLatch.countDown();
                        startLatch.await();

                        for (int i = 0; i < messagesPerThread; i++) {
                            queue.push(0, messageBody);
                            Message message = queue.pull(PullTimeout);
                            assertNotNull(message);
                            queue.delete(message);
                        }
                    } catch (Exception e) {
                        errorCount.incrementAndGet();
                        e.printStackTrace();
                    }
                }));
            }

            Stopwatch sw = Stopwatch.createStarted();
            startThreads(threads);
            joinThreads(threads);
            sw.stop();

// Path: src/test/java/org/sharedmq/test/PerformanceTests.java
// public interface PerformanceTests {
// }
// 
// Path: src/test/java/org/sharedmq/test/TestFolder.java
// public class TestFolder implements Closeable {
// 
//     private final File root;
// 
//     /**
//      * Creates an new folder in the default temporary-file directory.
//      *
//      * @param prefix The prefix for the new folder name.
//      * @param suffix The suffix for the new folder name.
//      * @throws IOException If folder creation fails.
//      */
//     public TestFolder(String prefix, String suffix) throws IOException {
//         root = File.createTempFile(prefix, suffix);
//         if (!root.delete() || !root.mkdir()) {
//             throw new IOException("Failed to prepare test folder.");
//         }
//     }
// 
//     /**
//      * Returns a {@link File} object matching this folder location.
//      */
//     public File getRoot() {
//         return root;
//     }
// 
//     /**
//      * Returns an {@link File} instance for the file with the given name in this test folder.
//      *
//      * @param filename The name of the faile.
//      */
//     public File getFile(String filename) {
//         return new File(root, filename);
//     }
// 
//     /**
//      * Deletes this test folder and all its content.
//      *
//      * @throws IOException
//      */
//     @Override
//     public void close() throws IOException {
// 
//         // A mapped byte buffer and the file mapping that it represents
//         // remain valid until the buffer itself is garbage-collected.
//         System.gc();
// 
//         IOUtils.deleteTree(root);
//     }
// }
// 
// Path: src/test/java/org/sharedmq/test/TestUtils.java
// public static void printResult(String prefix, Stopwatch timer, int operationCount) {
//     printResult(prefix, timer.elapsed(TimeUnit.MILLISECONDS), operationCount);
// }


// Path: src/test/java/org/sharedmq/SharedMessageQueuePerformanceTest.java
import com.google.common.base.Stopwatch;
import com.google.common.base.Strings;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.sharedmq.test.PerformanceTests;
import org.sharedmq.test.TestFolder;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.sharedmq.test.TestUtils.printResult;

        final List<Thread> threads = new ArrayList<>();
        final CountDownLatch startLatch = new CountDownLatch(threadCount);

        try (SharedMessageQueue queue = SharedMessageQueue.createQueue(queueFolder, Hours12, Hours12)) {
            for (int threadNum = 0; threadNum < threadCount; threadNum++) {
                threads.add(new Thread(() -> {
                    try {
                        // Thread startup can be slow.
                        // We want all threads to start their job approximately at same time.
                        startLatch.countDown();
                        startLatch.await();

                        for (int i = 0; i < messagesPerThread; i++) {
                            queue.push(0, messageBody);
                            Message message = queue.pull(PullTimeout);
                            assertNotNull(message);
                            queue.delete(message);
                        }
                    } catch (Exception e) {
                        errorCount.incrementAndGet();
                        e.printStackTrace();
                    }
                }));
            }

            Stopwatch sw = Stopwatch.createStarted();
            startThreads(threads);
            joinThreads(threads);
            sw.stop();

            printResult("testPushPullDelete: ", sw, totalMessageCount);