PerformanceBenchmark.java from Texai at Krugle
Show PerformanceBenchmark.java syntax highlighted
/*
* PerformanceBenchmark.java
*
* Created on August 10, 2007, 12:32 PM
*
* Description: Provides a performance test for the RDF Entity Manager.
*
* Copyright (C) August 10, 2007 Stephen L. Reed.
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.texai.kb.persistence.benchmark;
import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import net.jcip.annotations.Immutable;
import net.jcip.annotations.NotThreadSafe;
import net.sf.ehcache.CacheManager;
import org.apache.log4j.Logger;
import org.openrdf.OpenRDFException;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.sail.nativerdf.NativeStore;
import org.texai.kb.CacheInitializer;
import org.texai.kb.Constants;
import org.texai.kb.persistence.RDFEntityLoader;
import org.texai.kb.persistence.RDFEntityLoaderFactory;
import org.texai.kb.persistence.RDFEntityLoaderPool;
import org.texai.kb.persistence.RDFEntityManager;
import org.texai.kb.persistence.RDFEntityPersister;
import org.texai.util.TexaiException;
/**
*
* @author reed
*/
@NotThreadSafe
public class PerformanceBenchmark {
/** the number of reading threads */
private static final int NBR_THREADS = 2;
/** the indicator whether to clear and repopulate the repository */
// private static final boolean isRepositoryReset = true;
private static final boolean isRepositoryReset = false;
/** the logger */
private final Logger LOGGER = Logger.getLogger(PerformanceBenchmark.class);
/** the Sesame repository */
private Repository repository = null;
/** the Sesame repository connection */
private RepositoryConnection repositoryConnection = null;
/** the Sesame value factory */
private ValueFactory valueFactory = null;
/** the RDF entity persister */
private RDFEntityPersister rdfEntityPersister = null;
/** the number of linked RDF test entities to create */
private static final int NBR_RDF_TEST_ENTITIES_TO_CREATE = 200000;
/** the number of linked RDF test entities to randomly read */
private final int NBR_RDF_TEST_ENTITIES_TO_READ = 400000;
/** the array of RDF test entity identifying URIs */
private URI[] rdfTestEntityURI = new URI[NBR_RDF_TEST_ENTITIES_TO_CREATE];
/** the executor */
private final ExecutorService executor;
/** Creates a new instance of PerformanceBenchmark. */
public PerformanceBenchmark() {
executor = Executors.newFixedThreadPool(NBR_THREADS);
}
/** Initializes the application. */
private void initialization() {
try {
getClass().getClassLoader().setDefaultAssertionStatus(true);
CacheInitializer.initializeCaches();
// final File dataDirectory = new File(System.getProperty("user.home") + "/benchmark/");
final File dataDirectory = new File("/mnt/tmpfs/repositories/benchmark");
LOGGER.info("accessing Sesame2 repository in " + dataDirectory.toString());
final String indices = "spoc,posc";
repository = new SailRepository(new NativeStore(dataDirectory, indices));
repository.initialize();
repositoryConnection = repository.getConnection();
if (isRepositoryReset) {
LOGGER.info("clearing Sesame2 repository");
repositoryConnection.clear();
}
valueFactory = repository.getValueFactory();
} catch (final RepositoryException ex) {
throw new TexaiException(ex);
}
rdfEntityPersister = new RDFEntityPersister(repositoryConnection, valueFactory);
}
/** Finalizes the application. */
private void finalization() {
CacheManager.getInstance().shutdown();
try {
executor.shutdown();
LOGGER.info("closing the repository connection");
repositoryConnection.close();
LOGGER.info("shutting down the Sesame2 repository");
repository.shutDown();
} catch (RepositoryException ex) {
throw new TexaiException(ex);
}
LOGGER.info("Sesame2 repository shutdown");
}
/** Creates linked RDF test entities. */
private void createLinkedRDFTestEntities() {
final int nbrOfLinkedRDFTestEntityPairs = NBR_RDF_TEST_ENTITIES_TO_CREATE / 2;
final long startMillis = System.currentTimeMillis();
for (int i = 1; i <= nbrOfLinkedRDFTestEntityPairs; i++) {
createRDFTestEntity(i);
}
long secondsDuration = (System.currentTimeMillis() - startMillis) / 1000;
if (secondsDuration == 0) {
secondsDuration = 1;
}
LOGGER.info("created " + NBR_RDF_TEST_ENTITIES_TO_CREATE + " at the rate of " + NBR_RDF_TEST_ENTITIES_TO_CREATE / secondsDuration + " per second");
}
/** Queries the instance URIs. */
private void queryInstanceURIs() {
LOGGER.info("querying the instance URIs");
try {
final RepositoryConnection queryRepositoryConnection = repository.getConnection();
final String queryString =
"SELECT s FROM {s} rdf:type {<http://texai.org/texai/org.texai.kb.persistence.benchmark.RDFTestEntity>}";
LOGGER.info("query " + queryString);
final TupleQuery subjectsTupleQuery = queryRepositoryConnection.prepareTupleQuery(QueryLanguage.SERQL, queryString);
final List<URI> instanceURIs = new ArrayList<URI>();
final TupleQueryResult tupleQueryResult = subjectsTupleQuery.evaluate();
while (tupleQueryResult.hasNext()) {
instanceURIs.add((URI) tupleQueryResult.next().getBinding("s").getValue());
}
tupleQueryResult.close();
LOGGER.info("closing the query repository connection");
queryRepositoryConnection.close();
if (instanceURIs.isEmpty()) {
throw new TexaiException("no test entities selected");
}
rdfTestEntityURI = new URI[instanceURIs.size()];
rdfTestEntityURI = instanceURIs.toArray(rdfTestEntityURI);
} catch (final MalformedQueryException ex) {
throw new TexaiException(ex);
} catch (final RepositoryException ex) {
throw new TexaiException(ex);
} catch (final OpenRDFException ex) {
throw new TexaiException(ex);
}
LOGGER.info("Found " + rdfTestEntityURI.length + " instance URIs");
}
/** Randomly reads linked RDF test entities. */
private void readLinkedRDFTestEntities() {
LOGGER.info("randomly reading " + NBR_RDF_TEST_ENTITIES_TO_READ);
final long startMillis = System.currentTimeMillis();
final CountDownLatch doneSignal = new CountDownLatch(NBR_THREADS);
for (int i = 0; i < NBR_THREADS; i++) {
executor.execute(new LinkedRDFTestEntityReaderRunnable(doneSignal, i + 1));
}
try {
doneSignal.await();
} catch (InterruptedException ex) {
throw new TexaiException(ex);
}
double secondsDuration = (float) ((System.currentTimeMillis() - startMillis)) / 1000.0d;
if (secondsDuration == 0) {
secondsDuration = 1;
}
LOGGER.info("read " + NBR_RDF_TEST_ENTITIES_TO_READ + " at the rate of " + NBR_RDF_TEST_ENTITIES_TO_READ / secondsDuration + " per second");
}
/** A parallel runnable that loads random entity URIs. */
@Immutable
class LinkedRDFTestEntityReaderRunnable implements Runnable {
/** the count down latch that synchronizes the calling thread */
private final CountDownLatch doneSignal;
/** the thread id */
private final int id;
/** Constructs a new LinkedRDFTestEntityReaderRunnable instance.
*
* @param doneSignal the count down latch that synchronizes the calling thread
* @param id the identification for this runnable
*/
public LinkedRDFTestEntityReaderRunnable(final CountDownLatch doneSignal, final int id) {
//Preconditions
assert doneSignal != null : "doneSignal must not be null";
this.doneSignal = doneSignal;
this.id = id;
}
/** Executes this thread. */
public void run() {
final Random random = new Random();
RDFEntityManager rdfEntityManager = null;
try {
LOGGER.info("starting " + id);
Thread.currentThread().setName("reader " + id);
rdfEntityManager = new RDFEntityManager(repository);
int nbrTestEntitiesRead = 0;
for (int i = 1; i < (NBR_RDF_TEST_ENTITIES_TO_READ / NBR_THREADS); i++) {
nbrTestEntitiesRead++;
final URI randomURI = rdfTestEntityURI[random.nextInt(NBR_RDF_TEST_ENTITIES_TO_CREATE - 1)];
final RDFTestEntity randomRDFTestEntity = (RDFTestEntity) rdfEntityManager.find(RDFTestEntity.class, randomURI);
if (i % 10000 == 0) {
LOGGER.info(i + " --> " + randomRDFTestEntity.getName() + " thread " + id);
LOGGER.info(" " + CacheManager.getInstance().getCache(Constants.CACHE_CONNECTED_RDF_ENTITY_URIS).getStatistics().toString());
CacheInitializer.resetCaches();
}
}
LOGGER.info("thread " + id + " read " + nbrTestEntitiesRead + " entities");
doneSignal.countDown();
} catch (final Exception ex) {
LOGGER.error(ex.getMessage(), ex);
ex.printStackTrace();
} finally {
if (rdfEntityManager != null) {
rdfEntityManager.close();
}
}
}
}
/** Creates two linked RDF test entities with the given serial number suffix.
*
* @param serialNbr the given serial number suffix
*/
private void createRDFTestEntity(final int serialNbr) {
//preconditions
assert serialNbr > 0 : "serialNbr must be positive";
final RDFTestEntity rdfTestEntity1 = new RDFTestEntity();
final RDFTestEntity rdfTestEntity2 = new RDFTestEntity();
rdfTestEntity1.setDontCareField("do not care");
rdfTestEntity1.setFavoriteTestRDFEntityPeer(rdfTestEntity2);
rdfTestEntity1.setMaxNbrOfScooterRiders(2);
List<RDFTestEntity> myPeers = new ArrayList<RDFTestEntity>(1);
myPeers.add(rdfTestEntity2);
rdfTestEntity1.setMyPeers(myPeers);
rdfTestEntity1.setName("TestDomainEntity " + serialNbr);
rdfTestEntity1.setNumberOfCrew(1);
final String[] comments1 = {"comment 1", "comment 2"};
rdfTestEntity1.setComment(comments1);
Set<String> cyclistNotes = new HashSet<String>();
cyclistNotes.add("note 1");
cyclistNotes.add("note 2");
rdfTestEntity2.setDontCareField("do not care");
rdfTestEntity2.setFavoriteTestRDFEntityPeer(rdfTestEntity2);
rdfTestEntity2.setMaxNbrOfScooterRiders(2);
myPeers = new ArrayList<RDFTestEntity>(1);
myPeers.add(rdfTestEntity1);
rdfTestEntity2.setMyPeers(myPeers);
List<Double> myPeersStrengths = new ArrayList<Double>();
myPeersStrengths.add(Double.valueOf(0.5d));
rdfTestEntity2.setName("LinkedTestDomainEntity " + serialNbr);
rdfTestEntity2.setNumberOfCrew(1);
final String[] comments2 = {"comment 1", "comment 2"};
rdfTestEntity2.setComment(comments2);
// set XML datatype fields in the first test RDF entity
rdfTestEntity1.setByteField((byte) 5);
rdfTestEntity1.setIntField(6);
rdfTestEntity1.setLongField(7L);
rdfTestEntity1.setFloatField(1.1F);
rdfTestEntity1.setDoubleField(1.2D);
rdfTestEntity1.setBigIntegerField(new BigInteger("100"));
rdfTestEntity1.setBigDecimalField(new BigDecimal("100.001"));
rdfTestEntity1.setCalendarField(Calendar.getInstance());
rdfTestEntity1.setDateField(Calendar.getInstance().getTime());
// set XML datatype fields in the linked test RDF entity
rdfTestEntity2.setByteField((byte) 5);
rdfTestEntity2.setIntField(6);
rdfTestEntity2.setLongField(7L);
rdfTestEntity2.setFloatField(1.1F);
rdfTestEntity2.setDoubleField(1.2D);
rdfTestEntity2.setBigIntegerField(new BigInteger("100"));
rdfTestEntity2.setBigDecimalField(new BigDecimal("100.001"));
rdfTestEntity2.setCalendarField(Calendar.getInstance());
rdfTestEntity2.setDateField(Calendar.getInstance().getTime());
// persist will cascade to rdfTestEntity2
rdfEntityPersister.persist(rdfTestEntity1);
rdfTestEntityURI[serialNbr - 1] = new URIImpl(rdfTestEntity1.getRDFEntityId());
}
/** Executes this application.
*
* @param args the command line arguments (unused)
*/
public static void main(final String[] args) {
final PerformanceBenchmark performanceBenchmark = new PerformanceBenchmark();
performanceBenchmark.initialization();
if (isRepositoryReset) {
performanceBenchmark.createLinkedRDFTestEntities();
}
performanceBenchmark.queryInstanceURIs();
performanceBenchmark.readLinkedRDFTestEntities();
performanceBenchmark.finalization();
}
}
See more files for this project here