static RuntimeException lockCleanup(Throwable e, Transaction txn, LockResult result) { if (result.isAcquired()) { try { txn.unlock(); } catch (Throwable e2) { Utils.suppress(e, e2); } } throw Utils.rethrow(e); }
/** * @param tkey mKey must have been set to this non-null key already */ private LockResult transformCurrent(LockResult result, final byte[] tkey) throws IOException { final Cursor c = mSource; if (c.value() == null) { // Retain the position and lock when value doesn't exist. mValue = null; return result; } byte[] tvalue = mTransformer.transformValue(c, tkey); mValue = tvalue; if (tvalue == null && result == LockResult.ACQUIRED) { // Release the lock when filtered out, but maintain the cursor position. c.link().unlock(); result = LockResult.UNOWNED; } return result; }
private boolean condUpdate(final Transaction txn, final byte[] key, final byte[] oldValue, final byte[] newValue) throws IOException { Cursor c = mSource.newCursor(txn); LockResult result = c.find(key); if (!Arrays.equals(c.value(), oldValue)) { c.reset(); if (result == LockResult.ACQUIRED) { txn.unlock(); } return false; } c.store(newValue); c.reset(); return true; }
/** * Skip implementation which locks every key it sees, releasing all but the last one. * * @throws IllegalArgumentException when skip amount is zero */ static LockResult skipWithLocks(Cursor c, long amount) throws IOException { if (amount == 0) { return c.skip(amount); } if (amount > 0) while (true) { LockResult result = c.next(); if (c.key() == null || --amount <= 0) { return result; } if (result == LockResult.ACQUIRED) { c.link().unlock(); } } else while (true) { LockResult result = c.previous(); if (c.key() == null || ++amount >= 0) { return result; } if (result == LockResult.ACQUIRED) { c.link().unlock(); } } }
/** * Skip implementation which locks every key it sees, releasing all but the last one. * * @throws IllegalArgumentException when skip amount is zero */ static LockResult skipWithLocks(Cursor c, long amount) throws IOException { if (amount == 0) { return c.skip(amount); } if (amount > 0) while (true) { LockResult result = c.next(); if (c.key() == null || --amount <= 0) { return result; } if (result == LockResult.ACQUIRED) { c.link().unlock(); } } else while (true) { LockResult result = c.previous(); if (c.key() == null || ++amount >= 0) { return result; } if (result == LockResult.ACQUIRED) { c.link().unlock(); } } }
private boolean condUpdate(final Transaction txn, final byte[] key, final byte[] oldValue, final byte[] newValue) throws IOException { Cursor c = mSource.newCursor(txn); LockResult result = c.find(key); if (!Arrays.equals(c.value(), oldValue)) { c.reset(); if (result == LockResult.ACQUIRED) { txn.unlock(); } return false; } c.store(newValue); c.reset(); return true; }
/** * Skip implementation which locks every key it sees, releasing all but the last one. * * @throws IllegalArgumentException when skip amount is zero */ static LockResult skipWithLocks(Cursor c, long amount) throws IOException { if (amount == 0) { return c.skip(amount); } if (amount > 0) while (true) { LockResult result = c.next(); if (c.key() == null || --amount <= 0) { return result; } if (result == LockResult.ACQUIRED) { c.link().unlock(); } } else while (true) { LockResult result = c.previous(); if (c.key() == null || ++amount >= 0) { return result; } if (result == LockResult.ACQUIRED) { c.link().unlock(); } } }
/** * Moves the Cursor to find the first available entry less than or equal to * the given key. * * <p>Ownership of the key instance transfers to the Cursor, and it must * not be modified after calling this method. * * @return {@link LockResult#UNOWNED UNOWNED}, {@link LockResult#ACQUIRED * ACQUIRED}, {@link LockResult#OWNED_SHARED OWNED_SHARED}, {@link * LockResult#OWNED_UPGRADABLE OWNED_UPGRADABLE}, or {@link * LockResult#OWNED_EXCLUSIVE OWNED_EXCLUSIVE} * @throws NullPointerException if key is null */ public default LockResult findLe(byte[] key) throws IOException { LockResult result = find(key); if (value() == null) { if (result == LockResult.ACQUIRED) { link().unlock(); } result = previous(); } return result; }
/** * Moves the Cursor to find the first available entry greater than or equal * to the given key. * * <p>Ownership of the key instance transfers to the Cursor, and it must * not be modified after calling this method. * * @return {@link LockResult#UNOWNED UNOWNED}, {@link LockResult#ACQUIRED * ACQUIRED}, {@link LockResult#OWNED_SHARED OWNED_SHARED}, {@link * LockResult#OWNED_UPGRADABLE OWNED_UPGRADABLE}, or {@link * LockResult#OWNED_EXCLUSIVE OWNED_EXCLUSIVE} * @throws NullPointerException if key is null */ public default LockResult findGe(byte[] key) throws IOException { LockResult result = find(key); if (value() == null) { if (result == LockResult.ACQUIRED) { link().unlock(); } result = next(); } return result; }
/** * Moves the Cursor to find the first available entry less than or equal to * the given key. * * <p>Ownership of the key instance transfers to the Cursor, and it must * not be modified after calling this method. * * @return {@link LockResult#UNOWNED UNOWNED}, {@link LockResult#ACQUIRED * ACQUIRED}, {@link LockResult#OWNED_SHARED OWNED_SHARED}, {@link * LockResult#OWNED_UPGRADABLE OWNED_UPGRADABLE}, or {@link * LockResult#OWNED_EXCLUSIVE OWNED_EXCLUSIVE} * @throws NullPointerException if key is null */ public default LockResult findLe(byte[] key) throws IOException { LockResult result = find(key); if (value() == null) { if (result == LockResult.ACQUIRED) { link().unlock(); } result = previous(); } return result; }
/** * Optimized version of the regular findLe method, which can perform fewer search steps if * the given key is in close proximity to the current one. Even if not in close proximity, * the find outcome is identical, although it may perform more slowly. * * <p>Ownership of the key instance transfers to the Cursor, and it must * not be modified after calling this method. * * @return {@link LockResult#UNOWNED UNOWNED}, {@link LockResult#ACQUIRED * ACQUIRED}, {@link LockResult#OWNED_SHARED OWNED_SHARED}, {@link * LockResult#OWNED_UPGRADABLE OWNED_UPGRADABLE}, or {@link * LockResult#OWNED_EXCLUSIVE OWNED_EXCLUSIVE} * @throws NullPointerException if key is null */ public default LockResult findNearbyLe(byte[] key) throws IOException { LockResult result = findNearby(key); if (value() == null) { if (result == LockResult.ACQUIRED) { link().unlock(); } result = previous(); } return result; }
/** * Moves the Cursor to find the first available entry greater than or equal * to the given key. * * <p>Ownership of the key instance transfers to the Cursor, and it must * not be modified after calling this method. * * @return {@link LockResult#UNOWNED UNOWNED}, {@link LockResult#ACQUIRED * ACQUIRED}, {@link LockResult#OWNED_SHARED OWNED_SHARED}, {@link * LockResult#OWNED_UPGRADABLE OWNED_UPGRADABLE}, or {@link * LockResult#OWNED_EXCLUSIVE OWNED_EXCLUSIVE} * @throws NullPointerException if key is null */ public default LockResult findGe(byte[] key) throws IOException { LockResult result = find(key); if (value() == null) { if (result == LockResult.ACQUIRED) { link().unlock(); } result = next(); } return result; }
/** * Moves the Cursor to find the first available entry less than or equal to * the given key. * * <p>Ownership of the key instance transfers to the Cursor, and it must * not be modified after calling this method. * * @return {@link LockResult#UNOWNED UNOWNED}, {@link LockResult#ACQUIRED * ACQUIRED}, {@link LockResult#OWNED_SHARED OWNED_SHARED}, {@link * LockResult#OWNED_UPGRADABLE OWNED_UPGRADABLE}, or {@link * LockResult#OWNED_EXCLUSIVE OWNED_EXCLUSIVE} * @throws NullPointerException if key is null */ public default LockResult findLe(byte[] key) throws IOException { LockResult result = find(key); if (value() == null) { if (result == LockResult.ACQUIRED) { link().unlock(); } result = previous(); } return result; }
/** * Moves the Cursor to find the first available entry greater than or equal * to the given key. * * <p>Ownership of the key instance transfers to the Cursor, and it must * not be modified after calling this method. * * @return {@link LockResult#UNOWNED UNOWNED}, {@link LockResult#ACQUIRED * ACQUIRED}, {@link LockResult#OWNED_SHARED OWNED_SHARED}, {@link * LockResult#OWNED_UPGRADABLE OWNED_UPGRADABLE}, or {@link * LockResult#OWNED_EXCLUSIVE OWNED_EXCLUSIVE} * @throws NullPointerException if key is null */ public default LockResult findGe(byte[] key) throws IOException { LockResult result = find(key); if (value() == null) { if (result == LockResult.ACQUIRED) { link().unlock(); } result = next(); } return result; }
/** * Optimized version of the regular findGe method, which can perform fewer search steps if * the given key is in close proximity to the current one. Even if not in close proximity, * the find outcome is identical, although it may perform more slowly. * * <p>Ownership of the key instance transfers to the Cursor, and it must * not be modified after calling this method. * * @return {@link LockResult#UNOWNED UNOWNED}, {@link LockResult#ACQUIRED * ACQUIRED}, {@link LockResult#OWNED_SHARED OWNED_SHARED}, {@link * LockResult#OWNED_UPGRADABLE OWNED_UPGRADABLE}, or {@link * LockResult#OWNED_EXCLUSIVE OWNED_EXCLUSIVE} * @throws NullPointerException if key is null */ public default LockResult findNearbyGe(byte[] key) throws IOException { LockResult result = findNearby(key); if (value() == null) { if (result == LockResult.ACQUIRED) { link().unlock(); } result = next(); } return result; }
/** * Called by select method when the second value must be selected and the corresponding * first value doesn't exist. This cursor's key and value are set as a side effect. * * @return null if cursor must be moved before select can be called again */ protected LockResult selectSecond(Transaction txn, byte[] key) throws IOException { mKey = key; mValue = Cursor.NOT_LOADED; mSecond.link(txn); try { LockResult r1 = mView.mFirst.touch(txn, key); LockResult r2 = autoload() ? mSecond.load() : mSecond.lock(); byte[] value = mSecond.value(); mValue = value; if (value == null) { if (r1.isAcquired()) { txn.unlock(); } if (r2.isAcquired()) { txn.unlock(); } return null; } return resultCombine(txn, r1, r2); } finally { mSecond.link(Transaction.BOGUS); } }
private boolean condStore(final Transaction txn, final byte[] key, final byte[] value, final byte[] failConditionValue) throws IOException { Cursor c = mSource.newCursor(txn); c.autoload(false); LockResult result = c.find(key); if (c.value() == failConditionValue) { c.reset(); if (result == LockResult.ACQUIRED) { txn.unlock(); } return false; } c.store(value); c.reset(); return true; }
private boolean condStore(final Transaction txn, final byte[] key, final byte[] value, final byte[] failConditionValue) throws IOException { Cursor c = mSource.newCursor(txn); c.autoload(false); LockResult result = c.find(key); if (c.value() == failConditionValue) { c.reset(); if (result == LockResult.ACQUIRED) { txn.unlock(); } return false; } c.store(value); c.reset(); return true; }
/** * @param tkey mKey must have been set to this non-null key already */ private LockResult transformCurrent(LockResult result, final byte[] key, final byte[] tkey) throws IOException { final Cursor c = mSource; final byte[] value = c.value(); if (value == null) { // Retain the position and lock when value doesn't exist. mValue = null; return result; } byte[] tvalue; if (value != NOT_LOADED || !mTransformer.requireValue()) { tvalue = mTransformer.transformValue(value, key, tkey); } else { // Disabling autoload mode makes little sense when using a value transformer, // because the value must be loaded anyhow. c.load(); tvalue = mTransformer.transformValue(c.value(), key, tkey); } mValue = tvalue; if (tvalue == null && result == LockResult.ACQUIRED) { // Release the lock when filtered out, but maintain the cursor position. c.link().unlock(); result = LockResult.UNOWNED; } return result; }
/** * @param tkey mKey must have been set to this non-null key already */ private LockResult transformCurrent(LockResult result, final byte[] key, final byte[] tkey) throws IOException { final Cursor c = mSource; final byte[] value = c.value(); if (value == null) { // Retain the position and lock when value doesn't exist. mValue = null; return result; } byte[] tvalue; if (value != NOT_LOADED || !mTransformer.requireValue()) { tvalue = mTransformer.transformValue(value, key, tkey); } else { // Disabling autoload mode makes little sense when using a value transformer, // because the value must be loaded anyhow. c.load(); tvalue = mTransformer.transformValue(c.value(), key, tkey); } mValue = tvalue; if (tvalue == null && result == LockResult.ACQUIRED) { // Release the lock when filtered out, but maintain the cursor position. c.link().unlock(); result = LockResult.UNOWNED; } return result; }