1 8 9 package com.sleepycat.je.txn; 10 11 import java.io.File ; 12 import java.io.IOException ; 13 import java.util.Enumeration ; 14 15 import junit.framework.Test; 16 import junit.framework.TestCase; 17 import junit.framework.TestSuite; 18 19 import com.sleepycat.bind.tuple.IntegerBinding; 20 import com.sleepycat.je.Cursor; 21 import com.sleepycat.je.Database; 22 import com.sleepycat.je.DatabaseConfig; 23 import com.sleepycat.je.DatabaseEntry; 24 import com.sleepycat.je.DatabaseException; 25 import com.sleepycat.je.DbInternal; 26 import com.sleepycat.je.Environment; 27 import com.sleepycat.je.EnvironmentConfig; 28 import com.sleepycat.je.OperationStatus; 29 import com.sleepycat.je.Transaction; 30 import com.sleepycat.je.config.EnvironmentParams; 31 import com.sleepycat.je.dbi.EnvironmentImpl; 32 import com.sleepycat.je.dbi.MemoryBudget; 33 import com.sleepycat.je.log.FileManager; 34 import com.sleepycat.je.tree.IN; 35 import com.sleepycat.je.tree.LN; 36 import com.sleepycat.je.txn.Txn; 37 import com.sleepycat.je.util.TestUtils; 38 39 public class TxnMemoryTest extends TestCase { 40 private static final boolean DEBUG = false; 41 private static final String DB_NAME = "foo"; 42 43 private static final String LOCK_AUTOTXN = "lock-autotxn"; 44 private static final String LOCK_USERTXN = "lock-usertxn"; 45 private static final String LOCK_NOTXN = "lock-notxn"; 46 private static final String [] LOCK_MODE = {LOCK_AUTOTXN, 47 LOCK_USERTXN, 48 LOCK_NOTXN}; 49 private static final String COMMIT = "commit"; 50 private static final String ABORT = "abort"; 51 private static final String [] END_MODE = {COMMIT, ABORT}; 52 53 private File envHome; 54 private Environment env; 55 private EnvironmentImpl envImpl; 56 private MemoryBudget mb; 57 private Database db; 58 private DatabaseEntry keyEntry = new DatabaseEntry(); 59 private DatabaseEntry dataEntry = new DatabaseEntry(); 60 private String lockMode; 61 private String endMode; 62 63 private long beforeAction; 64 private long afterTxnsCreated; 65 private long afterAction; 66 private Transaction [] txns; 67 68 private int numTxns = 2; 69 private int numRecordsPerTxn = 30; 70 71 public static Test suite() { 72 TestSuite allTests = new TestSuite(); 73 for (int i = 0; i < LOCK_MODE.length; i += 1) { 74 for (int eMode = 0; eMode < END_MODE.length; eMode ++) { 75 TestSuite suite = new TestSuite(TxnMemoryTest.class); 76 Enumeration e = suite.tests(); 77 while (e.hasMoreElements()) { 78 TxnMemoryTest test = (TxnMemoryTest) e.nextElement(); 79 test.init(LOCK_MODE[i], END_MODE[eMode]); 80 allTests.addTest(test); 81 } 82 } 83 } 84 return allTests; 85 } 86 87 public TxnMemoryTest() { 88 envHome = new File (System.getProperty(TestUtils.DEST_DIR)); 89 } 90 91 private void init(String lockMode, String endMode) { 92 this.lockMode = lockMode; 93 this.endMode = endMode; 94 } 95 96 public void setUp() 97 throws IOException , DatabaseException { 98 99 IN.ACCUMULATED_LIMIT = 0; 100 Txn.ACCUMULATED_LIMIT = 0; 101 102 TestUtils.removeLogFiles("Setup", envHome, false); 103 TestUtils.removeFiles("Setup", envHome, FileManager.DEL_SUFFIX); 104 } 105 106 public void tearDown() 107 throws IOException , DatabaseException { 108 109 110 setName(lockMode + '/' + endMode + ":" + getName()); 111 112 try { 113 if (env != null) { 114 env.close(); 115 } 116 } catch (Throwable e) { 117 System.out.println("tearDown: " + e); 118 } 119 120 try { 121 TestUtils.removeLogFiles("tearDown", envHome, true); 122 TestUtils.removeFiles("tearDown", envHome, FileManager.DEL_SUFFIX); 123 } catch (Throwable e) { 124 System.out.println("tearDown: " + e); 125 } 126 127 db = null; 128 env = null; 129 } 130 131 134 private void openEnv() 135 throws DatabaseException { 136 137 EnvironmentConfig config = TestUtils.initEnvConfig(); 138 139 143 DbInternal.setTxnReadCommitted(config, false); 144 145 146 config.setConfigParam 147 (EnvironmentParams.CLEANER_TRACK_DETAIL.getName(), "false"); 148 149 config.setTransactional(true); 150 config.setAllowCreate(true); 151 env = new Environment(envHome, config); 152 envImpl = DbInternal.envGetEnvironmentImpl(env); 153 mb = envImpl.getMemoryBudget(); 154 155 DatabaseConfig dbConfig = new DatabaseConfig(); 156 dbConfig.setTransactional(!lockMode.equals(LOCK_NOTXN)); 157 dbConfig.setAllowCreate(true); 158 db = env.openDatabase(null, DB_NAME, dbConfig); 159 } 160 161 164 private void closeEnv(boolean doCheckpoint) 165 throws DatabaseException { 166 167 if (db != null) { 168 db.close(); 169 db = null; 170 } 171 if (env != null) { 172 env.close(); 173 env = null; 174 } 175 } 176 177 182 public void testWriteLocks() 183 throws DatabaseException { 184 185 loadData(); 186 187 188 194 for (int t = 0; t < numTxns; t++) { 195 for (int i = 0; i < numRecordsPerTxn; i++) { 196 int value = i + (t*numRecordsPerTxn); 197 IntegerBinding.intToEntry(value, keyEntry); 198 IntegerBinding.intToEntry(value+1, dataEntry); 199 assertEquals(db.put(txns[t], keyEntry, dataEntry), 200 OperationStatus.SUCCESS); 201 } 202 } 203 afterAction = mb.getCacheMemoryUsage(); 204 205 closeTxns(true); 206 } 207 208 213 public void testReadLocks() 214 throws DatabaseException { 215 216 loadData(); 217 218 222 for (int t = 0; t < numTxns; t++) { 223 Cursor c = db.openCursor(txns[t], null); 224 while (c.getNext(keyEntry, dataEntry, null) == 225 OperationStatus.SUCCESS) { 226 } 227 c.close(); 228 } 229 afterAction = mb.getCacheMemoryUsage(); 230 231 closeTxns(false); 232 } 233 234 private void loadData() 235 throws DatabaseException { 236 237 openEnv(); 238 239 240 for (int t = 0; t < numTxns; t++) { 241 for (int i = 0; i < numRecordsPerTxn; i++) { 242 243 int value = i + (t*numRecordsPerTxn); 244 IntegerBinding.intToEntry(value, keyEntry); 245 IntegerBinding.intToEntry(value, dataEntry); 246 assertEquals(db.put(null, keyEntry, dataEntry), 247 OperationStatus.SUCCESS); 248 } 249 } 250 251 beforeAction = mb.getCacheMemoryUsage(); 252 253 254 txns = new Transaction[numTxns]; 255 if (lockMode.equals(LOCK_USERTXN)) { 256 for (int t = 0; t < numTxns; t++) { 257 txns[t] = env.beginTransaction(null, null); 258 } 259 260 afterTxnsCreated = mb.getCacheMemoryUsage(); 261 assertTrue( "afterTxns=" + afterTxnsCreated + 262 "beforeUpdate=" + beforeAction, 263 (afterTxnsCreated > beforeAction)); 264 } 265 } 266 267 private void closeTxns(boolean writesDone) 268 throws DatabaseException { 269 270 assertTrue(afterAction > afterTxnsCreated); 271 272 278 if (lockMode.equals(LOCK_USERTXN)) { 279 280 289 long expectedLockUsage = 290 (numRecordsPerTxn * numTxns * 291 (LockManager.TOTAL_LOCK_OVERHEAD + 292 MemoryBudget.LOCKINFO_OVERHEAD)); 293 294 long expectedFreedNodeMemory = 0; 295 296 301 if (endMode.equals(ABORT) && 302 writesDone) { 303 LN sampleLN = new LN(dataEntry); 304 expectedFreedNodeMemory += 305 ((numRecordsPerTxn * numTxns) * 306 sampleLN.getMemorySizeIncludedByParent()); 307 } 308 309 assertTrue((afterAction - afterTxnsCreated) >= expectedLockUsage); 310 311 for (int t = 0; t < numTxns; t++) { 312 Transaction txn = txns[t]; 313 if (endMode.equals(COMMIT)) { 314 txn.commit(); 315 } else { 316 txn.abort(); 317 } 318 } 319 320 long afterTxnEnd = mb.getCacheMemoryUsage(); 321 322 assertTrue("lockMode=" + lockMode + 323 " endMode=" + endMode + 324 " afterTxnEnd=" + afterTxnEnd + 325 " beforeAction=" + beforeAction + 326 " expectedFreed=" + expectedFreedNodeMemory, 327 (afterTxnEnd <= 328 (beforeAction - expectedFreedNodeMemory))); 329 } 330 if (DEBUG) { 331 System.out.println("afterUpdate = " + afterAction + 332 " before=" + beforeAction); 333 } 334 335 closeEnv(true); 336 } 337 } 338 | Popular Tags |