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:05 UTC

[ignite-3] branch ignite-17923 created (now 376a57f671)

This is an automated email from the ASF dual-hosted git repository.

sdanilov pushed a change to branch ignite-17923
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


      at 376a57f671 IGNITE-17923 Remove PartitionStorage and its tests

This branch includes the following new commits:

     new 376a57f671 IGNITE-17923 Remove PartitionStorage and its tests

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[ignite-3] 01/01: IGNITE-17923 Remove PartitionStorage and its tests

Posted by sd...@apache.org.
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());
-        }
-    }
-}