You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sd...@apache.org on 2022/10/18 08:15:06 UTC
[ignite-3] 01/01: IGNITE-17923 Remove PartitionStorage and its tests
This is an automated email from the ASF dual-hosted git repository.
sdanilov pushed a commit to branch ignite-17923
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit 376a57f67106f1fa570e2e0001f475be9c97156d
Author: Semyon Danilov <sa...@yandex.ru>
AuthorDate: Tue Oct 18 12:14:55 2022 +0400
IGNITE-17923 Remove PartitionStorage and its tests
---
.../ignite/internal/storage/PartitionStorage.java | 162 -----
.../internal/storage/engine/TableStorage.java | 22 -
.../storage/AbstractPartitionStorageTest.java | 723 ---------------------
3 files changed, 907 deletions(-)
diff --git a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/PartitionStorage.java b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/PartitionStorage.java
deleted file mode 100644
index 783092b369..0000000000
--- a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/PartitionStorage.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.storage;
-
-import java.nio.file.Path;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.Predicate;
-import org.apache.ignite.internal.util.Cursor;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Interface providing methods to read, remove and update keys in storage. Any locking is unnecessary as this storage is used within RAFT
- * groups where all write operations are serialized.
- *
- * @deprecated Replaced with {@link MvPartitionStorage}.
- */
-@Deprecated
-public interface PartitionStorage extends AutoCloseable {
- /**
- * Returns the partition id.
- *
- * @return Partition id.
- */
- int partitionId();
-
- /**
- * Reads a DataRow for a given key.
- *
- * @param key Search row.
- * @return Data row or {@code null} if no data has been found.
- * @throws StorageException If failed to read the data or the storage is already stopped.
- */
- @Nullable
- DataRow read(SearchRow key) throws StorageException;
-
- /**
- * Reads {@link DataRow}s for a given collection of keys.
- *
- * @param keys Search rows.
- * @return Data rows.
- * @throws StorageException If failed to read the data or the storage is already stopped.
- */
- Collection<DataRow> readAll(List<? extends SearchRow> keys) throws StorageException;
-
- /**
- * Writes a DataRow into the storage.
- *
- * @param row Data row.
- * @throws StorageException If failed to write the data or the storage is already stopped.
- */
- void write(DataRow row) throws StorageException;
-
- /**
- * Writes a collection of {@link DataRow}s into the storage.
- *
- * @param rows Data rows.
- * @throws StorageException If failed to write the data or the storage is already stopped.
- */
- void writeAll(List<? extends DataRow> rows) throws StorageException;
-
- /**
- * Inserts a collection of {@link DataRow}s into the storage and returns a collection of rows that can't be inserted due to their keys
- * being already present in the storage.
- *
- * @param rows Data rows.
- * @return Collection of rows that could not be inserted.
- * @throws StorageException If failed to write the data or the storage is already stopped.
- */
- Collection<DataRow> insertAll(List<? extends DataRow> rows) throws StorageException;
-
- /**
- * Removes a DataRow associated with a given Key.
- *
- * @param key Search row.
- * @throws StorageException If failed to remove the data or the storage is already stopped.
- */
- void remove(SearchRow key) throws StorageException;
-
- /**
- * Removes {@link DataRow}s mapped by given keys.
- *
- * @param keys Search rows.
- * @return List of skipped data rows.
- * @throws StorageException If failed to remove the data or the storage is already stopped.
- */
- Collection<SearchRow> removeAll(List<? extends SearchRow> keys) throws StorageException;
-
- /**
- * Removes {@link DataRow}s mapped by given keys and containing given values.
- *
- * @param keyValues Data rows.
- * @return List of skipped data rows.
- * @throws StorageException If failed to remove the data or the storage is already stopped.
- */
- Collection<DataRow> removeAllExact(List<? extends DataRow> keyValues) throws StorageException;
-
- /**
- * Executes an update with custom logic implemented by storage.UpdateClosure interface.
- *
- * @param key Search key.
- * @param clo Invoke closure.
- * @param <T> Closure invocation's result type.
- * @throws StorageException If failed to read data or storage is already stopped.
- */
- @Nullable <T> T invoke(SearchRow key, InvokeClosure<T> clo) throws StorageException;
-
- /**
- * Creates cursor over the storage data.
- *
- * @param filter Filter for the scan query.
- * @return Cursor with filtered data.
- * @throws StorageException If failed to read data or storage is already stopped.
- */
- Cursor<DataRow> scan(Predicate<SearchRow> filter) throws StorageException;
-
- /**
- * Creates a snapshot of the storage's current state in the specified directory.
- *
- * @param snapshotPath Directory to store a snapshot.
- * @return Future representing pending completion of the operation.
- */
- CompletableFuture<Void> snapshot(Path snapshotPath);
-
- /**
- * Restores a state of the storage which was previously captured with a {@link #snapshot(Path)}.
- *
- * @param snapshotPath Path to the snapshot's directory.
- */
- void restoreSnapshot(Path snapshotPath);
-
- /**
- * Removes all data from this storage and frees all associated resources.
- *
- * @throws StorageException If failed to destroy the data or storage is already stopped.
- */
- void destroy() throws StorageException;
-
- /**
- * Returns rows count belongs to current storage.
- *
- * @return Rows count.
- * @throws StorageException If failed to obtain size.
- */
- long rowsCount();
-}
diff --git a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/TableStorage.java b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/TableStorage.java
index 84f041ead2..d31b3a23f8 100644
--- a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/TableStorage.java
+++ b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/TableStorage.java
@@ -18,9 +18,7 @@
package org.apache.ignite.internal.storage.engine;
import org.apache.ignite.internal.schema.configuration.TableConfiguration;
-import org.apache.ignite.internal.storage.PartitionStorage;
import org.apache.ignite.internal.storage.StorageException;
-import org.jetbrains.annotations.Nullable;
/**
* Table storage that contains meta, partitions and SQL indexes.
@@ -29,26 +27,6 @@ import org.jetbrains.annotations.Nullable;
*/
@Deprecated
public interface TableStorage {
- /**
- * Retrieves or creates a partition for the current table. Not expected to be called concurrently with the same partition id.
- *
- * @param partId Partition id.
- * @return Partition storage.
- * @throws IllegalArgumentException If partition id is out of bounds.
- * @throws StorageException If an error has occurred during the partition creation.
- */
- PartitionStorage getOrCreatePartition(int partId) throws StorageException;
-
- /**
- * Returns the partition storage or {@code null} if the requested storage doesn't exist.
- *
- * @param partId Partition id.
- * @return Partition storage or {@code null}.
- * @throws IllegalArgumentException If partition id is out of bounds.
- */
- @Nullable
- PartitionStorage getPartition(int partId);
-
/**
* Destroys a partition if it exists.
*
diff --git a/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/AbstractPartitionStorageTest.java b/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/AbstractPartitionStorageTest.java
deleted file mode 100644
index a97d3720e0..0000000000
--- a/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/AbstractPartitionStorageTest.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.storage;
-
-import static java.util.Collections.emptyList;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-import org.apache.ignite.internal.storage.basic.DeleteExactInvokeClosure;
-import org.apache.ignite.internal.storage.basic.GetAndRemoveInvokeClosure;
-import org.apache.ignite.internal.storage.basic.GetAndReplaceInvokeClosure;
-import org.apache.ignite.internal.storage.basic.InsertInvokeClosure;
-import org.apache.ignite.internal.storage.basic.ReplaceExactInvokeClosure;
-import org.apache.ignite.internal.storage.basic.SimpleDataRow;
-import org.apache.ignite.internal.storage.basic.SimpleReadInvokeClosure;
-import org.apache.ignite.internal.storage.basic.SimpleRemoveInvokeClosure;
-import org.apache.ignite.internal.storage.basic.SimpleWriteInvokeClosure;
-import org.apache.ignite.internal.testframework.WorkDirectory;
-import org.apache.ignite.internal.testframework.WorkDirectoryExtension;
-import org.apache.ignite.internal.util.Cursor;
-import org.jetbrains.annotations.NotNull;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-/**
- * Abstract test that covers basic scenarios of the storage API.
- */
-@ExtendWith(WorkDirectoryExtension.class)
-public abstract class AbstractPartitionStorageTest {
- /** Test key. */
- protected static final String KEY = "key";
-
- /** Test value. */
- protected static final String VALUE = "value";
-
- /** Storage instance. */
- protected PartitionStorage storage;
-
- /**
- * Tests that read / write / remove work consistently on the same key.
- */
- @Test
- public void readWriteRemove() {
- SearchRow searchRow = searchRow(KEY);
-
- assertNull(storage.read(searchRow));
-
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.write(dataRow);
-
- assertArrayEquals(dataRow.value().array(), storage.read(searchRow).value().array());
-
- storage.remove(searchRow);
-
- assertNull(storage.read(searchRow));
- }
-
- /**
- * Tests that invoke method works consistently with default read / write / remove closures implementations on the same key.
- */
- @Test
- public void invoke() {
- SearchRow searchRow = searchRow(KEY);
-
- SimpleReadInvokeClosure readClosure = new SimpleReadInvokeClosure();
-
- storage.invoke(searchRow, readClosure);
-
- assertNull(readClosure.row());
-
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.invoke(searchRow, new SimpleWriteInvokeClosure(dataRow));
-
- storage.invoke(searchRow, readClosure);
-
- assertArrayEquals(dataRow.value().array(), readClosure.row().value().array());
-
- storage.invoke(searchRow, new SimpleRemoveInvokeClosure());
-
- storage.invoke(searchRow, readClosure);
-
- assertNull(readClosure.row());
- }
-
- /**
- * Tests that scan operation works properly without filter.
- *
- * @throws Exception If failed.
- */
- @Test
- public void scanSimple() throws Exception {
- List<DataRow> list = toList(storage.scan(key -> true));
-
- assertEquals(emptyList(), list);
-
- DataRow dataRow1 = dataRow("key1", "value1");
-
- storage.write(dataRow1);
-
- assertEquals(1, storage.rowsCount());
-
- list = toList(storage.scan(key -> true));
-
- assertThat(list, hasSize(1));
-
- assertArrayEquals(dataRow1.value().array(), list.get(0).value().array());
-
- DataRow dataRow2 = dataRow("key2", "value2");
-
- storage.write(dataRow2);
-
- list = toList(storage.scan(key -> true));
-
- assertThat(list, hasSize(2));
-
- // "key1" and "key2" have the same order both by hash and lexicographically.
- assertArrayEquals(dataRow1.value().array(), list.get(0).value().array());
- assertArrayEquals(dataRow2.value().array(), list.get(1).value().array());
- }
-
- /**
- * Tests that scan operation works properly with passed filter.
- *
- * @throws Exception If failed.
- */
- @Test
- public void scanFiltered() throws Exception {
- DataRow dataRow1 = dataRow("key1", "value1");
- DataRow dataRow2 = dataRow("key2", "value2");
-
- storage.write(dataRow1);
- storage.write(dataRow2);
-
- List<DataRow> list = toList(storage.scan(key -> stringKey(key).charAt(3) == '1'));
-
- assertThat(list, hasSize(1));
-
- assertArrayEquals(dataRow1.value().array(), list.get(0).value().array());
-
- list = toList(storage.scan(key -> stringKey(key).charAt(3) == '2'));
-
- assertThat(list, hasSize(1));
-
- assertArrayEquals(dataRow2.value().array(), list.get(0).value().array());
-
- list = toList(storage.scan(key -> false));
-
- assertTrue(list.isEmpty());
- }
-
- /**
- * Tests that {@link InsertInvokeClosure} inserts a data row if there is no existing data row with the same key.
- */
- @Test
- public void testInsertClosure() {
- DataRow dataRow = dataRow(KEY, VALUE);
-
- var closure = new InsertInvokeClosure(dataRow);
-
- storage.invoke(dataRow, closure);
-
- assertTrue(closure.result());
-
- checkHasSameEntry(dataRow);
- }
-
- /**
- * Tests that {@link InsertInvokeClosure} doesn't insert a data row if there is an existing data row with the same key.
- */
- @Test
- public void testInsertClosure_failureBranch() {
- DataRow dataRow = dataRow(KEY, VALUE);
-
- var closure = new InsertInvokeClosure(dataRow);
-
- storage.invoke(dataRow, closure);
-
- assertTrue(closure.result());
-
- DataRow sameKeyRow = dataRow(KEY, "test");
-
- var sameClosure = new InsertInvokeClosure(sameKeyRow);
-
- storage.invoke(sameKeyRow, sameClosure);
-
- assertFalse(sameClosure.result());
-
- checkHasSameEntry(dataRow);
- }
-
- /**
- * Tests that {@link DeleteExactInvokeClosure} deletes a data row if a key and a value matches the ones passed in the closure.
- */
- @Test
- public void testDeleteExactClosure() {
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.write(dataRow);
-
- checkHasSameEntry(dataRow);
-
- var closure = new DeleteExactInvokeClosure(dataRow);
-
- storage.invoke(dataRow, closure);
-
- assertTrue(closure.result());
-
- assertNull(storage.read(dataRow));
- }
-
- /**
- * Tests that {@link DeleteExactInvokeClosure} doesn't delete a data row if a key and a value don't match the ones passed in the
- * closure.
- */
- @Test
- public void testDeleteExactClosure_failureBranch() {
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.write(dataRow);
-
- checkHasSameEntry(dataRow);
-
- var closure = new DeleteExactInvokeClosure(dataRow(KEY, "test"));
-
- storage.invoke(dataRow, closure);
-
- assertFalse(closure.result());
-
- checkHasSameEntry(dataRow);
- }
-
- /**
- * Tests that {@link GetAndRemoveInvokeClosure} successfully retrieves and removes a data row.
- */
- @Test
- public void testGetAndRemoveClosure() {
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.write(dataRow);
-
- checkHasSameEntry(dataRow);
-
- var closure = new GetAndRemoveInvokeClosure();
-
- storage.invoke(dataRow, closure);
-
- assertTrue(closure.result());
-
- checkRowsEqual(dataRow, closure.oldRow());
-
- assertNull(storage.read(dataRow));
- }
-
- /**
- * Tests that {@link GetAndRemoveInvokeClosure} doesn't retrieve and remove a data row if it doesn't exist.
- */
- @Test
- public void testGetAndRemoveClosure_failureBranch() {
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.write(dataRow);
-
- checkHasSameEntry(dataRow);
-
- var closure = new GetAndRemoveInvokeClosure();
-
- storage.invoke(searchRow("test"), closure);
-
- assertFalse(closure.result());
-
- assertNull(closure.oldRow());
-
- checkHasSameEntry(dataRow);
- }
-
- /**
- * Tests that {@link GetAndReplaceInvokeClosure} with the {@code GetAndReplaceInvokeClosure#onlyIfExists} set to {@code false} retrieves
- * and replaces the existing entry in the storage.
- */
- @Test
- public void testGetAndReplaceClosureIfExistsFalse_entryExists() {
- String newValue = "newValue";
-
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.write(dataRow);
-
- checkHasSameEntry(dataRow);
-
- DataRow newRow = dataRow(KEY, newValue);
-
- var closure = new GetAndReplaceInvokeClosure(newRow, false);
-
- storage.invoke(dataRow, closure);
-
- DataRow replaced = closure.oldRow();
-
- assertNotNull(replaced);
-
- assertTrue(closure.result());
-
- checkRowsEqual(dataRow, replaced);
-
- checkHasDifferentEntry(dataRow);
- checkHasSameEntry(newRow);
- }
-
- /**
- * Tests that {@link GetAndReplaceInvokeClosure} with the {@code GetAndReplaceInvokeClosure#onlyIfExists} set to {@code false}
- * successfully inserts a new data row and returns an empty row if a previous row with the same key doesn't exist .
- */
- @Test
- public void testGetAndReplaceClosureIfExistsFalse_entryNotExists() {
- DataRow dataRow = dataRow(KEY, VALUE);
-
- var closure = new GetAndReplaceInvokeClosure(dataRow, false);
-
- storage.invoke(dataRow, closure);
-
- DataRow replaced = closure.oldRow();
-
- assertTrue(closure.result());
-
- assertNull(replaced);
-
- checkHasSameEntry(dataRow);
- }
-
- /**
- * Tests that {@link GetAndReplaceInvokeClosure} with the {@code GetAndReplaceInvokeClosure#onlyIfExists} set to {@code true} retrieves
- * and replaces the existing entry in the storage.
- */
- @Test
- public void testGetAndReplaceClosureIfExistsTrue_entryExists() {
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.write(dataRow);
-
- checkHasSameEntry(dataRow);
-
- DataRow newRow = dataRow(KEY, "test");
-
- var closure = new GetAndReplaceInvokeClosure(newRow, true);
-
- storage.invoke(dataRow, closure);
-
- DataRow replaced = closure.oldRow();
-
- assertNotNull(replaced);
-
- assertTrue(closure.result());
-
- checkHasDifferentEntry(dataRow);
- checkHasSameEntry(newRow);
- }
-
- /**
- * Tests that {@link GetAndReplaceInvokeClosure} with the {@code GetAndReplaceInvokeClosure#onlyIfExists} set to {@code true} doesn't
- * insert a new entry if a previous one doesn't exist.
- */
- @Test
- public void testGetAndReplaceClosureIfExistsTrue_entryNotExists() {
- DataRow dataRow = dataRow(KEY, VALUE);
-
- var closure = new GetAndReplaceInvokeClosure(dataRow, true);
-
- storage.invoke(dataRow, closure);
-
- DataRow replaced = closure.oldRow();
-
- assertNull(replaced);
-
- assertFalse(closure.result());
-
- assertNull(storage.read(dataRow));
- }
-
- /**
- * Tests that {@link ReplaceExactInvokeClosure} replaces the data row with a given key and a given value in the storage.
- */
- @Test
- public void testReplaceExactClosure() {
- String newValue = "newValue";
-
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.write(dataRow);
-
- checkHasSameEntry(dataRow);
-
- DataRow newRow = dataRow(KEY, newValue);
-
- var closure = new ReplaceExactInvokeClosure(dataRow, newRow);
-
- storage.invoke(dataRow, closure);
-
- assertTrue(closure.result());
-
- checkHasDifferentEntry(dataRow);
- checkHasSameEntry(newRow);
- }
-
- /**
- * Tests that {@link ReplaceExactInvokeClosure} doesn't replace the data row with a given key and a given value if the value in the
- * storage doesn't match the value passed via the closure.
- */
- @Test
- public void testReplaceExactClosure_failureBranch() {
- String newValue = "newValue";
-
- DataRow dataRow = dataRow(KEY, VALUE);
-
- storage.write(dataRow);
-
- checkHasSameEntry(dataRow);
-
- DataRow newRow = dataRow(KEY, newValue);
-
- var closure = new ReplaceExactInvokeClosure(newRow, dataRow);
-
- storage.invoke(dataRow, closure);
-
- assertFalse(closure.result());
-
- checkHasSameEntry(dataRow);
- }
-
- /**
- * Tests the {@link PartitionStorage#readAll(List)} operation successfully reads data rows from the storage.
- */
- @Test
- public void testReadAll() {
- List<DataRow> rows = insertBulk(100);
-
- Collection<DataRow> readRows = storage.readAll(rows);
-
- assertThat(
- readRows.stream().map(DataRow::value).collect(Collectors.toList()),
- containsInAnyOrder(rows.stream().map(DataRow::value).toArray(ByteBuffer[]::new))
- );
- }
-
- /**
- * Tests that {@link PartitionStorage#writeAll(List)} operation successfully writes a collection of data rows into the storage.
- */
- @Test
- public void testWriteAll() {
- List<DataRow> rows = IntStream.range(0, 100)
- .mapToObj(i -> dataRow(KEY + i, VALUE + i))
- .collect(Collectors.toList());
-
- storage.writeAll(rows);
- rows.forEach(this::checkHasSameEntry);
- }
-
- /**
- * Tests that {@link PartitionStorage#insertAll(List)} operation doesn't insert data rows which keys are already present in the storage.
- * This operation must also return the list of such data rows.
- */
- @Test
- public void testInsertAll() {
- List<DataRow> rows = insertBulk(100);
-
- List<DataRow> oldRows = rows.subList(0, 50);
-
- List<DataRow> newInsertion = Stream.concat(
- oldRows.stream(),
- IntStream.range(100, 150).mapToObj(i -> dataRow(KEY + "_" + i, VALUE + "_" + i))
- ).collect(Collectors.toList());
-
- Collection<DataRow> cantInsert = storage.insertAll(newInsertion);
-
- assertEquals(oldRows, cantInsert);
- }
-
- /**
- * Tests that {@link PartitionStorage#removeAll(List)} operation successfully retrieves and removes a collection of {@link SearchRow}s.
- */
- @Test
- public void testRemoveAll() throws Exception {
- List<DataRow> rows = insertBulk(100);
-
- Collection<SearchRow> skipped = storage.removeAll(rows);
-
- assertEquals(0, skipped.size());
-
- Cursor<DataRow> scan = storage.scan(row -> true);
-
- assertFalse(scan.hasNext());
-
- scan.close();
- }
-
- @Test
- public void testRemoveAllKeyNotExists() {
- SearchRow row = searchRow(KEY);
- Collection<SearchRow> skipped = storage.removeAll(Collections.singletonList(row));
-
- assertNotNull(skipped);
-
- assertEquals(1, skipped.size());
- assertEquals(row, skipped.iterator().next());
- }
-
- /**
- * Tests that {@link PartitionStorage#removeAllExact(List)} operation successfully removes and retrieves a collection of data rows with
- * the given exact keys and values from the storage.
- */
- @Test
- public void testRemoveAllExact() throws Exception {
- List<DataRow> rows = insertBulk(100);
-
- Collection<DataRow> skipped = storage.removeAllExact(rows);
-
- assertEquals(0, skipped.size());
-
- Cursor<DataRow> scan = storage.scan(row -> true);
-
- assertFalse(scan.hasNext());
-
- scan.close();
- }
-
- /**
- * Tests that {@link PartitionStorage#removeAllExact(List)} operation doesn't remove and retrieve a collection of data rows with the
- * given exact keys and values from the storage if the value in the storage doesn't match the given value.
- */
- @Test
- public void testRemoveAllExact_failureBranch() {
- List<DataRow> rows = insertBulk(100);
-
- List<DataRow> notExactRows = IntStream.range(0, 100)
- .mapToObj(i -> dataRow(KEY + i, VALUE + (i + 1)))
- .collect(Collectors.toList());
-
- Collection<DataRow> skipped = storage.removeAllExact(notExactRows);
-
- assertEquals(notExactRows, skipped);
-
- rows.forEach(this::checkHasSameEntry);
- }
-
- /**
- * Tests that {@link PartitionStorage#snapshot(Path)} and {@link PartitionStorage#restoreSnapshot(Path)} operations work properly
- * in basic scenario of creating snapshot and restoring it on the clear db.
- *
- * @param workDir Directory to store snapshot file.
- * @throws Exception If failed to take snapshot.
- */
- @Test
- public void testSnapshot(@WorkDirectory Path workDir) throws Exception {
- List<DataRow> rows = insertBulk(10);
-
- Path snapshotDir = workDir.resolve("snapshot");
-
- Files.createDirectories(snapshotDir);
-
- storage.snapshot(snapshotDir).get(1, TimeUnit.SECONDS);
-
- storage.removeAll(rows);
-
- storage.restoreSnapshot(snapshotDir);
-
- rows.forEach(this::checkHasSameEntry);
- }
-
- /**
- * Inserts and returns a given amount of data rows with {@link #KEY}_i as a key and {@link #VALUE}_i as a value where i is an index of
- * the data row.
- *
- * @param numberOfEntries Amount of entries to insert.
- * @return List of inserted rows.
- */
- private List<DataRow> insertBulk(int numberOfEntries) {
- List<DataRow> rows = IntStream.range(0, numberOfEntries)
- .mapToObj(i -> dataRow(KEY + "_" + i, VALUE + "_" + i))
- .collect(Collectors.toList());
-
- storage.insertAll(rows);
- rows.forEach(this::checkHasSameEntry);
-
- // Clone key and value byte arrays so that returned rows have new references.
- // This way we check that the ConcurrentHashMapStorage performs an actual array comparison.
- return rows.stream().map(row -> {
- byte[] valueBytes = row.valueBytes();
-
- assert valueBytes != null;
-
- return new SimpleDataRow(row.keyBytes().clone(), valueBytes.clone());
- }).collect(Collectors.toList());
- }
-
- /**
- * Checks that the storage contains a row with a given key but with a different value.
- *
- * @param row Data row.
- */
- private void checkHasDifferentEntry(DataRow row) {
- DataRow read = storage.read(row);
-
- assertNotNull(read);
- assertFalse(Arrays.equals(row.valueBytes(), read.valueBytes()));
- }
-
- /**
- * Checks that the storage contains a specific data row.
- *
- * @param row Expected data row.
- */
- protected void checkHasSameEntry(DataRow row) {
- DataRow read = storage.read(row);
-
- assertNotNull(read);
- checkRowsEqual(row, read);
- }
-
- /**
- * Checks that two rows are equal.
- *
- * @param expected Expected data row.
- * @param actual Actual data row.
- */
- private static void checkRowsEqual(DataRow expected, DataRow actual) {
- assertArrayEquals(expected.keyBytes(), actual.keyBytes());
- assertArrayEquals(expected.valueBytes(), actual.valueBytes());
- }
-
- /**
- * Wraps string key into a search row.
- *
- * @param key String key.
- * @return Search row.
- */
- protected SearchRow searchRow(String key) {
- return new SearchRow() {
- @Override
- public byte[] keyBytes() {
- return key.getBytes(StandardCharsets.UTF_8);
- }
-
- @Override
- public ByteBuffer key() {
- return ByteBuffer.wrap(keyBytes());
- }
- };
- }
-
- /**
- * Get key as a string.
- *
- * @param searchRow Search row.
- * @return String key.
- */
- protected String stringKey(SearchRow searchRow) {
- return new String(searchRow.keyBytes(), StandardCharsets.UTF_8);
- }
-
- /**
- * Wraps string key/value pair into a data row.
- *
- * @param key String key.
- * @param value String value.
- * @return Data row.
- */
- protected DataRow dataRow(String key, String value) {
- return new SimpleDataRow(
- key.getBytes(StandardCharsets.UTF_8),
- value.getBytes(StandardCharsets.UTF_8)
- );
- }
-
- /**
- * Converts cursor to list.
- *
- * @param cursor Cursor.
- * @param <T> Type of cursor content.
- * @return List.
- * @throws Exception If error occurred during iteration or while closing the cursor.
- */
- @NotNull
- private static <T> List<T> toList(Cursor<T> cursor) throws Exception {
- try (cursor) {
- return StreamSupport.stream(cursor.spliterator(), false).collect(Collectors.toList());
- }
- }
-}