1 8 9 package com.sleepycat.je.dbi; 10 11 import java.io.File ; 12 13 import junit.framework.TestCase; 14 15 import com.sleepycat.bind.tuple.IntegerBinding; 16 import com.sleepycat.je.BtreeStats; 17 import com.sleepycat.je.Cursor; 18 import com.sleepycat.je.Database; 19 import com.sleepycat.je.DatabaseConfig; 20 import com.sleepycat.je.DatabaseEntry; 21 import com.sleepycat.je.DatabaseException; 22 import com.sleepycat.je.DbInternal; 23 import com.sleepycat.je.Environment; 24 import com.sleepycat.je.EnvironmentConfig; 25 import com.sleepycat.je.LockMode; 26 import com.sleepycat.je.OperationStatus; 27 import com.sleepycat.je.Transaction; 28 import com.sleepycat.je.config.EnvironmentParams; 29 import com.sleepycat.je.dbi.SortedLSNTreeWalker.TreeNodeProcessor; 30 import com.sleepycat.je.log.FileManager; 31 import com.sleepycat.je.log.LogEntryType; 32 import com.sleepycat.je.tree.Node; 33 import com.sleepycat.je.util.TestUtils; 34 import com.sleepycat.je.utilint.DbLsn; 35 36 public class SortedLSNTreeWalkerTest extends TestCase { 37 private static boolean DEBUG = false; 38 39 40 private static final int NODE_MAX = 6; 41 private static final int N_RECS = 30; 42 43 private File envHome; 44 private Environment env; 45 private Database db; 46 47 public SortedLSNTreeWalkerTest() 48 throws Exception { 49 50 envHome = new File (System.getProperty(TestUtils.DEST_DIR)); 51 } 52 53 public void setUp() 54 throws Exception { 55 56 TestUtils.removeFiles("Setup", envHome, FileManager.JE_SUFFIX); 57 } 58 59 public void tearDown() 60 throws Exception { 61 62 if (env != null) { 63 try { 64 env.close(); 65 } catch (Exception e) { 66 System.err.println("TearDown: " + e); 67 } 68 } 69 env = null; 70 TestUtils.removeFiles("TearDown", envHome, FileManager.JE_SUFFIX); 71 } 72 73 public void testSortedLSNTreeWalkerNoDupsReadingINList() 74 throws Throwable { 75 76 open(false); 77 writeData(false); 78 BtreeStats stats = (BtreeStats) db.getStats(null); 79 if (DEBUG) { 80 System.out.println("***************"); 81 DbInternal.dbGetDatabaseImpl(db).getTree().dump(); 82 } 83 close(); 84 if (DEBUG) { 85 System.out.println("***************"); 86 } 87 open(false); 88 readData(); 89 if (DEBUG) { 90 DbInternal.dbGetDatabaseImpl(db).getTree().dump(); 91 System.out.println("***************"); 92 } 93 DatabaseImpl dbImpl = DbInternal.dbGetDatabaseImpl(db); 94 db.close(); 95 db = null; 96 assertEquals(N_RECS, walkTree(dbImpl, false, stats, true)); 97 close(); 98 } 99 100 public void testSortedLSNTreeWalkerNoDupsLoadLNs() 101 throws Throwable { 102 103 doTestSortedLSNTreeWalkerNoDups(true); 104 } 105 106 public void testSortedLSNTreeWalkerNoDupsNoLoadLNs() 107 throws Throwable { 108 109 doTestSortedLSNTreeWalkerNoDups(false); 110 } 111 112 private void doTestSortedLSNTreeWalkerNoDups(boolean loadLNs) 113 throws Throwable { 114 115 open(false); 116 writeData(false); 117 if (DEBUG) { 118 System.out.println("***************"); 119 DbInternal.dbGetDatabaseImpl(db).getTree().dump(); 120 } 121 BtreeStats stats = (BtreeStats) db.getStats(null); 122 close(); 123 if (DEBUG) { 124 System.out.println("***************"); 125 } 126 open(false); 127 readData(); 128 if (DEBUG) { 129 DbInternal.dbGetDatabaseImpl(db).getTree().dump(); 130 System.out.println("***************"); 131 } 132 DatabaseImpl dbImpl = DbInternal.dbGetDatabaseImpl(db); 133 db.close(); 134 db = null; 135 assertEquals(N_RECS, walkTree(dbImpl, false, stats, loadLNs)); 136 close(); 137 } 138 139 public void testSortedLSNTreeWalkerNoDupsDupsAllowed() 140 throws Throwable { 141 142 open(true); 143 writeData(false); 144 if (DEBUG) { 145 System.out.println("***************"); 146 DbInternal.dbGetDatabaseImpl(db).getTree().dump(); 147 } 148 BtreeStats stats = (BtreeStats) db.getStats(null); 149 close(); 150 if (DEBUG) { 151 System.out.println("***************"); 152 } 153 open(true); 154 if (DEBUG) { 155 DbInternal.dbGetDatabaseImpl(db).getTree().dump(); 156 System.out.println("***************"); 157 } 158 DatabaseImpl dbImpl = DbInternal.dbGetDatabaseImpl(db); 159 db.close(); 160 db = null; 161 assertEquals(N_RECS, walkTree(dbImpl, false, stats, true)); 162 close(); 163 } 164 165 public void testSortedLSNTreeWalkerDups() 166 throws Throwable { 167 168 doTestSortedLSNTreeWalkerDups(true); 169 } 170 171 public void testSortedLSNTreeWalkerDupsNoLoadLNs() 172 throws Throwable { 173 174 doTestSortedLSNTreeWalkerDups(false); 175 } 176 177 private void doTestSortedLSNTreeWalkerDups(boolean loadLNs) 178 throws Throwable { 179 180 open(true); 181 writeData(true); 182 BtreeStats stats = (BtreeStats) db.getStats(null); 183 close(); 184 open(true); 185 DatabaseImpl dbImpl = DbInternal.dbGetDatabaseImpl(db); 186 db.close(); 187 db = null; 188 assertEquals(N_RECS * 2, walkTree(dbImpl, true, stats, loadLNs)); 189 close(); 190 } 191 192 public void testSortedLSNTreeWalkerDupsReadingINList() 193 throws Throwable { 194 195 open(true); 196 writeData(true); 197 BtreeStats stats = (BtreeStats) db.getStats(null); 198 close(); 199 open(true); 200 readData(); 201 DatabaseImpl dbImpl = DbInternal.dbGetDatabaseImpl(db); 202 db.close(); 203 db = null; 204 assertEquals(N_RECS * 2, walkTree(dbImpl, false, stats, true)); 205 close(); 206 } 207 208 public void testSortedLSNTreeWalkerPendingDeleted() 209 throws Throwable { 210 211 open(true); 212 int numRecs = writeDataWithDeletes(); 213 BtreeStats stats = (BtreeStats) db.getStats(null); 214 close(); 215 open(true); 216 readData(); 217 DatabaseImpl dbImpl = DbInternal.dbGetDatabaseImpl(db); 218 db.close(); 219 db = null; 220 assertEquals(numRecs, walkTree(dbImpl, false, stats, true)); 221 close(); 222 } 223 224 private void open(boolean allowDuplicates) 225 throws Exception { 226 227 EnvironmentConfig envConfig = TestUtils.initEnvConfig(); 228 envConfig.setConfigParam 229 (EnvironmentParams.NODE_MAX.getName(), String.valueOf(NODE_MAX)); 230 238 239 envConfig.setConfigParam 240 (EnvironmentParams.ENV_RUN_EVICTOR.getName(), "false"); 241 242 envConfig.setConfigParam 243 (EnvironmentParams.ENV_RUN_INCOMPRESSOR.getName(), "false"); 244 245 envConfig.setTransactional(true); 246 envConfig.setAllowCreate(true); 247 env = new Environment(envHome, envConfig); 248 249 DatabaseConfig dbConfig = new DatabaseConfig(); 250 dbConfig.setAllowCreate(true); 251 dbConfig.setExclusiveCreate(false); 252 dbConfig.setTransactional(true); 253 dbConfig.setSortedDuplicates(allowDuplicates); 254 db = env.openDatabase(null, "testDb", dbConfig); 255 } 256 257 private void writeData(boolean dups) 258 throws DatabaseException { 259 260 DatabaseEntry key = new DatabaseEntry(); 261 DatabaseEntry data = new DatabaseEntry(); 262 for (int i = 0; i < N_RECS; i++) { 263 IntegerBinding.intToEntry(i, key); 264 data.setData(new byte[1000]); 265 assertEquals(db.put(null, key, data), 266 OperationStatus.SUCCESS); 267 if (dups) { 268 IntegerBinding.intToEntry(i + N_RECS + N_RECS, data); 269 assertEquals(db.put(null, key, data), 270 OperationStatus.SUCCESS); 271 } 272 } 273 } 274 275 private int writeDataWithDeletes() 276 throws DatabaseException { 277 278 DatabaseEntry key = new DatabaseEntry(); 279 DatabaseEntry data = new DatabaseEntry(); 280 int numInserted = 0; 281 282 data.setData(new byte[10]); 283 284 for (int i = 0; i < N_RECS; i++) { 285 IntegerBinding.intToEntry(i, key); 286 Transaction txn = env.beginTransaction(null, null); 287 assertEquals(db.put(txn, key, data), 288 OperationStatus.SUCCESS); 289 boolean deleted = false; 290 if ((i%2) ==0) { 291 assertEquals(db.delete(txn, key), 292 OperationStatus.SUCCESS); 293 deleted = true; 294 } 295 if ((i%3)== 0){ 296 txn.abort(); 297 } else { 298 txn.commit(); 299 if (!deleted) { 300 numInserted++; 301 } 302 } 303 } 304 return numInserted; 305 } 306 307 private void readData() 308 throws DatabaseException { 309 310 DatabaseEntry key = new DatabaseEntry(); 311 DatabaseEntry data = new DatabaseEntry(); 312 IntegerBinding.intToEntry(N_RECS - 1, key); 313 assertEquals(db.get(null, key, data, LockMode.DEFAULT), 314 OperationStatus.SUCCESS); 315 } 316 317 private void scanData() 318 throws DatabaseException { 319 320 DatabaseEntry key = new DatabaseEntry(); 321 DatabaseEntry data = new DatabaseEntry(); 322 Cursor cursor = db.openCursor(null, null); 323 while (cursor.getNext(key, data, LockMode.DEFAULT) == 324 OperationStatus.SUCCESS) { 325 } 326 cursor.close(); 327 } 328 329 330 private int walkTree(DatabaseImpl dbImpl, 331 boolean dups, 332 BtreeStats stats, 333 final boolean loadLNNodes) 334 throws DatabaseException { 335 336 TestingTreeNodeProcessor tnp = new TestingTreeNodeProcessor() { 337 public void processLSN(long childLSN, 338 LogEntryType childType, 339 Node node, 340 byte[] lnKey) 341 throws DatabaseException { 342 343 if (DEBUG) { 344 System.out.println 345 (childType + " " + DbLsn.toString(childLSN)); 346 } 347 348 if (childType.equals(LogEntryType.LOG_DBIN)) { 349 dbinCount++; 350 assertNull(lnKey); 351 assertNotNull(node); 352 } else if (childType.equals(LogEntryType.LOG_BIN)) { 353 binCount++; 354 assertNull(lnKey); 355 assertNotNull(node); 356 } else if (childType.equals(LogEntryType.LOG_DIN)) { 357 dinCount++; 358 assertNull(lnKey); 359 assertNotNull(node); 360 } else if (childType.equals(LogEntryType.LOG_IN)) { 361 inCount++; 362 assertNull(lnKey); 363 assertNotNull(node); 364 } else if (childType.equals(LogEntryType.LOG_LN)) { 365 entryCount++; 366 assertNotNull(lnKey); 367 if (loadLNNodes) { 368 assertNotNull(node); 369 } 370 } else if (childType.equals(LogEntryType.LOG_DUPCOUNTLN)) { 371 dupLNCount++; 372 assertNotNull(lnKey); 373 assertNotNull(node); 374 } else { 375 throw new RuntimeException 376 ("unknown entry type: " + childType); 377 } 378 } 379 380 public void processDupCount(long ignore) { 381 } 382 }; 383 384 SortedLSNTreeWalker walker = 385 new SortedLSNTreeWalker(dbImpl, false, false, 386 dbImpl.getTree().getRootLsn(), tnp, 387 null, 388 null); 389 390 walker.accumulateLNs = loadLNNodes; 391 392 walker.walk(); 393 394 if (DEBUG) { 395 System.out.println(stats); 396 } 397 398 399 assertEquals(stats.getInternalNodeCount(), tnp.inCount + 1); 400 assertEquals(stats.getBottomInternalNodeCount(), tnp.binCount); 401 assertEquals(stats.getDuplicateInternalNodeCount(), tnp.dinCount); 402 assertEquals(stats.getDuplicateBottomInternalNodeCount(), 403 tnp.dbinCount); 404 assertEquals(stats.getLeafNodeCount(), tnp.entryCount); 405 assertEquals(stats.getDupCountLeafNodeCount(), tnp.dupLNCount); 406 if (DEBUG) { 407 System.out.println("INs: " + tnp.inCount); 408 System.out.println("BINs: " + tnp.binCount); 409 System.out.println("DINs: " + tnp.dinCount); 410 System.out.println("DBINs: " + tnp.dbinCount); 411 System.out.println("entries: " + tnp.entryCount); 412 System.out.println("dupLN: " + tnp.dupLNCount); 413 } 414 415 return tnp.entryCount; 416 } 417 418 private static class TestingTreeNodeProcessor 419 implements TreeNodeProcessor { 420 421 int binCount = 0; 422 int dbinCount = 0; 423 int dinCount = 0; 424 int inCount = 0; 425 int entryCount = 0; 426 int dupLNCount = 0; 427 428 public void processLSN(long childLSN, 429 LogEntryType childType, 430 Node ignore, 431 byte[] ignore2) 432 throws DatabaseException { 433 434 throw new RuntimeException ("override me please"); 435 } 436 437 public void processDupCount(long ignore) { 438 throw new RuntimeException ("override me please"); 439 } 440 } 441 442 private void close() 443 throws Exception { 444 445 if (db != null) { 446 db.close(); 447 db = null; 448 } 449 450 if (env != null) { 451 env.close(); 452 env = null; 453 } 454 } 455 } 456 | Popular Tags |