You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sa...@apache.org on 2022/06/10 15:47:09 UTC
[ignite-3] branch main updated: IGNITE-17036 KeyValueStorage get exact revision fixed (#875)
This is an automated email from the ASF dual-hosted git repository.
sanpwc pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new a1aa7fd4e IGNITE-17036 KeyValueStorage get exact revision fixed (#875)
a1aa7fd4e is described below
commit a1aa7fd4e2398c72827777ec5417d67915ff4da3
Author: Alexander Lapin <la...@gmail.com>
AuthorDate: Fri Jun 10 18:47:04 2022 +0300
IGNITE-17036 KeyValueStorage get exact revision fixed (#875)
---
.../metastorage/server/KeyValueStorage.java | 6 +-
.../server/persistence/RocksDbKeyValueStorage.java | 28 ++++---
.../server/persistence/WatchCursor.java | 2 +-
.../server/AbstractKeyValueStorageTest.java | 88 ++++++++++++++++++++++
.../server/SimpleInMemoryKeyValueStorage.java | 27 ++++---
5 files changed, 118 insertions(+), 33 deletions(-)
diff --git a/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/KeyValueStorage.java b/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/KeyValueStorage.java
index dbc8c073e..56d6e33f4 100644
--- a/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/KeyValueStorage.java
+++ b/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/KeyValueStorage.java
@@ -57,13 +57,13 @@ public interface KeyValueStorage extends AutoCloseable {
@NotNull Entry get(byte[] key);
/**
- * Returns an entry by the given key and revision.
+ * Returns an entry by the given key and bounded by the given revision.
*
* @param key The key.
- * @param rev The revision.
+ * @param revUpperBound The upper bound of revision.
* @return Value corresponding to the given key.
*/
- @NotNull Entry get(byte[] key, long rev);
+ @NotNull Entry get(byte[] key, long revUpperBound);
/**
* Returns all entries corresponding to given keys.
diff --git a/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/persistence/RocksDbKeyValueStorage.java b/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/persistence/RocksDbKeyValueStorage.java
index 29f6638de..33ed663da 100644
--- a/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/persistence/RocksDbKeyValueStorage.java
+++ b/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/persistence/RocksDbKeyValueStorage.java
@@ -417,7 +417,7 @@ public class RocksDbKeyValueStorage implements KeyValueStorage {
rwLock.readLock().lock();
try {
- return doGet(key, LATEST_REV, false);
+ return doGet(key, LATEST_REV);
} finally {
rwLock.readLock().unlock();
}
@@ -426,11 +426,11 @@ public class RocksDbKeyValueStorage implements KeyValueStorage {
/** {@inheritDoc} */
@NotNull
@Override
- public Entry get(byte[] key, long rev) {
+ public Entry get(byte[] key, long revUpperBound) {
rwLock.readLock().lock();
try {
- return doGet(key, rev, true);
+ return doGet(key, revUpperBound);
} finally {
rwLock.readLock().unlock();
}
@@ -478,7 +478,7 @@ public class RocksDbKeyValueStorage implements KeyValueStorage {
rwLock.writeLock().lock();
try {
- Entry e = doGet(key, LATEST_REV, false);
+ Entry e = doGet(key, LATEST_REV);
if (e.empty() || e.tombstone()) {
return e;
@@ -538,7 +538,7 @@ public class RocksDbKeyValueStorage implements KeyValueStorage {
List<byte[]> vals = new ArrayList<>(keys.size());
for (byte[] key : keys) {
- Entry e = doGet(key, LATEST_REV, false);
+ Entry e = doGet(key, LATEST_REV);
res.add(e);
@@ -759,7 +759,7 @@ public class RocksDbKeyValueStorage implements KeyValueStorage {
* @throws RocksDBException If failed.
*/
private boolean addToBatchForRemoval(WriteBatch batch, byte[] key, long curRev, long counter) throws RocksDBException {
- Entry e = doGet(key, LATEST_REV, false);
+ Entry e = doGet(key, LATEST_REV);
if (e.empty() || e.tombstone()) {
return false;
@@ -817,7 +817,7 @@ public class RocksDbKeyValueStorage implements KeyValueStorage {
try {
for (byte[] key : keys) {
- res.add(doGet(key, rev, false));
+ res.add(doGet(key, rev));
}
} finally {
rwLock.readLock().unlock();
@@ -829,15 +829,13 @@ public class RocksDbKeyValueStorage implements KeyValueStorage {
/**
* Gets the value by key and revision.
*
- * @param key Target key.
- * @param rev Target revision.
- * @param exactRev {@code true} if searching for exact revision, {@code false} if rev is an upper bound (inclusive).
+ * @param key Target key.
+ * @param revUpperBound Target upper bound of revision.
* @return Value.
*/
@NotNull
- Entry doGet(byte[] key, long rev, boolean exactRev) {
- assert rev == LATEST_REV && !exactRev || rev > LATEST_REV :
- "Invalid arguments: [rev=" + rev + ", exactRev=" + exactRev + ']';
+ Entry doGet(byte[] key, long revUpperBound) {
+ assert revUpperBound >= LATEST_REV : "Invalid arguments: [revUpperBound=" + revUpperBound + ']';
long[] revs;
try {
@@ -852,10 +850,10 @@ public class RocksDbKeyValueStorage implements KeyValueStorage {
long lastRev;
- if (rev == LATEST_REV) {
+ if (revUpperBound == LATEST_REV) {
lastRev = lastRevision(revs);
} else {
- lastRev = exactRev ? rev : maxRevision(revs, rev);
+ lastRev = maxRevision(revs, revUpperBound);
}
// lastRev can be -1 if maxRevision return -1.
diff --git a/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/persistence/WatchCursor.java b/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/persistence/WatchCursor.java
index cbb675bb5..c3dabd4aa 100644
--- a/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/persistence/WatchCursor.java
+++ b/modules/metastorage-server/src/main/java/org/apache/ignite/internal/metastorage/server/persistence/WatchCursor.java
@@ -158,7 +158,7 @@ class WatchCursor implements Cursor<WatchEvent> {
newEntry = new Entry(key, val.bytes(), revision, val.updateCounter());
}
- Entry oldEntry = storage.doGet(key, revision - 1, false);
+ Entry oldEntry = storage.doGet(key, revision - 1);
evts.add(new EntryEvent(oldEntry, newEntry));
}
diff --git a/modules/metastorage-server/src/test/java/org/apache/ignite/internal/metastorage/server/AbstractKeyValueStorageTest.java b/modules/metastorage-server/src/test/java/org/apache/ignite/internal/metastorage/server/AbstractKeyValueStorageTest.java
index 2af752ecd..77b983ce7 100644
--- a/modules/metastorage-server/src/test/java/org/apache/ignite/internal/metastorage/server/AbstractKeyValueStorageTest.java
+++ b/modules/metastorage-server/src/test/java/org/apache/ignite/internal/metastorage/server/AbstractKeyValueStorageTest.java
@@ -106,6 +106,94 @@ public abstract class AbstractKeyValueStorageTest {
assertEquals(2, e.updateCounter());
}
+ @Test
+ void getWithRevisionBound() {
+ byte[] key1 = key(1);
+ byte[] val1 = keyValue(1, 1);
+
+ final byte[] key2 = key(2);
+ final byte[] val2_1 = keyValue(2, 21);
+ final byte[] val2_2 = keyValue(2, 22);
+
+ final byte[] key3 = key(3);
+ final byte[] val3 = keyValue(3, 3);
+
+ final byte[] key4 = key(4);
+
+ assertEquals(0, storage.revision());
+ assertEquals(0, storage.updateCounter());
+
+ // Regular put.
+ storage.put(key1, val1);
+
+ // Rewrite.
+ storage.put(key2, val2_1);
+ storage.put(key2, val2_2);
+
+ // Remove.
+ storage.put(key3, val3);
+ storage.remove(key3);
+
+ assertEquals(5, storage.revision());
+ assertEquals(5, storage.updateCounter());
+
+ // Bounded by revision 2.
+ Entry key1EntryBounded2 = storage.get(key1, 2);
+
+ assertNotNull(key1EntryBounded2);
+ assertEquals(1, key1EntryBounded2.revision());
+ assertEquals(1, key1EntryBounded2.updateCounter());
+ assertArrayEquals(val1, key1EntryBounded2.value());
+ assertFalse(key1EntryBounded2.tombstone());
+ assertFalse(key1EntryBounded2.empty());
+
+ Entry key2EntryBounded2 = storage.get(key2, 2);
+
+ assertNotNull(key2EntryBounded2);
+ assertEquals(2, key2EntryBounded2.revision());
+ assertEquals(2, key2EntryBounded2.updateCounter());
+ assertArrayEquals(val2_1, key2EntryBounded2.value());
+ assertFalse(key2EntryBounded2.tombstone());
+ assertFalse(key2EntryBounded2.empty());
+
+ Entry key3EntryBounded2 = storage.get(key3, 2);
+
+ assertNotNull(key3EntryBounded2);
+ assertEquals(0, key3EntryBounded2.revision());
+ assertEquals(0, key3EntryBounded2.updateCounter());
+ assertNull(key3EntryBounded2.value());
+ assertFalse(key3EntryBounded2.tombstone());
+ assertTrue(key3EntryBounded2.empty());
+
+ // Bounded by revision 5.
+ Entry key1EntryBounded5 = storage.get(key1, 5);
+
+ assertNotNull(key1EntryBounded5);
+ assertEquals(1, key1EntryBounded5.revision());
+ assertEquals(1, key1EntryBounded5.updateCounter());
+ assertArrayEquals(val1, key1EntryBounded5.value());
+ assertFalse(key1EntryBounded5.tombstone());
+ assertFalse(key1EntryBounded5.empty());
+
+ Entry key2EntryBounded5 = storage.get(key2, 5);
+
+ assertNotNull(key2EntryBounded5);
+ assertEquals(3, key2EntryBounded5.revision());
+ assertEquals(3, key2EntryBounded5.updateCounter());
+ assertArrayEquals(val2_2, key2EntryBounded5.value());
+ assertFalse(key2EntryBounded5.tombstone());
+ assertFalse(key2EntryBounded5.empty());
+
+ Entry key3EntryBounded5 = storage.get(key3, 5);
+
+ assertNotNull(key3EntryBounded5);
+ assertEquals(5, key3EntryBounded5.revision());
+ assertEquals(5, key3EntryBounded5.updateCounter());
+ assertTrue(key3EntryBounded5.tombstone());
+ assertNull(key3EntryBounded5.value());
+ assertFalse(key3EntryBounded5.empty());
+ }
+
@Test
void getAll() {
byte[] key1 = key(1);
diff --git a/modules/metastorage-server/src/test/java/org/apache/ignite/internal/metastorage/server/SimpleInMemoryKeyValueStorage.java b/modules/metastorage-server/src/test/java/org/apache/ignite/internal/metastorage/server/SimpleInMemoryKeyValueStorage.java
index fa550a775..ffea7e0e5 100644
--- a/modules/metastorage-server/src/test/java/org/apache/ignite/internal/metastorage/server/SimpleInMemoryKeyValueStorage.java
+++ b/modules/metastorage-server/src/test/java/org/apache/ignite/internal/metastorage/server/SimpleInMemoryKeyValueStorage.java
@@ -146,16 +146,16 @@ public class SimpleInMemoryKeyValueStorage implements KeyValueStorage {
@Override
public Entry get(byte[] key) {
synchronized (mux) {
- return doGet(key, LATEST_REV, false);
+ return doGet(key, LATEST_REV);
}
}
/** {@inheritDoc} */
@NotNull
@Override
- public Entry get(byte[] key, long rev) {
+ public Entry get(byte[] key, long revUpperBound) {
synchronized (mux) {
- return doGet(key, rev, true);
+ return doGet(key, revUpperBound);
}
}
@@ -190,7 +190,7 @@ public class SimpleInMemoryKeyValueStorage implements KeyValueStorage {
@Override
public Entry getAndRemove(byte[] key) {
synchronized (mux) {
- Entry e = doGet(key, LATEST_REV, false);
+ Entry e = doGet(key, LATEST_REV);
if (e.empty() || e.tombstone()) {
return e;
@@ -211,7 +211,7 @@ public class SimpleInMemoryKeyValueStorage implements KeyValueStorage {
List<byte[]> vals = new ArrayList<>(keys.size());
for (byte[] key : keys) {
- Entry e = doGet(key, LATEST_REV, false);
+ Entry e = doGet(key, LATEST_REV);
if (e.empty() || e.tombstone()) {
continue;
@@ -240,7 +240,7 @@ public class SimpleInMemoryKeyValueStorage implements KeyValueStorage {
List<byte[]> vals = new ArrayList<>(keys.size());
for (byte[] key : keys) {
- Entry e = doGet(key, LATEST_REV, false);
+ Entry e = doGet(key, LATEST_REV);
res.add(e);
@@ -434,7 +434,7 @@ public class SimpleInMemoryKeyValueStorage implements KeyValueStorage {
}
private boolean doRemove(byte[] key, long curRev) {
- Entry e = doGet(key, LATEST_REV, false);
+ Entry e = doGet(key, LATEST_REV);
if (e.empty() || e.tombstone()) {
return false;
@@ -479,7 +479,7 @@ public class SimpleInMemoryKeyValueStorage implements KeyValueStorage {
synchronized (mux) {
for (byte[] key : keys) {
- res.add(doGet(key, rev, false));
+ res.add(doGet(key, rev));
}
}
@@ -487,9 +487,8 @@ public class SimpleInMemoryKeyValueStorage implements KeyValueStorage {
}
@NotNull
- private Entry doGet(byte[] key, long rev, boolean exactRev) {
- assert rev == LATEST_REV && !exactRev || rev > LATEST_REV :
- "Invalid arguments: [rev=" + rev + ", exactRev=" + exactRev + ']';
+ private Entry doGet(byte[] key, long revUpperBound) {
+ assert revUpperBound >= LATEST_REV : "Invalid arguments: [revUpperBound=" + revUpperBound + ']';
List<Long> revs = keysIdx.get(key);
@@ -499,10 +498,10 @@ public class SimpleInMemoryKeyValueStorage implements KeyValueStorage {
long lastRev;
- if (rev == LATEST_REV) {
+ if (revUpperBound == LATEST_REV) {
lastRev = lastRevision(revs);
} else {
- lastRev = exactRev ? rev : maxRevision(revs, rev);
+ lastRev = maxRevision(revs, revUpperBound);
}
// lastRev can be -1 if maxRevision return -1.
@@ -853,7 +852,7 @@ public class SimpleInMemoryKeyValueStorage implements KeyValueStorage {
newEntry = new Entry(key, val.bytes(), nextRetRev, val.updateCounter());
}
- Entry oldEntry = doGet(key, nextRetRev - 1, false);
+ Entry oldEntry = doGet(key, nextRetRev - 1);
evts.add(new EntryEvent(oldEntry, newEntry));
}