/**
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.objectweb.speedo.stress;
import org.objectweb.speedo.pobjects.collection.AllCollection;
import org.objectweb.util.monolog.api.BasicLevel;
import javax.jdo.JDOFatalException;
import javax.jdo.PersistenceManager;
/**
*
* @author M. Guillemin
*/
public abstract class AllCollectionHelper extends StressHelper {
/**
* is the lists of object identifier prepared before the transaction
* execution.
* if (oids == null) {
* db is not initialised
* } else if (oids != null && oids.length==0) {
* db initialised and keepOid = false
* } else {
* db initialised and keepOid == true
* }
*/
protected static Object[] oids = null;
protected String DBSIZE = getLoggerName() + ".dbsize";
protected String NO_DB_INIT = getLoggerName() + ".nodbinit";
public AllCollectionHelper(String s) {
super(s);
}
protected String[] getClassNamesToInit() {
return new String[]{AllCollection.class.getName()};
}
protected boolean linkObject() {
return true;
}
protected boolean keepOid() {
return true;
}
/**
* IMPORTANT: dot not removed data on support in order to avoid next
* creations
*/
public void setUp() throws Exception {
logger.log(BasicLevel.DEBUG, "setUp.");
cleanup();
initDataStructure(false);
debug = logger.isLoggable(BasicLevel.DEBUG);
}
/**
* Creates the persistent object if it is not already done.
* @param task the task to prepare
* @param _ctx the context of the test.
*/
protected void prepareTask(Task task, Object _ctx) {
super.prepareTask(task, _ctx);
ACCtx ctx = (ACCtx) _ctx;
if (oids == null) {
synchronized (TestCollectionConcurrency.class) {
if (oids == null && !Boolean.getBoolean(NO_DB_INIT)) {
//Initialisation the database
logger.log(BasicLevel.INFO, "\tPreparing test...");
new PrepareTestAllCollection(this)
.prepare(ctx, keepOid());
if (keepOid()) {
//keep oids in the static variable
oids = ctx.oids;
} else {
//db initialized without oids
oids = new Object[0];
}
logger.log(BasicLevel.INFO, "\tTest Prepared.");
}
}
}
ctx.oids = oids;
}
/**
* The context to use for the AllCollection object
*/
public class ACCtx {
/**
* The identifier of the created object (see keepOid method)
*/
public Object oids[];
/**
* The number of persistent object
*/
public int dbSize;
/**
* indicates if the oid must be kept during the preparation of the task
*/
public boolean keepOidOnPrepare;
public ACCtx(int dbSize) {
this.dbSize = dbSize;
oids = new Object[dbSize];
}
public void initOnPrepare(int nbTx, boolean fetchOid) {
this.keepOidOnPrepare = fetchOid;
}
public String toString() {
return "dbSize = " + dbSize;
}
}
}
class PrepareTestAllCollection extends StressHelper {
private final static int NB_CREATION = 100;
private final static int NB_THREAD = 4;
public PrepareTestAllCollection(AllCollectionHelper helper) {
super(helper.getName());
}
protected String[] getClassNamesToInit() {
return new String[]{AllCollection.class.getName()};
}
protected String getLoggerName() {
return STRESS_LOG_NAME + ".AllCollectionHelper";
}
protected String getLogPrefix() {
return super.getLogPrefix() + "\t";
}
protected void perform(StressHelper.Task task,
int threadId,
int txId,
Object ctx,
PerformResult res) {
AllCollectionHelper.ACCtx pctx = (AllCollectionHelper.ACCtx) ctx;
int plus = pctx.dbSize % NB_CREATION;
int nbTx = task.txToExecute.length;
PersistenceManager pm = getPM(task, threadId, txId);
try {
res.beginTest();
beginTx(pm, task, threadId, txId);
AllCollection ac=null;
if (plus > 0) {
//The first transaction creates the additional object
for (int oid = 0; txId == 0 && oid < plus; oid++) {
long oids = (oid * 6);
//long[] ls = new long[]{oids, oids + 1, oids + 2, oids + 3, oids + 4, oids + 5};
long[] ls = new long[]{oids, oids + 1};
ac = new AllCollection("stressCollection" + oid);
ac.setLongs(ls);
ac.setRefs(new Object[]{ac});
logger.log(BasicLevel.DEBUG, "make persistent ac="+ac.getId());
pm.makePersistent(ac);
if (pctx.keepOidOnPrepare) {
pctx.oids[oid] = pm.getObjectId(ac);
}
}
}
// The other transactions create 'nbCreation' objects
for (int no = 0; no < NB_CREATION; no++) {
int oid = (txId * NB_CREATION) + no + plus;
if (oid < pctx.dbSize) {
long oids = (oid * 6);
//long[] ls = new long[]{oids, oids + 1, oids + 2, oids + 3, oids + 4, oids + 5};
long[] ls = new long[]{oids, oids + 1};
ac = new AllCollection("stressCollection" + oid);
ac.setLongs(ls);
ac.setRefs(new Object[]{ac});
logger.log(BasicLevel.DEBUG, "make persistent ac="+ac.getId());
pm.makePersistent(ac);
if (pctx.keepOidOnPrepare) {
pctx.oids[oid] = pm.getObjectId(ac);
}
}
}
commitTx(pm, task, threadId, txId);
res.endTest();
} catch (JDOFatalException e) {
rollbackOnException(pm, e, res, task, threadId, txId);
} catch (Throwable e) {
stopOnError(pm, e, res, task, threadId, txId);
} finally {
closePM(pm, threadId, txId, task, res);
}
}
public void prepare(AllCollectionHelper.ACCtx ctx, boolean fetchOid) {
int plus = ctx.dbSize % NB_CREATION;
int nbTx = (ctx.dbSize / NB_CREATION) + (plus > 0 ? 1 : 0);
ctx.initOnPrepare(nbTx, fetchOid);
perform(NB_THREAD, nbTx, Integer.getInteger(TIMEOUT, 200000).intValue(), ctx);
}
}