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 cccb376830 IGNITE-22567 Add `containsAll` to `RecordView` and
`KeyValueView` (#4018)
cccb376830 is described below
commit cccb376830d4b3cc7456e5f7b0e0ab18c14c3d4e
Author: Mikhail Efremov <[email protected]>
AuthorDate: Thu Jul 4 15:31:15 2024 +0600
IGNITE-22567 Add `containsAll` to `RecordView` and `KeyValueView` (#4018)
---
.../java/org/apache/ignite/table/KeyValueView.java | 23 ++++-
.../java/org/apache/ignite/table/RecordView.java | 23 ++++-
.../ignite/internal/client/proto/ClientOp.java | 3 +
.../handler/ClientInboundMessageHandler.java | 4 +
.../table/ClientTupleContainsAllKeysRequest.java | 61 +++++++++++
.../apache/ignite/client/ClientOperationType.java | 5 +
.../org/apache/ignite/client/IgniteClient.java | 2 +-
.../org/apache/ignite/client/RetryReadPolicy.java | 1 +
.../apache/ignite/internal/client/ClientUtils.java | 73 +------------
.../ignite/internal/client/TcpClientChannel.java | 3 +-
.../ignite/internal/client/TcpIgniteClient.java | 2 +-
.../internal/client/compute/ClientCompute.java | 4 +-
.../internal/client/table/AbstractClientView.java | 2 +-
.../client/table/ClientKeyValueBinaryView.java | 27 ++++-
.../internal/client/table/ClientKeyValueView.java | 27 ++++-
.../client/table/ClientRecordBinaryView.java | 27 ++++-
.../internal/client/table/ClientRecordView.java | 27 ++++-
.../ignite/internal/client/table/ClientTables.java | 2 +-
.../internal/client/tx/ClientTransaction.java | 2 +-
.../internal/client/tx/ClientTransactions.java | 2 +-
.../apache/ignite/client/ClientApiArchTest.java | 5 +-
.../client/ClientKeyValueBinaryViewTest.java | 28 +++++
.../ignite/client/ClientKeyValueViewTest.java | 29 ++++++
.../apache/ignite/client/ClientRecordViewTest.java | 41 ++++++++
.../org/apache/ignite/client/ClientTableTest.java | 53 ++++++++++
.../ignite/internal/client/ClientUtilsTest.java | 3 +-
.../org/apache/ignite/internal/util/ViewUtils.java | 115 +++++++++++++++++++++
.../sql/engine/ItPkOnlyTableCrossApiTest.java | 2 +-
.../ignite/internal/table/AbstractTableView.java | 24 +----
.../internal/table/KeyValueBinaryViewImpl.java | 39 +++++--
.../ignite/internal/table/KeyValueViewImpl.java | 41 ++++++--
.../table/PublicApiThreadingKeyValueView.java | 10 ++
.../table/PublicApiThreadingRecordView.java | 10 ++
.../internal/table/RecordBinaryViewImpl.java | 33 ++++++
.../ignite/internal/table/RecordViewImpl.java | 33 ++++++
.../table/KeyValueBinaryViewOperationsTest.java | 40 +++++++
.../internal/table/KeyValueViewOperationsTest.java | 34 ++++++
.../table/RecordBinaryViewOperationsTest.java | 45 ++++++++
.../internal/table/RecordViewOperationsTest.java | 37 +++++++
39 files changed, 814 insertions(+), 128 deletions(-)
diff --git
a/modules/api/src/main/java/org/apache/ignite/table/KeyValueView.java
b/modules/api/src/main/java/org/apache/ignite/table/KeyValueView.java
index 76a9e7b929..c3940e2752 100644
--- a/modules/api/src/main/java/org/apache/ignite/table/KeyValueView.java
+++ b/modules/api/src/main/java/org/apache/ignite/table/KeyValueView.java
@@ -142,7 +142,7 @@ public interface KeyValueView<K, V> extends
DataStreamerTarget<Entry<K, V>>, Cri
*
* @param tx Transaction or {@code null} to auto-commit.
* @param key Key whose presence is to be verified. The key cannot be
{@code null}.
- * @return {@code True} if a value exists for the specified key, {@code
false} otherwise.
+ * @return {@code True} if a value exists for every specified key, {@code
false} otherwise.
* @throws MarshallerException if the key doesn't match the schema.
*/
boolean contains(@Nullable Transaction tx, K key);
@@ -157,6 +157,27 @@ public interface KeyValueView<K, V> extends
DataStreamerTarget<Entry<K, V>>, Cri
*/
CompletableFuture<Boolean> containsAsync(@Nullable Transaction tx, K key);
+ /**
+ * Determines whether a table contains entries for all given keys.
+ *
+ * @param tx Transaction or {@code null} to auto-commit.
+ * @param keys Keys whose presence is to be verified. The collection and
it's values cannot be {@code null}.
+ * @return {@code True} if a value exists for every specified key, {@code
false} otherwise.
+ * @throws MarshallerException if the key doesn't match the schema.
+ */
+ boolean containsAll(@Nullable Transaction tx, Collection<K> keys);
+
+ /**
+ * Determines whether a table contains entries for all given keys.
+ *
+ * @param tx Transaction or {@code null} to auto-commit.
+ * @param keys Keys whose presence is to be verified. The collection and
it's values cannot be {@code null}.
+ * @return Future that represents the pending completion of the operation.
The result of the future will be {@code true} if a value
+ * exists for every specified key, {@code false} otherwise.
+ * @throws MarshallerException if the key doesn't match the schema.
+ */
+ CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction tx,
Collection<K> keys);
+
/**
* Puts into a table a value associated with the given key.
*
diff --git a/modules/api/src/main/java/org/apache/ignite/table/RecordView.java
b/modules/api/src/main/java/org/apache/ignite/table/RecordView.java
index cbe91746ea..846e846393 100644
--- a/modules/api/src/main/java/org/apache/ignite/table/RecordView.java
+++ b/modules/api/src/main/java/org/apache/ignite/table/RecordView.java
@@ -77,7 +77,7 @@ public interface RecordView<R> extends DataStreamerTarget<R>,
CriteriaQuerySourc
*
* @param tx Transaction or {@code null} to auto-commit.
* @param keyRec A record with key columns set. The key cannot be {@code
null}.
- * @return {@code True} if a value exists for the specified key, {@code
false} otherwise.
+ * @return {@code True} if a value exists for every specified key, {@code
false} otherwise.
* @throws MarshallerException if the key doesn't match the schema.
*/
boolean contains(@Nullable Transaction tx, R keyRec);
@@ -92,6 +92,27 @@ public interface RecordView<R> extends
DataStreamerTarget<R>, CriteriaQuerySourc
*/
CompletableFuture<Boolean> containsAsync(@Nullable Transaction tx, R
keyRec);
+ /**
+ * Determines whether a table contains entries for all given keys.
+ *
+ * @param tx Transaction or {@code null} to auto-commit.
+ * @param keys Keys whose presence is to be verified. The collection and
it's values cannot be {@code null}.
+ * @return {@code True} if a value exists for every specified key, {@code
false} otherwise.
+ * @throws MarshallerException if the key doesn't match the schema.
+ */
+ boolean containsAll(@Nullable Transaction tx, Collection<R> keys);
+
+ /**
+ * Determines whether a table contains entries for all given keys.
+ *
+ * @param tx Transaction or {@code null} to auto-commit.
+ * @param keys Keys whose presence is to be verified. The collection and
it's values cannot be {@code null}.
+ * @return Future that represents the pending completion of the operation.
The result of the future will be {@code true} if a value
+ * exists for every specified key, {@code false} otherwise.
+ * @throws MarshallerException if the key doesn't match the schema.
+ */
+ CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction tx,
Collection<R> keys);
+
/**
* Inserts a record into a table, if it does not exist, or replaces an
existing one.
*
diff --git
a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientOp.java
b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientOp.java
index 45706d23a7..f48959a018 100644
---
a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientOp.java
+++
b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientOp.java
@@ -176,4 +176,7 @@ public class ClientOp {
/** Send streamer batch with receiver. */
public static final int STREAMER_WITH_RECEIVER_BATCH_SEND = 66;
+
+ /** Check if all tuples with the given keys collection exist. */
+ public static final int TUPLE_CONTAINS_ALL_KEYS = 67;
}
diff --git
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
index a1f40a502f..8a58f478fa 100644
---
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
+++
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
@@ -74,6 +74,7 @@ import
org.apache.ignite.client.handler.requests.table.ClientStreamerWithReceive
import org.apache.ignite.client.handler.requests.table.ClientTableGetRequest;
import
org.apache.ignite.client.handler.requests.table.ClientTablePartitionPrimaryReplicasGetRequest;
import org.apache.ignite.client.handler.requests.table.ClientTablesGetRequest;
+import
org.apache.ignite.client.handler.requests.table.ClientTupleContainsAllKeysRequest;
import
org.apache.ignite.client.handler.requests.table.ClientTupleContainsKeyRequest;
import
org.apache.ignite.client.handler.requests.table.ClientTupleDeleteAllExactRequest;
import
org.apache.ignite.client.handler.requests.table.ClientTupleDeleteAllRequest;
@@ -692,6 +693,9 @@ public class ClientInboundMessageHandler extends
ChannelInboundHandlerAdapter im
case ClientOp.TUPLE_CONTAINS_KEY:
return ClientTupleContainsKeyRequest.process(in, out,
igniteTables, resources);
+ case ClientOp.TUPLE_CONTAINS_ALL_KEYS:
+ return ClientTupleContainsAllKeysRequest.process(in, out,
igniteTables, resources);
+
case ClientOp.JDBC_CONNECT:
return ClientJdbcConnectRequest.execute(in, out,
jdbcQueryEventHandler);
diff --git
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTupleContainsAllKeysRequest.java
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTupleContainsAllKeysRequest.java
new file mode 100644
index 0000000000..3e10a3fd0b
--- /dev/null
+++
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTupleContainsAllKeysRequest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.client.handler.requests.table;
+
+import static
org.apache.ignite.client.handler.requests.table.ClientTableCommon.readTableAsync;
+import static
org.apache.ignite.client.handler.requests.table.ClientTableCommon.readTuples;
+import static
org.apache.ignite.client.handler.requests.table.ClientTableCommon.readTx;
+
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.client.handler.ClientResourceRegistry;
+import org.apache.ignite.internal.client.proto.ClientMessagePacker;
+import org.apache.ignite.internal.client.proto.ClientMessageUnpacker;
+import org.apache.ignite.table.IgniteTables;
+
+/**
+ * Client tuple contains all keys request.
+ */
+public class ClientTupleContainsAllKeysRequest {
+ /**
+ * Processes the request.
+ *
+ * @param in Unpacker.
+ * @param out Packer.
+ * @param tables Ignite tables.
+ * @param resources Resource registry.
+ * @return Future.
+ */
+ public static CompletableFuture<Void> process(
+ ClientMessageUnpacker in,
+ ClientMessagePacker out,
+ IgniteTables tables,
+ ClientResourceRegistry resources
+ ) {
+ return readTableAsync(in, tables).thenCompose(table -> {
+ var tx = readTx(in, out, resources);
+ return readTuples(in, table, true).thenCompose(keyTuples -> table
+ .recordView()
+ .containsAllAsync(tx, keyTuples)
+ .thenAccept(containsAll -> {
+
out.packInt(table.schemaView().lastKnownSchemaVersion());
+ out.packBoolean(containsAll);
+ })
+ );
+ });
+ }
+}
diff --git
a/modules/client/src/main/java/org/apache/ignite/client/ClientOperationType.java
b/modules/client/src/main/java/org/apache/ignite/client/ClientOperationType.java
index a5b37d8fe0..b8c97c8dda 100644
---
a/modules/client/src/main/java/org/apache/ignite/client/ClientOperationType.java
+++
b/modules/client/src/main/java/org/apache/ignite/client/ClientOperationType.java
@@ -129,6 +129,11 @@ public enum ClientOperationType {
*/
TUPLE_CONTAINS_KEY,
+ /**
+ * Contains All Keys ({@link
org.apache.ignite.table.KeyValueView#containsAll(Transaction, Collection)}).
+ */
+ TUPLE_CONTAINS_ALL_KEYS,
+
/**
* Compute Execute ({@link
org.apache.ignite.compute.IgniteCompute#submit(JobTarget, JobDescriptor,
Object)}).
*/
diff --git
a/modules/client/src/main/java/org/apache/ignite/client/IgniteClient.java
b/modules/client/src/main/java/org/apache/ignite/client/IgniteClient.java
index 75eb23d893..7b3e84c260 100644
--- a/modules/client/src/main/java/org/apache/ignite/client/IgniteClient.java
+++ b/modules/client/src/main/java/org/apache/ignite/client/IgniteClient.java
@@ -24,7 +24,7 @@ import static
org.apache.ignite.client.IgniteClientConfiguration.DFLT_OPERATION_
import static
org.apache.ignite.client.IgniteClientConfiguration.DFLT_RECONNECT_INTERVAL;
import static
org.apache.ignite.client.IgniteClientConfiguration.DFLT_RECONNECT_THROTTLING_PERIOD;
import static
org.apache.ignite.client.IgniteClientConfiguration.DFLT_RECONNECT_THROTTLING_RETRIES;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.List;
import java.util.Objects;
diff --git
a/modules/client/src/main/java/org/apache/ignite/client/RetryReadPolicy.java
b/modules/client/src/main/java/org/apache/ignite/client/RetryReadPolicy.java
index e5af02e18e..15f0a6540a 100644
--- a/modules/client/src/main/java/org/apache/ignite/client/RetryReadPolicy.java
+++ b/modules/client/src/main/java/org/apache/ignite/client/RetryReadPolicy.java
@@ -31,6 +31,7 @@ public class RetryReadPolicy extends RetryLimitPolicy {
switch (context.operation()) {
case TABLES_GET:
case TUPLE_CONTAINS_KEY:
+ case TUPLE_CONTAINS_ALL_KEYS:
case TUPLE_GET_ALL:
case TUPLE_GET:
case TABLE_GET:
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/ClientUtils.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/ClientUtils.java
index ff886ef002..ea48fd6346 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/ClientUtils.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/ClientUtils.java
@@ -17,87 +17,17 @@
package org.apache.ignite.internal.client;
-import static org.apache.ignite.lang.ErrorGroups.Common.INTERNAL_ERR;
-
-import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
import org.apache.ignite.client.ClientOperationType;
import org.apache.ignite.client.IgniteClientConfiguration;
import org.apache.ignite.internal.client.proto.ClientOp;
-import org.apache.ignite.internal.lang.IgniteExceptionMapperUtil;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.logger.Loggers;
-import org.apache.ignite.internal.util.ExceptionUtils;
-import org.apache.ignite.lang.IgniteCheckedException;
-import org.apache.ignite.lang.IgniteException;
import org.apache.ignite.lang.LoggerFactory;
-import org.apache.ignite.lang.TraceableException;
/**
* Client utilities.
*/
public class ClientUtils {
- /**
- * Wraps an exception in an IgniteException, extracting trace identifier
and error code when the specified exception or one of its
- * causes is an IgniteException itself.
- *
- * @param e Internal exception.
- * @return Public exception.
- */
- public static Throwable ensurePublicException(Throwable e) {
- Objects.requireNonNull(e);
-
- e = ExceptionUtils.unwrapCause(e);
-
- if (e instanceof IgniteException) {
- return copyExceptionWithCauseIfPossible((IgniteException) e);
- }
-
- if (e instanceof IgniteCheckedException) {
- return copyExceptionWithCauseIfPossible((IgniteCheckedException)
e);
- }
-
- e = IgniteExceptionMapperUtil.mapToPublicException(e);
-
- return new IgniteException(INTERNAL_ERR, e.getMessage(), e);
- }
-
- /**
- * Try to copy exception using ExceptionUtils.copyExceptionWithCause and
return new exception if it was not possible.
- *
- * @param e Exception.
- * @return Properly copied exception or a new error, if exception can not
be copied.
- */
- private static <T extends Throwable & TraceableException> Throwable
copyExceptionWithCauseIfPossible(T e) {
- Throwable copy = ExceptionUtils.copyExceptionWithCause(e.getClass(),
e.traceId(), e.code(), e.getMessage(), e);
- if (copy != null) {
- return copy;
- }
-
- return new IgniteException(INTERNAL_ERR, "Public Ignite
exception-derived class does not have required constructor: "
- + e.getClass().getName(), e);
- }
-
- /**
- * Waits for async operation completion.
- *
- * @param fut Future to wait to.
- * @param <T> Future result type.
- * @return Future result.
- */
- public static <T> T sync(CompletableFuture<T> fut) {
- try {
- return fut.get();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt(); // Restore interrupt flag.
-
- throw ExceptionUtils.sneakyThrow(ensurePublicException(e));
- } catch (ExecutionException e) {
- throw ExceptionUtils.sneakyThrow(ensurePublicException(e));
- }
- }
-
/**
* Converts internal op code to public {@link ClientOperationType}.
*
@@ -170,6 +100,9 @@ public class ClientUtils {
case ClientOp.TUPLE_CONTAINS_KEY:
return ClientOperationType.TUPLE_CONTAINS_KEY;
+ case ClientOp.TUPLE_CONTAINS_ALL_KEYS:
+ return ClientOperationType.TUPLE_CONTAINS_ALL_KEYS;
+
case ClientOp.JDBC_CONNECT:
return null;
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
index 30e4faf85a..252505e5f4 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
@@ -54,6 +54,7 @@ import
org.apache.ignite.internal.client.proto.ProtocolVersion;
import org.apache.ignite.internal.client.proto.ResponseFlags;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.tostring.S;
+import org.apache.ignite.internal.util.ViewUtils;
import org.apache.ignite.lang.ErrorGroups.Table;
import org.apache.ignite.lang.IgniteException;
import org.apache.ignite.network.NetworkAddress;
@@ -361,7 +362,7 @@ class TcpClientChannel implements ClientChannel,
ClientMessageHandler, ClientCon
metrics.requestsActiveDecrement();
- throw sneakyThrow(ClientUtils.ensurePublicException(t));
+ throw sneakyThrow(ViewUtils.ensurePublicException(t));
}
}
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
index 6088023ecd..7a7f508820 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
@@ -17,7 +17,7 @@
package org.apache.ignite.internal.client;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.ArrayList;
import java.util.Collection;
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
index f3a9aab616..061f078861 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
@@ -44,7 +44,6 @@ import org.apache.ignite.compute.JobExecutionOptions;
import org.apache.ignite.compute.JobTarget;
import org.apache.ignite.compute.task.TaskExecution;
import org.apache.ignite.deployment.DeploymentUnit;
-import org.apache.ignite.internal.client.ClientUtils;
import org.apache.ignite.internal.client.PayloadInputChannel;
import org.apache.ignite.internal.client.PayloadOutputChannel;
import org.apache.ignite.internal.client.ReliableChannel;
@@ -59,6 +58,7 @@ import
org.apache.ignite.internal.client.table.ClientTupleSerializer;
import org.apache.ignite.internal.client.table.PartitionAwarenessProvider;
import org.apache.ignite.internal.sql.SqlCommon;
import org.apache.ignite.internal.util.ExceptionUtils;
+import org.apache.ignite.internal.util.ViewUtils;
import org.apache.ignite.lang.IgniteException;
import org.apache.ignite.lang.TableNotFoundException;
import org.apache.ignite.marshaling.Marshaler;
@@ -471,7 +471,7 @@ public class ClientCompute implements IgniteCompute {
try {
return future.join();
} catch (CompletionException e) {
- throw
ExceptionUtils.sneakyThrow(ClientUtils.ensurePublicException(e));
+ throw
ExceptionUtils.sneakyThrow(ViewUtils.ensurePublicException(e));
}
}
}
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/AbstractClientView.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/AbstractClientView.java
index b0553f4aa1..e5722e21c5 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/AbstractClientView.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/AbstractClientView.java
@@ -18,9 +18,9 @@
package org.apache.ignite.internal.client.table;
import static java.util.stream.Collectors.toSet;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
import static
org.apache.ignite.internal.table.criteria.CriteriaExceptionMapperUtil.mapToPublicCriteriaException;
import static org.apache.ignite.internal.util.ExceptionUtils.unwrapCause;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import static org.apache.ignite.lang.util.IgniteNameUtils.parseSimpleName;
import java.util.Arrays;
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueBinaryView.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueBinaryView.java
index cf83698a5e..2a6c84c248 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueBinaryView.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueBinaryView.java
@@ -17,10 +17,12 @@
package org.apache.ignite.internal.client.table;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
import static
org.apache.ignite.internal.util.CompletableFutures.emptyCollectionCompletedFuture;
import static
org.apache.ignite.internal.util.CompletableFutures.emptyMapCompletedFuture;
import static
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
+import static
org.apache.ignite.internal.util.CompletableFutures.trueCompletedFuture;
+import static org.apache.ignite.internal.util.ViewUtils.checkKeysForNulls;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.Collection;
import java.util.Collections;
@@ -174,6 +176,29 @@ public class ClientKeyValueBinaryView extends
AbstractClientView<Entry<Tuple, Tu
tx);
}
+ /** {@inheritDoc} */
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<Tuple>
keys) {
+ return sync(containsAllAsync(tx, keys));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<Tuple> keys) {
+ checkKeysForNulls(keys);
+
+ if (keys.isEmpty()) {
+ return trueCompletedFuture();
+ }
+
+ return tbl.doSchemaOutOpAsync(
+ ClientOp.TUPLE_CONTAINS_ALL_KEYS,
+ (s, w) -> ser.writeTuples(tx, keys, s, w, true),
+ r -> r.in().unpackBoolean(),
+ ClientTupleSerializer.getPartitionAwarenessProvider(tx,
keys.iterator().next()),
+ tx);
+ }
+
/** {@inheritDoc} */
@Override
public void put(@Nullable Transaction tx, Tuple key, @Nullable Tuple val) {
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueView.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueView.java
index fc82797b57..231e76b457 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueView.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueView.java
@@ -17,7 +17,6 @@
package org.apache.ignite.internal.client.table;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
import static org.apache.ignite.internal.client.table.ClientTable.writeTx;
import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
import static
org.apache.ignite.internal.marshaller.ValidationUtils.validateNullableOperation;
@@ -25,6 +24,9 @@ import static
org.apache.ignite.internal.marshaller.ValidationUtils.validateNull
import static
org.apache.ignite.internal.util.CompletableFutures.emptyCollectionCompletedFuture;
import static
org.apache.ignite.internal.util.CompletableFutures.emptyMapCompletedFuture;
import static
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
+import static
org.apache.ignite.internal.util.CompletableFutures.trueCompletedFuture;
+import static org.apache.ignite.internal.util.ViewUtils.checkKeysForNulls;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.BitSet;
import java.util.Collection;
@@ -213,6 +215,29 @@ public class ClientKeyValueView<K, V> extends
AbstractClientView<Entry<K, V>> im
tx);
}
+ /** {@inheritDoc} */
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<K> keys) {
+ return sync(containsAllAsync(tx, keys));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<K> keys) {
+ checkKeysForNulls(keys);
+
+ if (keys.isEmpty()) {
+ return trueCompletedFuture();
+ }
+
+ return tbl.doSchemaOutOpAsync(
+ ClientOp.TUPLE_CONTAINS_ALL_KEYS,
+ (s, w) -> keySer.writeRecs(tx, keys, s, w, TuplePart.KEY),
+ r -> r.in().unpackBoolean(),
+ ClientTupleSerializer.getPartitionAwarenessProvider(tx,
keySer.mapper(), keys.iterator().next()),
+ tx);
+ }
+
/** {@inheritDoc} */
@Override
public void put(@Nullable Transaction tx, K key, V val) {
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordBinaryView.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordBinaryView.java
index 4c91b7ffeb..f8ebe6412e 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordBinaryView.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordBinaryView.java
@@ -17,9 +17,11 @@
package org.apache.ignite.internal.client.table;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
import static
org.apache.ignite.internal.util.CompletableFutures.emptyListCompletedFuture;
import static
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
+import static
org.apache.ignite.internal.util.CompletableFutures.trueCompletedFuture;
+import static org.apache.ignite.internal.util.ViewUtils.checkKeysForNulls;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.Collection;
import java.util.Collections;
@@ -122,6 +124,29 @@ public class ClientRecordBinaryView extends
AbstractClientView<Tuple> implements
tx);
}
+ /** {@inheritDoc} */
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<Tuple>
keys) {
+ return sync(containsAllAsync(tx, keys));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<Tuple> keys) {
+ checkKeysForNulls(keys);
+
+ if (keys.isEmpty()) {
+ return trueCompletedFuture();
+ }
+
+ return tbl.doSchemaOutOpAsync(
+ ClientOp.TUPLE_CONTAINS_ALL_KEYS,
+ (s, w) -> ser.writeTuples(tx, keys, s, w, true),
+ r -> r.in().unpackBoolean(),
+ ClientTupleSerializer.getPartitionAwarenessProvider(tx,
keys.iterator().next()),
+ tx);
+ }
+
/** {@inheritDoc} */
@Override
public void upsert(@Nullable Transaction tx, Tuple rec) {
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordView.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordView.java
index 7b58792401..3e726d820d 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordView.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordView.java
@@ -17,9 +17,11 @@
package org.apache.ignite.internal.client.table;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
import static
org.apache.ignite.internal.util.CompletableFutures.emptyListCompletedFuture;
import static
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
+import static
org.apache.ignite.internal.util.CompletableFutures.trueCompletedFuture;
+import static org.apache.ignite.internal.util.ViewUtils.checkKeysForNulls;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.Collection;
import java.util.Collections;
@@ -129,6 +131,29 @@ public class ClientRecordView<R> extends
AbstractClientView<R> implements Record
tx);
}
+ /** {@inheritDoc} */
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<R> keys) {
+ return sync(containsAllAsync(tx, keys));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<R> keys) {
+ checkKeysForNulls(keys);
+
+ if (keys.isEmpty()) {
+ return trueCompletedFuture();
+ }
+
+ return tbl.doSchemaOutOpAsync(
+ ClientOp.TUPLE_CONTAINS_ALL_KEYS,
+ (s, w) -> ser.writeRecs(tx, keys, s, w, TuplePart.KEY),
+ r -> r.in().unpackBoolean(),
+ ClientTupleSerializer.getPartitionAwarenessProvider(tx,
ser.mapper(), keys.iterator().next()),
+ tx);
+ }
+
/** {@inheritDoc} */
@Override
public void upsert(@Nullable Transaction tx, R rec) {
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
index 08704a2d57..ba9d44adf7 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
@@ -17,7 +17,7 @@
package org.apache.ignite.internal.client.table;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.ArrayList;
import java.util.List;
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransaction.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransaction.java
index 8f8492b048..ade1e53aff 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransaction.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransaction.java
@@ -17,8 +17,8 @@
package org.apache.ignite.internal.client.tx;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import static org.apache.ignite.lang.ErrorGroups.Common.INTERNAL_ERR;
import static
org.apache.ignite.lang.ErrorGroups.Transactions.TX_ALREADY_FINISHED_ERR;
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransactions.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransactions.java
index fd5fb93f44..325ed680a7 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransactions.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransactions.java
@@ -17,7 +17,7 @@
package org.apache.ignite.internal.client.tx;
-import static org.apache.ignite.internal.client.ClientUtils.sync;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.concurrent.CompletableFuture;
import org.apache.ignite.internal.client.PayloadInputChannel;
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientApiArchTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientApiArchTest.java
index 5bb1186089..ee56557008 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/ClientApiArchTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/ClientApiArchTest.java
@@ -60,8 +60,9 @@ public class ClientApiArchTest {
f,
"internal.client.IgniteClientConfigurationImpl;",
"internal.client.TcpIgniteClient;",
- "internal.client.ClientUtils.sync;",
- "internal.client.SslConfigurationBuilder;");
+ "internal.client.SslConfigurationBuilder;",
+ "internal.util.ViewUtils.sync;"
+ );
});
}
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueBinaryViewTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueBinaryViewTest.java
index 70384fdd32..fcc31af18e 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueBinaryViewTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueBinaryViewTest.java
@@ -182,6 +182,34 @@ public class ClientKeyValueBinaryViewTest extends
AbstractClientTableTest {
assertThat(Arrays.asList(ex.getStackTrace()),
anyOf(hasToString(containsString("ClientKeyValueBinaryView"))));
}
+ @Test
+ public void testContainsAll() {
+ KeyValueView<Tuple, Tuple> kvView = defaultTable().keyValueView();
+
+ Tuple firstKeyTuple = tupleKey(101L);
+ Tuple secondKeyTuple = tupleKey(102L);
+ Tuple thirdKeyTuple = tupleKey(103L);
+
+ Map<Tuple, Tuple> kvs = Map.of(
+ firstKeyTuple, tupleVal("201"),
+ secondKeyTuple, tupleVal("202"),
+ thirdKeyTuple, tupleVal("203")
+ );
+
+ kvView.putAll(null, kvs);
+
+ assertThrows(NullPointerException.class, () ->
kvView.containsAll(null, null));
+ assertThrows(NullPointerException.class, () ->
kvView.containsAll(null, List.of(firstKeyTuple, null, thirdKeyTuple)));
+
+ assertTrue(kvView.containsAll(null, List.of()));
+ assertTrue(kvView.containsAll(null, List.of(firstKeyTuple)));
+ assertTrue(kvView.containsAll(null, List.of(firstKeyTuple,
secondKeyTuple, thirdKeyTuple)));
+
+ Tuple zeroKeyTuple = tupleKey(0L);
+ assertFalse(kvView.containsAll(null, List.of(zeroKeyTuple)));
+ assertFalse(kvView.containsAll(null, List.of(firstKeyTuple,
secondKeyTuple, zeroKeyTuple)));
+ }
+
@Test
public void testPutAll() {
KeyValueView<Tuple, Tuple> kvView = defaultTable().keyValueView();
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
index ba8e895a99..c3a0743fd8 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
@@ -29,6 +29,7 @@ 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.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.math.BigDecimal;
@@ -489,6 +490,34 @@ public class ClientKeyValueViewTest extends
AbstractClientTableTest {
assertFalse(pojoView.contains(null, -1L));
}
+ @Test
+ public void testContainsAll() {
+ KeyValueView<Long, String> pojoView =
defaultTable().keyValueView(Mapper.of(Long.class), Mapper.of(String.class));
+
+ long firstKey = 101L;
+ long secondKey = 102L;
+ long thirdKey = 103L;
+
+ Map<Long, String> pojos = Map.of(
+ firstKey, "201",
+ secondKey, "202",
+ thirdKey, "203"
+ );
+
+ pojoView.putAll(null, pojos);
+
+ assertThrows(NullPointerException.class, () ->
pojoView.containsAll(null, null));
+ assertThrows(NullPointerException.class, () ->
pojoView.containsAll(null, List.of(firstKey, null, thirdKey)));
+
+ assertTrue(pojoView.containsAll(null, List.of()));
+ assertTrue(pojoView.containsAll(null, List.of(firstKey)));
+ assertTrue(pojoView.containsAll(null, List.of(firstKey, secondKey,
thirdKey)));
+
+ long zeroKey = 0L;
+ assertFalse(pojoView.containsAll(null, List.of(zeroKey)));
+ assertFalse(pojoView.containsAll(null, List.of(firstKey, secondKey,
zeroKey)));
+ }
+
@Test
public void testNullableColumnWithDefaultValueSetNullReturnsNull() {
Table table = tableWithDefaultValues();
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
index 0c9243feae..2c91b133eb 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
@@ -290,6 +290,47 @@ public class ClientRecordViewTest extends
AbstractClientTableTest {
assertFalse(recordView.contains(null, new PersonPojo(DEFAULT_ID - 1,
DEFAULT_NAME)));
}
+ @Test
+ public void testContainsAll() {
+ RecordView<PersonPojo> recordView =
defaultTable().recordView(PersonPojo.class);
+
+ long firstKey = 101L;
+ PersonPojo firstPerson = new PersonPojo(firstKey, "201");
+
+ long secondKey = 102L;
+ PersonPojo secondPerson = new PersonPojo(secondKey, "202");
+
+ long thirdKey = 103L;
+ PersonPojo thirdPerson = new PersonPojo(thirdKey, "203");
+
+ List<PersonPojo> recs = List.of(firstPerson, secondPerson,
thirdPerson);
+
+ recordView.insertAll(null, recs);
+
+ assertThrows(NullPointerException.class, () ->
recordView.containsAll(null, null));
+ assertThrows(NullPointerException.class, () ->
recordView.containsAll(null, List.of(firstPerson, null, thirdPerson)));
+
+ assertTrue(recordView.containsAll(null, List.of()));
+ assertTrue(recordView.containsAll(null, List.of(firstPerson)));
+ assertTrue(recordView.containsAll(null, List.of(firstPerson,
secondPerson, thirdPerson)));
+ assertTrue(recordView.containsAll(null, List.of(
+ new PersonPojo(firstKey, " "),
+ new PersonPojo(secondKey, " "),
+ new PersonPojo(thirdKey, " ")
+ )));
+
+ long zeroKey = 0L;
+ PersonPojo missedPojo = new PersonPojo(zeroKey, DEFAULT_NAME);
+
+ assertFalse(recordView.containsAll(null, List.of(missedPojo)));
+ assertFalse(recordView.containsAll(null, List.of(firstPerson,
secondPerson, missedPojo)));
+ assertFalse(recordView.containsAll(null, List.of(
+ new PersonPojo(firstKey, " "),
+ new PersonPojo(secondKey, " "),
+ new PersonPojo(zeroKey, " ")
+ )));
+ }
+
@Test
public void testUpsertAll() {
RecordView<PersonPojo> pojoView =
defaultTable().recordView(Mapper.of(PersonPojo.class));
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientTableTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientTableTest.java
index a23653e336..cd050c6e1e 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/ClientTableTest.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/ClientTableTest.java
@@ -201,6 +201,59 @@ public class ClientTableTest extends
AbstractClientTableTest {
assertEquals("3", res[1].stringValue("name"));
}
+ @Test
+ public void testContains() {
+ RecordView<Tuple> recordView = defaultTable().recordView();
+
+ long key = 101L;
+ Tuple keyTuple = tuple(key);
+ Tuple valTuple = tuple(key, "201");
+
+ recordView.insert(null, valTuple);
+
+ assertThrows(NullPointerException.class, () ->
recordView.contains(null, null));
+
+ assertTrue(recordView.contains(null, keyTuple));
+
+ Tuple missedKeyTuple = tuple(0L);
+
+ assertFalse(recordView.contains(null, missedKeyTuple));
+ }
+
+ @Test
+ public void testContainsAll() {
+ RecordView<Tuple> recordView = defaultTable().recordView();
+
+ long firstKey = 101L;
+ Tuple firstKeyTuple = tuple(firstKey);
+ Tuple firstValTuple = tuple(firstKey, "201");
+
+ long secondKey = 102L;
+ Tuple secondKeyTuple = tuple(secondKey);
+ Tuple secondValTuple = tuple(secondKey, "202");
+
+ long thirdKey = 103L;
+ Tuple thirdKeyTuple = tuple(thirdKey);
+ Tuple thirdValTuple = tuple(thirdKey, "203");
+
+ List<Tuple> recs = List.of(firstValTuple, secondValTuple,
thirdValTuple);
+
+ recordView.insertAll(null, recs);
+
+ assertThrows(NullPointerException.class, () ->
recordView.containsAll(null, null));
+ assertThrows(NullPointerException.class, () ->
recordView.containsAll(null, List.of(firstKeyTuple, null, thirdKeyTuple)));
+
+ assertTrue(recordView.containsAll(null, List.of()));
+ assertTrue(recordView.containsAll(null, List.of(firstKeyTuple)));
+ assertTrue(recordView.containsAll(null, List.of(firstKeyTuple,
secondKeyTuple, thirdKeyTuple)));
+
+ long missedKey = 0L;
+ Tuple missedKeyTuple = tuple(missedKey);
+
+ assertFalse(recordView.containsAll(null, List.of(missedKeyTuple)));
+ assertFalse(recordView.containsAll(null, List.of(firstKeyTuple,
secondKeyTuple, missedKeyTuple)));
+ }
+
@Test
public void testUpsertAll() {
var table = defaultTable().recordView();
diff --git
a/modules/client/src/test/java/org/apache/ignite/internal/client/ClientUtilsTest.java
b/modules/client/src/test/java/org/apache/ignite/internal/client/ClientUtilsTest.java
index eb41308fb2..357539585f 100644
---
a/modules/client/src/test/java/org/apache/ignite/internal/client/ClientUtilsTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/internal/client/ClientUtilsTest.java
@@ -28,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Arrays;
+import org.apache.ignite.internal.util.ViewUtils;
import org.apache.ignite.lang.IgniteCheckedException;
import org.apache.ignite.lang.IgniteException;
import org.jetbrains.annotations.Nullable;
@@ -98,7 +99,7 @@ public class ClientUtilsTest {
* Method that should present in resulting stack trace.
*/
private static Throwable checkableTestMethod(Throwable ex) {
- return ClientUtils.ensurePublicException(ex);
+ return ViewUtils.ensurePublicException(ex);
}
/**
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/util/ViewUtils.java
b/modules/core/src/main/java/org/apache/ignite/internal/util/ViewUtils.java
new file mode 100644
index 0000000000..da3ff46506
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/ViewUtils.java
@@ -0,0 +1,115 @@
+/*
+ * 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.util;
+
+import static org.apache.ignite.internal.util.ExceptionUtils.sneakyThrow;
+import static org.apache.ignite.internal.util.ExceptionUtils.unwrapCause;
+import static org.apache.ignite.lang.ErrorGroups.Common.INTERNAL_ERR;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import org.apache.ignite.internal.lang.IgniteExceptionMapperUtil;
+import org.apache.ignite.lang.IgniteCheckedException;
+import org.apache.ignite.lang.IgniteException;
+import org.apache.ignite.lang.TraceableException;
+
+/**
+ * Table view utilities.
+ */
+public final class ViewUtils {
+ /**
+ * Waits for async operation completion.
+ *
+ * @param fut Future to wait to.
+ * @param <T> Future result type.
+ * @return Future result.
+ */
+ public static <T> T sync(CompletableFuture<T> fut) {
+ try {
+ return fut.get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt(); // Restore interrupt flag.
+
+ throw sneakyThrow(ensurePublicException(e));
+ } catch (ExecutionException e) {
+ Throwable cause = unwrapCause(e);
+
+ throw sneakyThrow(ensurePublicException(cause));
+ }
+ }
+
+ /**
+ * Wraps an exception in an IgniteException, extracting trace identifier
and error code when the specified exception or one of its
+ * causes is an IgniteException itself.
+ *
+ * @param e Internal exception.
+ * @return Public exception.
+ */
+ public static Throwable ensurePublicException(Throwable e) {
+ Objects.requireNonNull(e);
+
+ e = unwrapCause(e);
+
+ if (e instanceof IgniteException) {
+ return copyExceptionWithCauseIfPossible((IgniteException) e);
+ }
+
+ if (e instanceof IgniteCheckedException) {
+ return copyExceptionWithCauseIfPossible((IgniteCheckedException)
e);
+ }
+
+ e = IgniteExceptionMapperUtil.mapToPublicException(e);
+
+ return new IgniteException(INTERNAL_ERR, e.getMessage(), e);
+ }
+
+ /**
+ * Try to copy exception using ExceptionUtils.copyExceptionWithCause and
return new exception if it was not possible.
+ *
+ * @param e Exception.
+ * @return Properly copied exception or a new error, if exception can not
be copied.
+ */
+ private static <T extends Throwable & TraceableException> Throwable
copyExceptionWithCauseIfPossible(T e) {
+ Throwable copy = ExceptionUtils.copyExceptionWithCause(e.getClass(),
e.traceId(), e.code(), e.getMessage(), e);
+ if (copy != null) {
+ return copy;
+ }
+
+ return new IgniteException(INTERNAL_ERR, "Public Ignite
exception-derived class does not have required constructor: "
+ + e.getClass().getName(), e);
+ }
+
+ /**
+ * Checks that given keys collection isn't null and there is no a
null-value key.
+ *
+ * @param keys Given keys collection.
+ * @param <K> Keys type.
+ * @throws NullPointerException In case if the collection null either any
key is null.
+ */
+ public static <K> void checkKeysForNulls(Collection<K> keys) {
+ Objects.requireNonNull(keys, "keys");
+
+ for (K key : keys) {
+ Objects.requireNonNull(key, "key");
+ }
+ }
+
+ private ViewUtils() { }
+}
diff --git
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItPkOnlyTableCrossApiTest.java
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItPkOnlyTableCrossApiTest.java
index 3560cce7a4..96a1fe4bce 100644
---
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItPkOnlyTableCrossApiTest.java
+++
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItPkOnlyTableCrossApiTest.java
@@ -156,7 +156,7 @@ public class ItPkOnlyTableCrossApiTest extends
BaseSqlIntegrationTest {
rwTx -> {
IgniteException ex = assertThrows(IgniteException.class,
() -> tab.keyValueView(KeyObject.class,
Integer.class).put(rwTx, key, 1));
- assertThat(ex.getCause(),
is(instanceOf(IllegalArgumentException.class)));
+ assertThat(ex.getCause().getCause(),
is(instanceOf(IllegalArgumentException.class)));
kvView.put(rwTx, key, null);
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/AbstractTableView.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/AbstractTableView.java
index bfffdf5956..70ff46fb76 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/AbstractTableView.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/AbstractTableView.java
@@ -22,14 +22,13 @@ import static java.util.function.Function.identity;
import static
org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.convertToPublicFuture;
import static
org.apache.ignite.internal.table.criteria.CriteriaExceptionMapperUtil.mapToPublicCriteriaException;
import static org.apache.ignite.internal.util.ExceptionUtils.isOrCausedBy;
-import static org.apache.ignite.internal.util.ExceptionUtils.sneakyThrow;
import static org.apache.ignite.internal.util.ExceptionUtils.unwrapCause;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
-import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.ignite.internal.lang.IgniteExceptionMapperUtil;
@@ -99,26 +98,6 @@ abstract class AbstractTableView<R> implements
CriteriaQuerySource<R> {
this.rowConverter = new TableViewRowConverter(schemaReg);
}
- /**
- * Waits for operation completion.
- *
- * @param future Future to wait to.
- * @param <T> Future result type.
- * @return Future result.
- */
- protected static <T> T sync(CompletableFuture<T> future) {
- try {
- return future.get();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt(); // Restore interrupt flag.
-
- throw
sneakyThrow(IgniteExceptionMapperUtil.mapToPublicException(e));
- } catch (ExecutionException e) {
- Throwable cause = unwrapCause(e);
- throw sneakyThrow(cause);
- }
- }
-
/**
* Combines the effect of {@link #withSchemaSync(Transaction, KvAction)}
and
* {@link
IgniteExceptionMapperUtil#convertToPublicFuture(CompletableFuture)}.
@@ -275,7 +254,6 @@ abstract class AbstractTableView<R> implements
CriteriaQuerySource<R> {
});
}
-
/**
* Action representing some KV operation. When executed, the action is
supplied with schema version corresponding
* to the operation timestamp (see {@link #doOperation(Transaction,
KvAction)} for details).
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueBinaryViewImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueBinaryViewImpl.java
index d450b60d76..d608e65081 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueBinaryViewImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueBinaryViewImpl.java
@@ -18,6 +18,9 @@
package org.apache.ignite.internal.table;
import static
org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.convertToPublicFuture;
+import static
org.apache.ignite.internal.util.CompletableFutures.trueCompletedFuture;
+import static org.apache.ignite.internal.util.ViewUtils.checkKeysForNulls;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.ArrayList;
import java.util.BitSet;
@@ -162,14 +165,6 @@ public class KeyValueBinaryViewImpl extends
AbstractTableView<Entry<Tuple, Tuple
});
}
- private static void checkKeysForNulls(Collection<Tuple> keys) {
- Objects.requireNonNull(keys, "keys");
-
- for (Tuple key : keys) {
- Objects.requireNonNull(key, "key");
- }
- }
-
/** {@inheritDoc} */
@Override
public boolean contains(@Nullable Transaction tx, Tuple key) {
@@ -182,6 +177,34 @@ public class KeyValueBinaryViewImpl extends
AbstractTableView<Entry<Tuple, Tuple
return getAsync(tx, key).thenApply(Objects::nonNull);
}
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<Tuple>
keys) {
+ return sync(containsAllAsync(tx, keys));
+ }
+
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<Tuple> keys) {
+ checkKeysForNulls(keys);
+
+ if (keys.isEmpty()) {
+ return trueCompletedFuture();
+ }
+
+ return doOperation(tx, (schemaVersion) -> {
+ List<BinaryRowEx> keyRows = marshalKeys(keys, schemaVersion);
+
+ return tbl.getAll(keyRows, (InternalTransaction)
tx).thenApply(rows -> {
+ for (BinaryRow row : rows) {
+ if (row == null) {
+ return false;
+ }
+ }
+
+ return true;
+ });
+ });
+ }
+
/** {@inheritDoc} */
@Override
public void put(@Nullable Transaction tx, Tuple key, Tuple val) {
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueViewImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueViewImpl.java
index ad3f771d42..e523e52efc 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueViewImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueViewImpl.java
@@ -21,6 +21,9 @@ import static
org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.convertT
import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
import static
org.apache.ignite.internal.marshaller.ValidationUtils.validateNullableOperation;
import static
org.apache.ignite.internal.marshaller.ValidationUtils.validateNullableValue;
+import static
org.apache.ignite.internal.util.CompletableFutures.trueCompletedFuture;
+import static org.apache.ignite.internal.util.ViewUtils.checkKeysForNulls;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.ArrayList;
import java.util.BitSet;
@@ -201,14 +204,6 @@ public class KeyValueViewImpl<K, V> extends
AbstractTableView<Entry<K, V>> imple
});
}
- private static <K> void checkKeysForNulls(Collection<K> keys) {
- Objects.requireNonNull(keys, "keys");
-
- for (K key : keys) {
- Objects.requireNonNull(key, "key");
- }
- }
-
/** {@inheritDoc} */
@Override
public boolean contains(@Nullable Transaction tx, K key) {
@@ -227,6 +222,36 @@ public class KeyValueViewImpl<K, V> extends
AbstractTableView<Entry<K, V>> imple
});
}
+ /** {@inheritDoc} */
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<K> keys) {
+ return sync(containsAllAsync(tx, keys));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<K> keys) {
+ checkKeysForNulls(keys);
+
+ if (keys.isEmpty()) {
+ return trueCompletedFuture();
+ }
+
+ return doOperation(tx, (schemaVersion) -> {
+ Collection<BinaryRowEx> keyRows = marshal(keys, schemaVersion);
+
+ return tbl.getAll(keyRows, (InternalTransaction)
tx).thenApply(rows -> {
+ for (BinaryRow row : rows) {
+ if (row == null) {
+ return false;
+ }
+ }
+
+ return true;
+ });
+ });
+ }
+
/** {@inheritDoc} */
@Override
public void put(@Nullable Transaction tx, K key, @Nullable V val) {
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/PublicApiThreadingKeyValueView.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/PublicApiThreadingKeyValueView.java
index 0963fd85a1..f4e941a39c 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/PublicApiThreadingKeyValueView.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/PublicApiThreadingKeyValueView.java
@@ -102,6 +102,16 @@ public class PublicApiThreadingKeyValueView<K, V> extends
PublicApiThreadingView
return executeAsyncOp(() -> view.containsAsync(tx, key));
}
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<K> keys) {
+ return executeSyncOp(() -> view.containsAll(tx, keys));
+ }
+
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<K> keys) {
+ return executeSyncOp(() -> view.containsAllAsync(tx, keys));
+ }
+
@Override
public void put(@Nullable Transaction tx, K key, @Nullable V val) {
executeSyncOp(() -> view.put(tx, key, val));
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/PublicApiThreadingRecordView.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/PublicApiThreadingRecordView.java
index 076e01b211..dbab23bf99 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/PublicApiThreadingRecordView.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/PublicApiThreadingRecordView.java
@@ -81,6 +81,16 @@ public class PublicApiThreadingRecordView<R> extends
PublicApiThreadingViewBase<
return executeAsyncOp(() -> view.containsAsync(tx, keyRec));
}
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<R> keys) {
+ return executeSyncOp(() -> view.containsAll(tx, keys));
+ }
+
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<R> keys) {
+ return executeSyncOp(() -> view.containsAllAsync(tx, keys));
+ }
+
@Override
public void upsert(@Nullable Transaction tx, R rec) {
executeSyncOp(() -> view.upsert(tx, rec));
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordBinaryViewImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordBinaryViewImpl.java
index b901499305..8649fe26bf 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordBinaryViewImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordBinaryViewImpl.java
@@ -19,6 +19,9 @@ package org.apache.ignite.internal.table;
import static java.util.concurrent.CompletableFuture.completedFuture;
import static
org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.convertToPublicFuture;
+import static
org.apache.ignite.internal.util.CompletableFutures.trueCompletedFuture;
+import static org.apache.ignite.internal.util.ViewUtils.checkKeysForNulls;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.ArrayList;
import java.util.BitSet;
@@ -139,6 +142,36 @@ public class RecordBinaryViewImpl extends
AbstractTableView<Tuple> implements Re
});
}
+ /** {@inheritDoc} */
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<Tuple>
keys) {
+ return sync(containsAllAsync(tx, keys));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<Tuple> keys) {
+ checkKeysForNulls(keys);
+
+ if (keys.isEmpty()) {
+ return trueCompletedFuture();
+ }
+
+ return doOperation(tx, (schemaVersion) -> {
+ Collection<BinaryRowEx> keysRows = mapToBinary(keys,
schemaVersion, true);
+
+ return tbl.getAll(keysRows, (InternalTransaction)
tx).thenApply(rows -> {
+ for (BinaryRow row : rows) {
+ if (row == null) {
+ return false;
+ }
+ }
+
+ return true;
+ });
+ });
+ }
+
/** {@inheritDoc} */
@Override
public void upsert(@Nullable Transaction tx, Tuple rec) {
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java
index 57bc3903e0..e633bfb57a 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java
@@ -18,6 +18,9 @@
package org.apache.ignite.internal.table;
import static
org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.convertToPublicFuture;
+import static
org.apache.ignite.internal.util.CompletableFutures.trueCompletedFuture;
+import static org.apache.ignite.internal.util.ViewUtils.checkKeysForNulls;
+import static org.apache.ignite.internal.util.ViewUtils.sync;
import java.util.ArrayList;
import java.util.BitSet;
@@ -146,6 +149,36 @@ public class RecordViewImpl<R> extends
AbstractTableView<R> implements RecordVie
});
}
+ /** {@inheritDoc} */
+ @Override
+ public boolean containsAll(@Nullable Transaction tx, Collection<R> keys) {
+ return sync(containsAllAsync(tx, keys));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public CompletableFuture<Boolean> containsAllAsync(@Nullable Transaction
tx, Collection<R> keys) {
+ checkKeysForNulls(keys);
+
+ if (keys.isEmpty()) {
+ return trueCompletedFuture();
+ }
+
+ return doOperation(tx, (schemaVersion) -> {
+ Collection<BinaryRowEx> keyRows = marshalKeys(keys, schemaVersion);
+
+ return tbl.getAll(keyRows, (InternalTransaction)
tx).thenApply(rows -> {
+ for (BinaryRow row : rows) {
+ if (row == null) {
+ return false;
+ }
+ }
+
+ return true;
+ });
+ });
+ }
+
/** {@inheritDoc} */
@Override
public void upsert(@Nullable Transaction tx, R rec) {
diff --git
a/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueBinaryViewOperationsTest.java
b/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueBinaryViewOperationsTest.java
index 72112cd76e..f9e8ed9757 100644
---
a/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueBinaryViewOperationsTest.java
+++
b/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueBinaryViewOperationsTest.java
@@ -234,6 +234,46 @@ public class KeyValueBinaryViewOperationsTest extends
TableKvOperationsTestBase
assertFalse(tbl.contains(null, Tuple.create().set("id", 2L)));
}
+
+ @Test
+ public void testContainsAll() {
+ SchemaDescriptor schema = schemaDescriptor();
+
+ KeyValueView<Tuple, Tuple> kvView = createTable(schema).keyValueView();
+
+ long firstKey = 101L;
+ Tuple firstKeyTuple = Tuple.create().set("id", firstKey);
+ Tuple firstValTuple = Tuple.create().set("val", 201L);
+
+ long secondKey = 102L;
+ Tuple secondKeyTuple = Tuple.create().set("id", secondKey);
+ Tuple secondValTuple = Tuple.create().set("val", 202L);
+
+ long thirdKey = 103L;
+ Tuple thirdKeyTuple = Tuple.create().set("id", thirdKey);
+ Tuple thirdValTuple = Tuple.create().set("val", 203L);
+
+ Map<Tuple, Tuple> kvs = Map.of(
+ firstKeyTuple, firstValTuple,
+ secondKeyTuple, secondValTuple,
+ thirdKeyTuple, thirdValTuple
+ );
+
+ kvView.putAll(null, kvs);
+
+ assertThrows(NullPointerException.class, () ->
kvView.containsAll(null, null));
+ assertThrows(NullPointerException.class, () ->
kvView.containsAll(null, List.of(firstKeyTuple, null, thirdKeyTuple)));
+
+ assertTrue(kvView.containsAll(null, List.of()));
+ assertTrue(kvView.containsAll(null, List.of(firstKeyTuple)));
+ assertTrue(kvView.containsAll(null, List.of(firstKeyTuple,
secondKeyTuple, thirdKeyTuple)));
+
+ Tuple missedKeyTuple = Tuple.create().set("id", 0L);
+
+ assertFalse(kvView.containsAll(null, List.of(missedKeyTuple)));
+ assertFalse(kvView.containsAll(null, List.of(firstKeyTuple,
secondKeyTuple, missedKeyTuple)));
+ }
+
@Test
public void remove() {
SchemaDescriptor schema = schemaDescriptor();
diff --git
a/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueViewOperationsTest.java
b/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueViewOperationsTest.java
index 58589c2159..7aab26ce9b 100644
---
a/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueViewOperationsTest.java
+++
b/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueViewOperationsTest.java
@@ -292,6 +292,40 @@ public class KeyValueViewOperationsTest extends
TableKvOperationsTestBase {
assertFalse(tbl.contains(null, key2));
}
+ @Test
+ public void testContainsAll() {
+ KeyValueView<TestKeyObject, TestObjectWithAllTypes> kvView = kvView();
+
+ TestKeyObject firstKey = TestKeyObject.randomObject(rnd);
+ TestObjectWithAllTypes firstVal =
TestObjectWithAllTypes.randomObject(rnd);
+
+ TestKeyObject secondKey = TestKeyObject.randomObject(rnd);
+ TestObjectWithAllTypes secondVal =
TestObjectWithAllTypes.randomObject(rnd);
+
+ TestKeyObject thirdKey = TestKeyObject.randomObject(rnd);
+ TestObjectWithAllTypes thirdVal =
TestObjectWithAllTypes.randomObject(rnd);
+
+ Map<TestKeyObject, TestObjectWithAllTypes> kvs = Map.of(
+ firstKey, firstVal,
+ secondKey, secondVal,
+ thirdKey, thirdVal
+ );
+
+ kvView.putAll(null, kvs);
+
+ assertThrows(NullPointerException.class, () ->
kvView.containsAll(null, null));
+ assertThrows(NullPointerException.class, () ->
kvView.containsAll(null, List.of(firstKey, null, thirdKey)));
+
+ assertTrue(kvView.containsAll(null, List.of()));
+ assertTrue(kvView.containsAll(null, List.of(firstKey)));
+ assertTrue(kvView.containsAll(null, List.of(firstKey, secondKey,
thirdKey)));
+
+ TestKeyObject missedKey = TestKeyObject.randomObject(rnd);
+
+ assertFalse(kvView.containsAll(null, List.of(missedKey)));
+ assertFalse(kvView.containsAll(null, List.of(firstKey, secondKey,
missedKey)));
+ }
+
@Test
public void remove() {
final TestKeyObject key = TestKeyObject.randomObject(rnd);
diff --git
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
index 43d2c6cc32..27e68fbbfb 100644
---
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
+++
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
@@ -367,6 +367,51 @@ public class RecordBinaryViewOperationsTest extends
TableKvOperationsTestBase {
assertTrue(tbl.contains(null, keyRec));
}
+ @Test
+ public void testContainsAll() {
+ SchemaDescriptor schema = schemaDescriptor();
+ RecordView<Tuple> recordView = createTable(schema).recordView();
+
+ long firstKey = 101L;
+ Tuple firstKeyTuple = Tuple.create()
+ .set("id", firstKey);
+ Tuple firstValTuple = Tuple.create()
+ .set("id", firstKey)
+ .set("val", 201L);
+
+ long secondKey = 102L;
+ Tuple secondKeyTuple = Tuple.create()
+ .set("id", secondKey);
+ Tuple secondValTuple = Tuple.create()
+ .set("id", secondKey)
+ .set("val", 202L);
+
+ long thirdKey = 103L;
+ Tuple thirdKeyTuple = Tuple.create()
+ .set("id", thirdKey);
+ Tuple thirdValTuple = Tuple.create()
+ .set("id", thirdKey)
+ .set("val", 203L);
+
+ List<Tuple> recs = List.of(firstValTuple, secondValTuple,
thirdValTuple);
+
+ recordView.insertAll(null, recs);
+
+ assertThrows(NullPointerException.class, () ->
recordView.containsAll(null, null));
+ assertThrows(NullPointerException.class, () ->
recordView.containsAll(null, List.of(firstKeyTuple, null, thirdKeyTuple)));
+
+ assertTrue(recordView.containsAll(null, List.of()));
+ assertTrue(recordView.containsAll(null, List.of(firstKeyTuple)));
+ assertTrue(recordView.containsAll(null, List.of(firstKeyTuple,
secondKeyTuple, thirdKeyTuple)));
+
+ long missedKey = 0L;
+ Tuple missedKeyTuple = Tuple.create()
+ .set("id", missedKey);
+
+ assertFalse(recordView.containsAll(null, List.of(missedKeyTuple)));
+ assertFalse(recordView.containsAll(null, List.of(firstKeyTuple,
secondKeyTuple, missedKeyTuple)));
+ }
+
@Test
public void upsertAllAfterInsertAll() {
SchemaDescriptor schema = schemaDescriptor();
diff --git
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordViewOperationsTest.java
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordViewOperationsTest.java
index 72d5382a73..551dc0e23b 100644
---
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordViewOperationsTest.java
+++
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordViewOperationsTest.java
@@ -38,6 +38,7 @@ import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.ArgumentMatchers.any;
@@ -364,6 +365,42 @@ public class RecordViewOperationsTest extends
TableKvOperationsTestBase {
assertFalse(tbl.contains(null, randomObject(rnd, wrongKey)));
}
+ @Test
+ public void testContainsAll() {
+ RecordView<TestObjectWithAllTypes> recordView = recordView();
+
+ TestObjectWithAllTypes firstKey = key(rnd);
+ TestObjectWithAllTypes firstVal = randomObject(rnd, firstKey);
+
+ TestObjectWithAllTypes secondKey = key(rnd);
+ TestObjectWithAllTypes secondVal = randomObject(rnd, secondKey);
+
+ TestObjectWithAllTypes thirdKey = key(rnd);
+ TestObjectWithAllTypes thirdVal = randomObject(rnd, thirdKey);
+
+ List<TestObjectWithAllTypes> recs = List.of(firstVal, secondVal,
thirdVal);
+
+ recordView.insertAll(null, recs);
+
+ assertThrows(NullPointerException.class, () ->
recordView.containsAll(null, null));
+ assertThrows(NullPointerException.class, () ->
recordView.containsAll(null, List.of(firstKey, null, thirdKey)));
+ assertThrows(NullPointerException.class, () ->
recordView.containsAll(null, List.of(firstVal, null, thirdVal)));
+
+ assertTrue(recordView.containsAll(null, List.of()));
+ assertTrue(recordView.containsAll(null, List.of(firstKey)));
+ assertTrue(recordView.containsAll(null, List.of(firstVal)));
+ assertTrue(recordView.containsAll(null, List.of(firstKey, secondKey,
thirdKey)));
+ assertTrue(recordView.containsAll(null, List.of(firstVal, secondVal,
thirdVal)));
+
+ TestObjectWithAllTypes missedKey = key(rnd);
+ TestObjectWithAllTypes missedVal = randomObject(rnd, missedKey);
+
+ assertFalse(recordView.containsAll(null, List.of(missedKey)));
+ assertFalse(recordView.containsAll(null, List.of(missedVal)));
+ assertFalse(recordView.containsAll(null, List.of(firstKey, secondKey,
missedKey)));
+ assertFalse(recordView.containsAll(null, List.of(firstVal, secondVal,
missedVal)));
+ }
+
@Test
void retriesOnInternalSchemaVersionMismatchException() throws Exception {
RecordView<TestObjectWithAllTypes> view = recordView();