1 8 9 package com.sleepycat.je.evictor; 10 11 import java.io.File ; 12 import java.io.IOException ; 13 14 import junit.framework.TestCase; 15 16 import com.sleepycat.bind.tuple.IntegerBinding; 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.EnvironmentMutableConfig; 26 import com.sleepycat.je.LockMode; 27 import com.sleepycat.je.OperationStatus; 28 import com.sleepycat.je.config.EnvironmentParams; 29 import com.sleepycat.je.dbi.EnvironmentImpl; 30 import com.sleepycat.je.dbi.MemoryBudget; 31 import com.sleepycat.je.junit.JUnitThread; 32 import com.sleepycat.je.tree.IN; 33 import com.sleepycat.je.txn.Txn; 34 import com.sleepycat.je.util.TestUtils; 35 36 40 public class EvictActionTest extends TestCase { 41 42 private static final boolean DEBUG = false; 43 private static final int NUM_KEYS = 60; 44 private static final int NUM_DUPS = 30; 45 private static final int BIG_CACHE_SIZE = 500000; 46 private static final int SMALL_CACHE_SIZE = (int) 47 MemoryBudget.MIN_MAX_MEMORY_SIZE; 48 49 private File envHome = null; 50 private Environment env = null; 51 private Database db = null; 52 53 public EvictActionTest() { 54 envHome = new File (System.getProperty(TestUtils.DEST_DIR)); 55 } 56 57 public void setUp() 58 throws IOException { 59 60 IN.ACCUMULATED_LIMIT = 0; 61 Txn.ACCUMULATED_LIMIT = 0; 62 63 TestUtils.removeLogFiles("Setup", envHome, false); 64 } 65 66 public void tearDown() 67 throws Exception { 68 69 TestUtils.removeLogFiles("TearDown", envHome, false); 70 71 if (env != null) { 72 try { 73 env.close(); 74 } catch (Throwable e) { 75 System.out.println("tearDown: " + e); 76 } 77 } 78 79 envHome = null; 80 env = null; 81 db = null; 82 } 83 84 public void testEvict() 85 throws Throwable { 86 87 try { 88 doEvict(50, SMALL_CACHE_SIZE, true); 89 } catch (Throwable t) { 90 t.printStackTrace(); 91 throw t; 92 } 93 } 94 95 public void testNoNeedToEvict() 96 throws Throwable { 97 98 try { 99 doEvict(80, BIG_CACHE_SIZE, false); 100 } catch (Throwable t) { 101 t.printStackTrace(); 102 throw t; 103 } 104 } 105 106 110 private void doEvict(int floor, 111 int maxMem, 112 boolean shouldEvict) 113 throws Throwable { 114 115 try { 116 openEnv(floor, maxMem); 117 insertData(NUM_KEYS); 118 119 120 evictAndCheck(shouldEvict, NUM_KEYS); 121 122 123 evictAndCheck(shouldEvict, NUM_KEYS); 124 125 closeEnv(); 126 } catch (Throwable t) { 127 t.printStackTrace(); 128 throw (t); 129 } 130 } 131 132 public void testSetCacheSize() 133 throws DatabaseException { 134 135 136 openEnv(80, BIG_CACHE_SIZE); 137 EnvironmentMutableConfig config = env.getMutableConfig(); 138 insertData(NUM_KEYS); 139 140 141 verifyData(NUM_KEYS); 142 evictAndCheck(false, NUM_KEYS); 143 144 145 config.setCacheSize(SMALL_CACHE_SIZE); 146 env.setMutableConfig(config); 147 148 149 verifyData(NUM_KEYS); 150 evictAndCheck(true, NUM_KEYS); 151 152 153 config.setCacheSize(BIG_CACHE_SIZE); 154 env.setMutableConfig(config); 155 156 157 verifyData(NUM_KEYS); 158 evictAndCheck(false, NUM_KEYS); 159 160 closeEnv(); 161 } 162 163 public void testSetCachePercent() 164 throws DatabaseException { 165 166 int nKeys = NUM_KEYS * 500; 167 168 169 openEnv(80, BIG_CACHE_SIZE); 170 EnvironmentMutableConfig config = env.getMutableConfig(); 171 config.setCacheSize(0); 172 config.setCachePercent(90); 173 env.setMutableConfig(config); 174 insertData(nKeys); 175 176 177 verifyData(nKeys); 178 evictAndCheck(false, nKeys); 179 180 181 config.setCacheSize(0); 182 config.setCachePercent(1); 183 env.setMutableConfig(config); 184 185 186 verifyData(nKeys); 187 evictAndCheck(true, nKeys); 188 189 190 config.setCacheSize(0); 191 config.setCachePercent(90); 192 env.setMutableConfig(config); 193 194 195 verifyData(nKeys); 196 evictAndCheck(false, nKeys); 197 198 closeEnv(); 199 } 200 201 public void testThreadedCacheSizeChanges() 202 throws DatabaseException { 203 204 final int N_ITERS = 10; 205 openEnv(80, BIG_CACHE_SIZE); 206 insertData(NUM_KEYS); 207 208 JUnitThread writer = new JUnitThread("Writer") { 209 public void testBody() 210 throws DatabaseException { 211 for (int i = 0; i < N_ITERS; i += 1) { 212 env.evictMemory(); 213 214 insertData(NUM_KEYS); 215 env.evictMemory(); 216 EnvironmentMutableConfig config = env.getMutableConfig(); 217 config.setCacheSize(SMALL_CACHE_SIZE); 218 env.setMutableConfig(config); 219 } 220 } 221 }; 222 223 JUnitThread reader = new JUnitThread("Reader") { 224 public void testBody() 225 throws DatabaseException { 226 for (int i = 0; i < N_ITERS; i += 1) { 227 env.evictMemory(); 228 verifyData(NUM_KEYS); 229 env.evictMemory(); 230 EnvironmentMutableConfig config = env.getMutableConfig(); 231 config.setCacheSize(BIG_CACHE_SIZE); 232 env.setMutableConfig(config); 233 } 234 } 235 }; 236 237 writer.start(); 238 reader.start(); 239 240 try { 241 writer.finishTest(); 242 } catch (Throwable e) { 243 try { 244 reader.finishTest(); 245 } catch (Throwable ignore) { } 246 e.printStackTrace(); 247 fail(e.toString()); 248 } 249 250 try { 251 reader.finishTest(); 252 } catch (Throwable e) { 253 e.printStackTrace(); 254 fail(e.toString()); 255 } 256 257 closeEnv(); 258 } 259 260 263 private void openEnv(int floor, 264 int maxMem) 265 throws DatabaseException { 266 267 268 long evictBytes = maxMem - ((maxMem * floor) / 100); 269 270 271 EnvironmentConfig envConfig = TestUtils.initEnvConfig(); 272 envConfig.setAllowCreate(true); 273 envConfig.setTxnNoSync(Boolean.getBoolean(TestUtils.NO_SYNC)); 274 envConfig.setConfigParam(EnvironmentParams. 275 ENV_RUN_EVICTOR.getName(), "false"); 276 envConfig.setConfigParam(EnvironmentParams. 277 ENV_RUN_INCOMPRESSOR.getName(), "false"); 278 envConfig.setConfigParam(EnvironmentParams. 279 ENV_RUN_CLEANER.getName(), "false"); 280 envConfig.setConfigParam(EnvironmentParams. 281 ENV_RUN_CHECKPOINTER.getName(), "false"); 282 envConfig.setConfigParam(EnvironmentParams. 283 EVICTOR_EVICT_BYTES.getName(), 284 (new Long (evictBytes)).toString()); 285 envConfig.setConfigParam(EnvironmentParams. 286 MAX_MEMORY.getName(), 287 new Integer (maxMem).toString()); 288 289 envConfig.setConfigParam 290 (EnvironmentParams.CLEANER_TRACK_DETAIL.getName(), "false"); 291 envConfig.setConfigParam(EnvironmentParams.LOG_MEM_SIZE.getName(), 292 EnvironmentParams.LOG_MEM_SIZE_MIN_STRING); 293 envConfig.setConfigParam(EnvironmentParams.NUM_LOG_BUFFERS.getName(), 294 "2"); 295 296 300 envConfig.setConfigParam(EnvironmentParams. 301 EVICTOR_CRITICAL_PERCENTAGE.getName(), 302 "1000"); 303 304 305 envConfig.setConfigParam(EnvironmentParams. 306 NODE_MAX.getName(), "4"); 307 envConfig.setConfigParam(EnvironmentParams. 308 NODE_MAX_DUPTREE.getName(), "4"); 309 env = new Environment(envHome, envConfig); 310 311 312 DatabaseConfig dbConfig = new DatabaseConfig(); 313 dbConfig.setAllowCreate(true); 314 dbConfig.setSortedDuplicates(true); 315 db = env.openDatabase(null, "foo", dbConfig); 316 } 317 318 private void closeEnv() 319 throws DatabaseException { 320 321 db.close(); 322 db = null; 323 env.close(); 324 env = null; 325 } 326 327 private void insertData(int nKeys) 328 throws DatabaseException { 329 330 DatabaseEntry key = new DatabaseEntry(); 331 DatabaseEntry data = new DatabaseEntry(); 332 for (int i = 0; i < nKeys; i++) { 333 334 IntegerBinding.intToEntry(i, key); 335 336 if ((i % 5) == 0) { 337 for (int j = 10; j < (NUM_DUPS + 10); j++) { 338 IntegerBinding.intToEntry(j, data); 339 db.put(null, key, data); 340 } 341 } else { 342 IntegerBinding.intToEntry(i+1, data); 343 db.put(null, key, data); 344 } 345 } 346 } 347 348 private void verifyData(int nKeys) 349 throws DatabaseException { 350 351 352 Cursor cursor = db.openCursor(null, null); 353 DatabaseEntry data = new DatabaseEntry(); 354 DatabaseEntry key = new DatabaseEntry(); 355 356 for (int i = 0; i < nKeys; i++) { 357 if ((i % 5) ==0) { 358 for (int j = 10; j < (NUM_DUPS + 10); j++) { 359 assertEquals(OperationStatus.SUCCESS, 360 cursor.getNext(key, data, LockMode.DEFAULT)); 361 assertEquals(i, IntegerBinding.entryToInt(key)); 362 assertEquals(j, IntegerBinding.entryToInt(data)); 363 } 364 } else { 365 assertEquals(OperationStatus.SUCCESS, 366 cursor.getNext(key, data, LockMode.DEFAULT)); 367 assertEquals(i, IntegerBinding.entryToInt(key)); 368 assertEquals(i+1, IntegerBinding.entryToInt(data)); 369 } 370 } 371 372 assertEquals(OperationStatus.NOTFOUND, 373 cursor.getNext(key, data, LockMode.DEFAULT)); 374 cursor.close(); 375 } 376 377 private void evictAndCheck(boolean shouldEvict, int nKeys) 378 throws DatabaseException { 379 380 EnvironmentImpl envImpl = DbInternal.envGetEnvironmentImpl(env); 381 MemoryBudget mb = envImpl.getMemoryBudget(); 382 383 393 long preEvictMem = mb.getCacheMemoryUsage(); 394 TestUtils.validateNodeMemUsage(envImpl, true); 395 env.evictMemory(); 396 long postEvictMem = mb.getCacheMemoryUsage(); 397 398 TestUtils.validateNodeMemUsage(envImpl, true); 399 if (DEBUG) { 400 System.out.println("preEvict=" + preEvictMem + 401 " postEvict=" + postEvictMem); 402 } 403 404 if (shouldEvict) { 405 assertTrue("preEvict=" + preEvictMem + 406 " postEvict=" + postEvictMem + 407 " maxMem=" + mb.getMaxMemory(), 408 (preEvictMem > postEvictMem)); 409 } else { 410 assertTrue("preEvict=" + preEvictMem + 411 " postEvict=" + postEvictMem, 412 (preEvictMem == postEvictMem)); 413 } 414 415 verifyData(nKeys); 416 TestUtils.validateNodeMemUsage(envImpl, true); 417 } 418 } 419 | Popular Tags |