/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.github.geophile.erdo.systemtest.lockmanagement; import com.github.geophile.erdo.map.Factory; import com.github.geophile.erdo.transaction.LockManager; import com.github.geophile.erdo.transaction.Transaction; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; public class LockManagerTest { public static void main(String[] args) throws InterruptedException { new LockManagerTest(args).run(); } private LockManagerTest(String[] args) { int a = 0; this.accounts = new AtomicLong[Integer.parseInt(args[a++])]; int lockManagerBuckets = Integer.parseInt(args[a++]); this.lockManager = new LockManager(lockManagerBuckets); this.factory = new TestFactory(lockManager); this.threads = new LockManagerTestThread[Integer.parseInt(args[a++])]; this.transactionsPerThread = Integer.parseInt(args[a++]); System.out.println(String.format("accounts: %s", accounts.length)); System.out.println(String.format("buckets: %s", lockManagerBuckets)); System.out.println(String.format("threads: %s", threads.length)); System.out.println(String.format("transactionsPerThread: %s", transactionsPerThread)); } private void run() throws InterruptedException { setupTransactionManagement(); createAccounts(); createThreads(); startThreads(); waitForCompletion(); verify(); } private void createAccounts() { for (int a = 0; a < accounts.length; a++) { accounts[a] = new AtomicLong(0); } } private void createThreads() { for (int t = 0; t < threads.length; t++) { threads[t] = new LockManagerTestThread(t, factory.transactionManager(), lockManager, accounts, transactionsPerThread); } } private void setupTransactionManagement() { Transaction.initialize(factory); ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool( 1, new ThreadFactory() { public Thread newThread(Runnable runnable) { Thread thread = new Thread(runnable); thread.setDaemon(true); thread.setName("DEADLOCK_DETECTOR"); return thread; } }); scheduledExecutorService.scheduleWithFixedDelay( new Runnable() { public void run() { try { lockManager.killDeadlockVictims(); } catch (Exception e) { e.printStackTrace(); } } }, 20, 20, TimeUnit.MILLISECONDS); } private void startThreads() { for (LockManagerTestThread thread : threads) { thread.start(); } } private void waitForCompletion() throws InterruptedException { for (LockManagerTestThread thread : threads) { thread.join(); } } private void verify() { long sum = 0; for (int a = 0; a < accounts.length; a++) { long balance = accounts[a].get(); System.out.println(String.format("%s: %s", a, balance)); sum += balance; } for (AtomicLong account : accounts) { long balance = account.get(); sum += balance; } if (sum == 0) { System.out.println("OK!"); } else { System.out.println(String.format("Test failed, sum = %s", sum)); } } private final Factory factory; private final AtomicLong[] accounts; private final LockManager lockManager; private final LockManagerTestThread[] threads; private final int transactionsPerThread; }