@Test public void timedOutUpdate() throws Exception { View ix = openIndex("foo"); byte[] key = "hello".getBytes(); byte[] value1 = "world".getBytes(); byte[] value2 = "world!!!".getBytes(); ix.store(null, key, value1); Transaction txn = mDb.newTransaction(); ix.store(txn, key, value2); fastAssertArrayEquals(value2, ix.load(Transaction.BOGUS, key)); try { ix.load(null, key); fail(); } catch (LockTimeoutException e) { } Transaction txn2 = mDb.newTransaction(); try { ix.load(txn2, key); fail(); } catch (LockTimeoutException e) { } txn2.lockMode(LockMode.UPGRADABLE_READ); try { ix.load(txn2, key); fail(); } catch (LockTimeoutException e) { } txn2.lockMode(LockMode.REPEATABLE_READ); try { ix.load(txn2, key); fail(); } catch (LockTimeoutException e) { } txn2.lockMode(LockMode.READ_COMMITTED); try { ix.load(txn2, key); fail(); } catch (LockTimeoutException e) { } txn2.lockMode(LockMode.READ_UNCOMMITTED); fastAssertArrayEquals(value2, ix.load(txn2, key)); txn2.lockMode(LockMode.UNSAFE); fastAssertArrayEquals(value2, ix.load(txn2, key)); txn.commit(); fastAssertArrayEquals(value2, ix.load(null, key)); }
@Test public void delayedUpdate() throws Exception { View ix = openIndex("foo"); byte[] key = "hello".getBytes(); byte[] value1 = "world".getBytes(); ix.store(null, key, value1); int i = 0; Updater u = start(ix, key, ("world-" + (i++)).getBytes()); fastAssertArrayEquals(u.mValue, ix.load(null, key)); u = start(ix, key, ("world-" + (i++)).getBytes()); Transaction txn2 = mDb.newTransaction(); fastAssertArrayEquals(u.mValue, ix.load(txn2, key)); txn2.reset(); u = start(ix, key, ("world-" + (i++)).getBytes()); txn2.lockMode(LockMode.UPGRADABLE_READ); fastAssertArrayEquals(u.mValue, ix.load(txn2, key)); txn2.reset(); u = start(ix, key, ("world-" + (i++)).getBytes()); txn2.lockMode(LockMode.REPEATABLE_READ); fastAssertArrayEquals(u.mValue, ix.load(txn2, key)); txn2.reset(); u = start(ix, key, ("world-" + (i++)).getBytes()); txn2.lockMode(LockMode.READ_COMMITTED); fastAssertArrayEquals(u.mValue, ix.load(txn2, key)); txn2.reset(); }
private void delayedDelete(boolean noGhost) throws Exception { View ix = openIndex("foo"); byte[] key = "hello".getBytes(); byte[] value1 = "world".getBytes(); ix.store(null, key, value1); Updater u = start(ix, key, null, noGhost); assertEquals(null, ix.load(null, key)); ix.store(null, key, value1); u = start(ix, key, null, noGhost); Transaction txn2 = mDb.newTransaction(); assertEquals(null, ix.load(txn2, key)); txn2.reset(); ix.store(null, key, value1); u = start(ix, key, null, noGhost); txn2.lockMode(LockMode.UPGRADABLE_READ); assertEquals(null, ix.load(txn2, key)); txn2.reset(); ix.store(null, key, value1); u = start(ix, key, null, noGhost); txn2.lockMode(LockMode.REPEATABLE_READ); assertEquals(null, ix.load(txn2, key)); txn2.reset(); ix.store(null, key, value1); u = start(ix, key, null, noGhost); txn2.lockMode(LockMode.READ_COMMITTED); assertEquals(null, ix.load(txn2, key)); txn2.reset(); }
@Test public void testEvictBase() throws IOException { int size = mSize; boolean autoLoad = mAutoLoad; Index ix = mDb.openIndex("test"); int initialRecordCount = 100_000 * (1024 / size); for (int i = 0; i < initialRecordCount; i++) { String key = textOfLength(i, 'k', size); String val = textOfLength(i, 'v', size); ix.store(null, key.getBytes(), val.getBytes()); } // basic eviction TestEvictionFilter evictionFilter = new TestEvictionFilter(); long evicted = ix.evict(null, null, null, evictionFilter, autoLoad); int recordCount = initialRecordCount - evictionFilter.mKeys.size(); long keyValueSize = 0; for (int i = 0; i < evictionFilter.mKeys.size(); ++i) { keyValueSize += evictionFilter.mKeys.get(i).length + evictionFilter.mValues.get(i).length; } assertEquals( evicted, autoLoad ? keyValueSize : keyValueSize * 2); // if autoload is not enabled, only keys are load assertEquals(recordCount, ix.count(null, null)); for (byte[] key : evictionFilter.mKeys) { assertNull(ix.load(null, key)); } assertTrue(evictionFilter.mKeys.size() >= 1); assertTrue(evictionFilter.mKeys.size() <= 1024 / size); // empty range evictionFilter = new TestEvictionFilter(); assertEquals(0, ix.evict(null, "a".getBytes(), "b".getBytes(), evictionFilter, autoLoad)); assertEquals(recordCount, ix.count(null, null)); assertEquals(0, evictionFilter.mKeys.size()); assertEquals(0, evictionFilter.mValues.size()); // evict nodes in a particular range evictionFilter = new TestEvictionFilter(); ix.newCursor(null).find("a".getBytes()); // loads rightmost nodes at all levels into cache assertEquals( size * 2, ix.evict(null, "009998".getBytes(), "009999".getBytes(), evictionFilter, autoLoad)); assertEquals(1, evictionFilter.mKeys.size()); assertEquals(1, evictionFilter.mValues.size()); assertTrue(new String(evictionFilter.mKeys.get(0)).startsWith("009998")); if (autoLoad) { assertTrue(new String(evictionFilter.mValues.get(0)).startsWith("009998")); } else { assertTrue(evictionFilter.mValues.get(0) == Cursor.NOT_LOADED); } assertEquals(--recordCount, ix.count(null, null)); // ghost records evictionFilter = new TestEvictionFilter(); Transaction txn = mDb.newTransaction(); int lowKey = initialRecordCount - 11; int highKey = initialRecordCount - 20; for (int i = lowKey; i <= highKey; i++) { String key = textOfLength(i, 'k', size); ix.delete(txn, key.getBytes()); } assertEquals( 0, ix.evict( null, String.valueOf(lowKey).getBytes(), String.valueOf(highKey).getBytes(), evictionFilter, autoLoad)); assertEquals(0, evictionFilter.mKeys.size()); assertEquals(0, evictionFilter.mValues.size()); txn.reset(); VerificationObserver observer = new VerificationObserver(); ix.verify(observer); assertFalse(observer.failed); }