blob: 496260d0914d4b5a1c5dc0c4d53838af598a1ba8 [file] [log] [blame]
/*
* Copyright 2009-2010 by The Regents of the University of California
* Licensed 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 from
*
* 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 edu.uci.ics.asterix.transaction.management.logging.test;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
import edu.uci.ics.asterix.transaction.management.logging.BasicLogger;
import edu.uci.ics.asterix.transaction.management.resource.TransactionalResourceRepository;
import edu.uci.ics.asterix.transaction.management.service.locking.ILockManager;
import edu.uci.ics.asterix.transaction.management.service.logging.ILogManager;
import edu.uci.ics.asterix.transaction.management.service.logging.ILogRecordHelper;
import edu.uci.ics.asterix.transaction.management.service.logging.LogActionType;
import edu.uci.ics.asterix.transaction.management.service.logging.LogType;
import edu.uci.ics.asterix.transaction.management.service.logging.LogUtil;
import edu.uci.ics.asterix.transaction.management.service.logging.LogicalLogLocator;
import edu.uci.ics.asterix.transaction.management.service.transaction.IResourceManager;
import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionContext;
import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionIDFactory;
import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionProvider;
public class TransactionWorkloadSimulator {
public static ILogManager logManager;
public static ILockManager lockManager;
TransactionProvider provider;
public static WorkloadProperties workload;
Transaction[] transactions;
public TransactionWorkloadSimulator(WorkloadProperties workload) {
this.workload = workload;
transactions = new Transaction[workload.numActiveThreads];
}
public void beginWorkload() throws ACIDException {
provider = new TransactionProvider("nc1");
logManager = provider.getLogManager();
lockManager = provider.getLockManager();
provider.getTransactionalResourceRepository().registerTransactionalResourceManager(DummyResourceMgr.id,
new DummyResourceMgr());
Transaction[] transactions = new Transaction[workload.numActiveThreads];
long startTime = System.nanoTime();
for (int i = 0; i < workload.numActiveThreads; i++) {
transactions[i] = new Transaction(provider, "Transaction " + (i + 1), workload.singleTransaction);
transactions[i].start();
}
for (int i = 0; i < workload.numActiveThreads; i++) {
try {
transactions[i].join();
} catch (InterruptedException ignore) {
}
}
for (int i = 0; i < workload.numActiveThreads; i++) {
provider.getTransactionManager().commitTransaction(transactions[i].getContext());
}
long endTime = System.nanoTime();
int totalLogs = Transaction.logCount.get();
System.out.println(" Total logs :" + totalLogs);
long timeTaken = ((endTime - startTime) / 1000000);
System.out.println(" total time :" + timeTaken);
System.out.println(" throughput :" + totalLogs * 1000 / timeTaken + " logs/sec");
long totalBytesWritten = Transaction.logByteCount.get();
System.out.println(" bytes written :" + totalBytesWritten);
System.out.println(" IO throughput " + totalBytesWritten * 1000 / timeTaken + " bytes/sec");
System.out.println(" Avg Content Creation time :" + BasicLogger.getAverageContentCreationTime());
}
public static void main(String args[]) {
WorkloadProperties workload = new WorkloadProperties();
TransactionWorkloadSimulator simulator = new TransactionWorkloadSimulator(workload);
try {
simulator.beginWorkload();
} catch (ACIDException acide) {
acide.printStackTrace();
}
}
}
class SingleTransactionContextFactory {
private static TransactionContext context;
public static TransactionContext getContext(TransactionProvider provider) throws ACIDException {
if (context == null) {
context = new TransactionContext(TransactionIDFactory.generateTransactionId(), provider);
}
return context;
}
}
class MultipleTransactionContextFactory {
public static TransactionContext getContext(TransactionProvider provider) throws ACIDException {
return new TransactionContext(TransactionIDFactory.generateTransactionId(), provider);
}
}
class Transaction extends Thread {
public static AtomicInteger logCount = new AtomicInteger(0);
public static AtomicLong logByteCount = new AtomicLong(0);
Random random = new Random();
BasicLogger logger = new BasicLogger();
LogicalLogLocator memLSN;
String name;
TransactionContext context;
private byte[] resourceID = new byte[1];
private int myLogCount = 0;
private TransactionProvider transactionProvider;
private ILogManager logManager;
public Transaction(TransactionProvider provider, String name, boolean singleTransaction) throws ACIDException {
this.name = name;
this.transactionProvider = provider;
if (singleTransaction) {
context = SingleTransactionContextFactory.getContext(transactionProvider);
} else {
context = MultipleTransactionContextFactory.getContext(transactionProvider);
}
memLSN = LogUtil.getDummyLogicalLogLocator(transactionProvider.getLogManager());
logManager = transactionProvider.getLogManager();
}
public TransactionContext getContext() {
return context;
}
@Override
public void run() {
if (TransactionWorkloadSimulator.workload.minLogsPerTransactionThread == TransactionWorkloadSimulator.workload.maxLogsPerTransactionThread) {
TransactionWorkloadSimulator.workload.maxLogsPerTransactionThread++;
}
int numLogs = TransactionWorkloadSimulator.workload.minLogsPerTransactionThread
+ random.nextInt(TransactionWorkloadSimulator.workload.maxLogsPerTransactionThread
- TransactionWorkloadSimulator.workload.minLogsPerTransactionThread);
int total = 0;
LogicalLogLocator memLSN = LogUtil.getDummyLogicalLogLocator(logManager);
if (TransactionWorkloadSimulator.workload.maxLogSize == TransactionWorkloadSimulator.workload.minLogSize) {
TransactionWorkloadSimulator.workload.maxLogSize++;
}
if (TransactionWorkloadSimulator.workload.singleResource) {
int choice = random.nextInt(2);
resourceID[0] = (byte) (choice % 2);
} else {
random.nextBytes(resourceID);
}
boolean retry = false;
int lockMode = -1;
try {
for (int i = 0; i < numLogs - 1; i++) {
int logSize = TransactionWorkloadSimulator.workload.minLogSize
+ random.nextInt(TransactionWorkloadSimulator.workload.maxLogSize
- TransactionWorkloadSimulator.workload.minLogSize);
total += logSize;
byte logType = LogType.UPDATE;
byte logActionType = LogActionType.REDO_UNDO;
long pageId = 0;
if (!retry) {
lockMode = random.nextInt(2);
}
boolean lockGranted = TransactionWorkloadSimulator.lockManager.lock(context, resourceID, lockMode);
if (!lockGranted) {
retry = true;
continue;
}
TransactionWorkloadSimulator.logManager.log(memLSN, context, ResourceMgrInfo.BTreeResourceMgrId,
pageId, logType, logActionType, logSize, logger, null);
retry = false;
Thread.currentThread().sleep(TransactionWorkloadSimulator.workload.thinkTime);
logCount.incrementAndGet();
logByteCount.addAndGet(logSize
+ TransactionWorkloadSimulator.logManager.getLogManagerProperties().getLogHeaderSize()
+ TransactionWorkloadSimulator.logManager.getLogManagerProperties().getLogChecksumSize());
myLogCount++;
}
} catch (ACIDException acide) {
acide.printStackTrace();
} catch (Exception ie) {
ie.printStackTrace();
}
}
}
class WorkloadProperties {
public int numActiveThreads = 200;
public long thinkTime = 0; // (in mesecs)
public int minLogsPerTransactionThread = 5;
public int maxLogsPerTransactionThread = 5;
public int minLogSize = 1024 - 51;
public int maxLogSize = 1024 - 51;
public float commitFraction = 0.5f;
public float rollbackFraction = 0.1f;
public boolean singleTransaction = false;
public boolean singleResource = true;
}
class ResourceMgrInfo {
public static final byte BTreeResourceMgrId = 1;
public static final byte MetadataResourceMgrId = 2;
}
class DummyResourceMgr implements IResourceManager {
public static final byte id = 1;
@Override
public void redo(ILogRecordHelper logParser, LogicalLogLocator memLSN) throws ACIDException {
// TODO Auto-generated method stub
}
@Override
public void undo(ILogRecordHelper logParser, LogicalLogLocator memLSN) throws ACIDException {
// TODO Auto-generated method stub
}
@Override
public byte getResourceManagerId() {
// TODO Auto-generated method stub
return 1;
}
}