001: /**
002: * Copyright (C) 2001-2004 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.speedo.stress;
018:
019: import org.objectweb.speedo.pobjects.userid.IntUserId;
020: import org.objectweb.util.monolog.api.BasicLevel;
021:
022: import javax.jdo.JDOFatalException;
023: import javax.jdo.PersistenceManager;
024:
025: /**
026: *
027: * @author S.Chassande-Barrioz
028: */
029: public abstract class IntUserIdHelper extends StressHelper {
030:
031: /**
032: * is the lists of object identifier prepared before the transaction
033: * execution.
034: * if (oids == null) {
035: * db is not initialised
036: * } else if (oids != null && oids.length==0) {
037: * db initialised and keepOid = false
038: * } else {
039: * db initialised and keepOid == true
040: * }
041: */
042: protected static Object[] oids = null;
043: protected String DBSIZE = getLoggerName() + ".dbsize";
044: protected String NO_DB_INIT = getLoggerName() + ".nodbinit";
045:
046: public class IUICtx {
047: public Object oids[];
048: public int dbSize;
049: public boolean keepOid;
050:
051: public IUICtx(int dbSize) {
052: this .dbSize = dbSize;
053: keepOid = false;
054: }
055:
056: public String toString() {
057: return "dbSize = " + dbSize;
058: }
059: }
060:
061: public IntUserIdHelper(String s) {
062: super (s);
063: }
064:
065: /**
066: * Default implementation return true.
067: * @return true if the oid of the created object must be kept into the
068: * context
069: */
070: protected boolean keepOid() {
071: return true;
072: }
073:
074: protected String[] getClassNamesToInit() {
075: return new String[] { IntUserId.class.getName() };
076: }
077:
078: /**
079: * IMPORTANT: dot not removed data on support in order to avoid next
080: * creations
081: */
082: public void setUp() throws Exception {
083: logger.log(BasicLevel.DEBUG, "setUp.");
084: cleanup();
085: initDataStructure(false);
086: }
087:
088: protected void prepareTask(Task task, Object _ctx) {
089: debug = logger.isLoggable(BasicLevel.DEBUG);
090: super .prepareTask(task, _ctx);
091: IUICtx ctx = (IUICtx) _ctx;
092: if (oids == null) {
093: synchronized (getClass()) {
094: if (oids == null && !Boolean.getBoolean(NO_DB_INIT)) {
095: ctx.oids = new Object[ctx.dbSize];
096: logger.log(BasicLevel.INFO, "\tPreparing test...");
097: //Initialisation the database
098: PrepareTest prep = new PrepareTest(this );
099: try {
100: prep.setUp();
101: } catch (Exception e) {
102: fail(e.getMessage());
103: }
104: prep.prepare(ctx, keepOid());
105: prep.tearDown();
106: logger.log(BasicLevel.INFO, "\ttest Prepared");
107: if (keepOid()) {
108: //keep oids in the static variable
109: oids = ctx.oids;
110: } else {
111: //db initialized without oids
112: oids = new Object[0];
113: }
114: }
115: }
116: }
117: ctx.oids = oids;
118: }
119: }
120:
121: class PrepareTest extends StressHelper {
122:
123: private final static int NB_CREATION = 100;
124: private final static int NB_THREAD = 4;
125:
126: public PrepareTest(IntUserIdHelper helper) {
127: super (helper.getName());
128: }
129:
130: protected String[] getClassNamesToInit() {
131: return new String[] { IntUserId.class.getName() };
132: }
133:
134: protected String getLoggerName() {
135: return STRESS_LOG_NAME + ".IntUserIdHelper";
136: }
137:
138: protected String getLogPrefix() {
139: return super .getLogPrefix() + "\t";
140: }
141:
142: /**
143: * IMPORTANT: dot not removed data on support in order to avoid next
144: * creations
145: */
146: public void setUp() throws Exception {
147: logger.log(BasicLevel.DEBUG, "setUp.");
148: cleanup();
149: initDataStructure(false);
150: }
151:
152: protected void perform(StressHelper.Task task, int threadId,
153: int txId, Object ctx, PerformResult res) {
154: IntUserIdHelper.IUICtx gctx = (IntUserIdHelper.IUICtx) ctx;
155: final int plus = gctx.dbSize % NB_CREATION;
156: PersistenceManager pm = getPM(task, threadId, txId);
157: try {
158: res.beginTest();
159: beginTx(pm, task, threadId, txId);
160: if (plus > 0) {
161: //The first transaction creates the additional object
162: for (int oid = 0; txId == 0 && oid < plus; oid++) {
163: IntUserId iui = new IntUserId(oid, "Obj No " + oid);
164: pm.makePersistent(iui);
165: if (gctx.keepOid) {
166: gctx.oids[oid] = pm.getObjectId(iui);
167: }
168: }
169: }
170: // The other transactions create 'nbCreation' objects
171: for (int no = 0; no < NB_CREATION; no++) {
172: int oid = (txId * NB_CREATION) + no + plus;
173: if (oid < gctx.dbSize) {
174: IntUserId iui = new IntUserId(oid, "Obj No " + oid);
175: pm.makePersistent(iui);
176: if (gctx.keepOid) {
177: gctx.oids[oid] = pm.getObjectId(iui);
178: }
179: }
180: }
181:
182: commitTx(pm, task, threadId, txId);
183: res.endTest();
184: } catch (JDOFatalException e) {
185: rollbackOnException(pm, e, res, task, threadId, txId);
186: } catch (Throwable e) {
187: stopOnError(pm, e, res, task, threadId, txId);
188: } finally {
189: closePM(pm, threadId, txId, task, res);
190: }
191: }
192:
193: /**
194: * Tests the concurrency of several writer on a same persistent object.
195: * (500 users)
196: */
197: public void prepare(IntUserIdHelper.IUICtx ctx, boolean keepOid) {
198: int plus = ctx.dbSize % NB_CREATION;
199: int nbTx = (ctx.dbSize / NB_CREATION) + (plus > 0 ? 1 : 0);
200: ctx.keepOid = keepOid;
201: perform(NB_THREAD, nbTx, Integer.getInteger(TIMEOUT, 200000)
202: .intValue(), ctx);
203: }
204: }
|