From a72f57f4720fc30c3ed00074dedb1b51f321a0af Mon Sep 17 00:00:00 2001 From: Dheeraj Mishra Date: Fri, 13 Feb 2026 10:35:23 +0530 Subject: [PATCH] CLIENT-4159: enhance dostring based on the given template that provides additional contenxt to LLM to generate correct code snippet --- .../src/com/aerospike/client/AbortStatus.java | 38 +- .../com/aerospike/client/AerospikeClient.java | 1338 ++++++++++++++++- .../aerospike/client/AerospikeException.java | 389 ++++- .../src/com/aerospike/client/BatchDelete.java | 18 +- .../src/com/aerospike/client/BatchRead.java | 20 +- .../src/com/aerospike/client/BatchRecord.java | 71 +- client/src/com/aerospike/client/BatchUDF.java | 17 +- .../src/com/aerospike/client/BatchWrite.java | 18 +- client/src/com/aerospike/client/Bin.java | 54 +- .../src/com/aerospike/client/CommitError.java | 39 +- .../com/aerospike/client/CommitStatus.java | 39 +- client/src/com/aerospike/client/Host.java | 47 +- .../aerospike/client/IAerospikeClient.java | 252 ++-- client/src/com/aerospike/client/Info.java | 63 +- client/src/com/aerospike/client/Key.java | 234 ++- client/src/com/aerospike/client/Language.java | 17 +- .../src/com/aerospike/client/Operation.java | 69 +- client/src/com/aerospike/client/Record.java | 147 +- .../src/com/aerospike/client/ResultCode.java | 46 +- .../com/aerospike/client/ScanCallback.java | 41 +- client/src/com/aerospike/client/Txn.java | 72 +- client/src/com/aerospike/client/Value.java | 144 +- .../com/aerospike/client/admin/Privilege.java | 28 +- .../aerospike/client/admin/PrivilegeCode.java | 8 +- .../client/async/AsyncIndexTask.java | 18 +- .../com/aerospike/client/async/EventLoop.java | 19 +- .../aerospike/client/async/EventLoopType.java | 8 +- .../aerospike/client/async/EventLoops.java | 17 +- .../aerospike/client/async/EventPolicy.java | 11 +- .../client/async/NettyEventLoops.java | 14 +- .../aerospike/client/async/NioEventLoops.java | 11 +- .../aerospike/client/cdt/ListOperation.java | 70 +- .../aerospike/client/cdt/ListReturnType.java | 4 +- .../aerospike/client/cdt/ListWriteFlags.java | 4 +- .../aerospike/client/cdt/MapOperation.java | 89 +- .../aerospike/client/cdt/MapReturnType.java | 4 +- .../aerospike/client/cdt/MapWriteFlags.java | 4 +- .../aerospike/client/cluster/Connection.java | 35 + .../configuration/ConfigurationProvider.java | 24 + .../src/com/aerospike/client/exp/CdtExp.java | 42 +- .../aerospike/client/exp/ExpWriteFlags.java | 4 +- .../src/com/aerospike/client/exp/ListExp.java | 66 +- .../src/com/aerospike/client/exp/MapExp.java | 105 +- .../client/listener/AbortListener.java | 11 + .../client/listener/BatchListListener.java | 12 + .../listener/BatchOperateListListener.java | 12 + .../listener/BatchRecordArrayListener.java | 12 + .../listener/BatchRecordSequenceListener.java | 13 + .../listener/BatchSequenceListener.java | 13 + .../client/listener/ClusterStatsListener.java | 12 + .../client/listener/CommitListener.java | 12 + .../client/listener/DeleteListener.java | 12 + .../client/listener/ExecuteListener.java | 12 + .../client/listener/ExistsArrayListener.java | 12 + .../client/listener/ExistsListener.java | 12 + .../listener/ExistsSequenceListener.java | 13 + .../client/listener/IndexListener.java | 13 + .../client/listener/InfoListener.java | 12 + .../client/listener/RecordArrayListener.java | 12 + .../client/listener/RecordListener.java | 13 + .../listener/RecordSequenceListener.java | 40 +- .../client/listener/TaskStatusListener.java | 12 + .../client/listener/WriteListener.java | 13 + .../client/operation/BitOperation.java | 20 +- .../client/operation/BitOverflowAction.java | 8 +- .../aerospike/client/operation/BitPolicy.java | 9 +- .../client/operation/BitResizeFlags.java | 8 +- .../client/operation/BitWriteFlags.java | 4 +- .../client/operation/HLLOperation.java | 19 +- .../aerospike/client/operation/HLLPolicy.java | 9 +- .../client/operation/HLLWriteFlags.java | 4 +- .../aerospike/client/policy/AdminPolicy.java | 11 +- .../client/policy/BatchDeletePolicy.java | 12 +- .../aerospike/client/policy/BatchPolicy.java | 22 +- .../client/policy/BatchReadPolicy.java | 12 +- .../client/policy/BatchUDFPolicy.java | 11 +- .../client/policy/BatchWritePolicy.java | 12 +- .../aerospike/client/policy/ClientPolicy.java | 103 +- .../aerospike/client/policy/InfoPolicy.java | 10 +- .../com/aerospike/client/policy/Policy.java | 53 +- .../aerospike/client/policy/QueryPolicy.java | 64 +- .../aerospike/client/policy/ScanPolicy.java | 27 +- .../aerospike/client/policy/TCPKeepAlive.java | 9 +- .../aerospike/client/policy/TlsPolicy.java | 15 +- .../client/policy/TxnRollPolicy.java | 7 +- .../client/policy/TxnVerifyPolicy.java | 7 +- .../aerospike/client/policy/WritePolicy.java | 27 +- .../com/aerospike/client/query/Filter.java | 54 +- .../client/query/IndexCollectionType.java | 8 +- .../com/aerospike/client/query/IndexType.java | 8 +- .../com/aerospike/client/query/KeyRecord.java | 55 +- .../client/query/PartitionFilter.java | 15 +- .../aerospike/client/query/QueryListener.java | 30 +- .../com/aerospike/client/query/RecordSet.java | 54 +- .../com/aerospike/client/query/RegexFlag.java | 4 +- .../com/aerospike/client/query/ResultSet.java | 43 +- .../com/aerospike/client/query/Statement.java | 244 ++- .../aerospike/client/task/ExecuteTask.java | 54 +- .../com/aerospike/client/task/IndexTask.java | 44 +- .../aerospike/client/task/RegisterTask.java | 36 +- .../src/com/aerospike/client/task/Task.java | 75 +- .../src/com/aerospike/client/util/Utf8.java | 2 +- .../com/aerospike/client/util/Version.java | 14 + 103 files changed, 4357 insertions(+), 897 deletions(-) diff --git a/client/src/com/aerospike/client/AbortStatus.java b/client/src/com/aerospike/client/AbortStatus.java index 4aee26c36..1822917bc 100644 --- a/client/src/com/aerospike/client/AbortStatus.java +++ b/client/src/com/aerospike/client/AbortStatus.java @@ -17,16 +17,52 @@ package com.aerospike.client; /** - * Transaction abort status code. + * Status code for a transaction abort operation. + * + *

Indicates success ({@link #OK}, {@link #ALREADY_ABORTED}) or that the client roll-back/close was abandoned + * and the server will eventually abort. The {@link #str} field holds the full message for logging or display. + * + *

Abort a transaction and check the returned status.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient(new ClientPolicy(), "localhost", 3000);
+ * Txn txn = new Txn();
+ * // ... attach txn to multi-record ops, then decide to abort
+ * AbortStatus status = client.abort(txn);
+ * if (status == AbortStatus.OK || status == AbortStatus.ALREADY_ABORTED) {
+ *     // Abort completed or was already aborted
+ * } else {
+ *     // ROLL_BACK_ABANDONED or CLOSE_ABANDONED; server will eventually abort
+ *     System.err.println(status.str);
+ * }
+ * }
+ * + * @see com.aerospike.client.CommitStatus + * @see com.aerospike.client.CommitError + * @see com.aerospike.client.AerospikeClient#abort */ public enum AbortStatus { + /** Abort completed successfully. */ OK("Abort succeeded"), + + /** Transaction was already aborted (e.g. duplicate abort). */ ALREADY_ABORTED("Already aborted"), + + /** Client roll-back was abandoned; server will eventually abort the transaction. */ ROLL_BACK_ABANDONED("Transaction client roll back abandoned. Server will eventually abort the transaction."), + + /** Transaction was rolled back but client close was abandoned; server will eventually close. */ CLOSE_ABANDONED("Transaction has been rolled back, but transaction client close was abandoned. Server will eventually close the transaction."); + /** + * Full status message for this value; suitable for logging or user display. + */ public final String str; + /** + * Constructor for enum constant. + * + * @param str the full status message + */ AbortStatus(String str) { this.str = str; } diff --git a/client/src/com/aerospike/client/AerospikeClient.java b/client/src/com/aerospike/client/AerospikeClient.java index a5c8cdfd3..39eb6ba48 100644 --- a/client/src/com/aerospike/client/AerospikeClient.java +++ b/client/src/com/aerospike/client/AerospikeClient.java @@ -139,16 +139,28 @@ import com.aerospike.client.util.Version; /** - * Instantiate an AerospikeClient object to access an Aerospike - * database cluster and perform database operations. - *

- * This client is thread-safe. One client instance should be used per cluster. - * Multiple threads should share this cluster instance. - *

- * Your application uses this class API to perform database operations such as - * writing and reading records, and selecting sets of records. Write operations - * include specialized functionality such as append/prepend and arithmetic - * addition. + * Main client for connecting to an Aerospike cluster and performing database operations. + * + *

Overview + *

+ * + *

Connect, write, read, then close the client.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Key key = new Key("test", "set1", "id1");
+ * client.put(null, key, new Bin("name", "Alice"), new Bin("age", 30));
+ * Record rec = client.get(null, key);
+ * if (rec != null) { System.out.println(rec.getString("name")); }
+ * client.close();
+ * }
+ * + * @see ClientPolicy + * @see Key + * @see Bin */ public class AerospikeClient implements IAerospikeClient, Closeable { //------------------------------------------------------- @@ -421,7 +433,19 @@ protected AerospikeClient(ClientPolicy policy) { } /** - * Return the client's ConfigurationProvider. + * Return the client's configuration provider, if set via {@link ClientPolicy}. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     ConfigurationProvider cp = client.getConfigProvider();
+	 *     if (cp != null) { // use config
+	 *     }
+	 * } finally { client.close(); }
+	 * }
+ * + * @return the configuration provider, or null if none was set */ public ConfigurationProvider getConfigProvider() { return configProvider; @@ -683,6 +707,15 @@ public void restorePolicyDefaults() { * This close() method will wait for shutdown if the current thread is not * an event loop thread. It's recommended to call close() from a non event * loop thread for this reason. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * try (IAerospikeClient client = new AerospikeClient("localhost", 3000)) {
+	 *     // ... use client ...
+	 * } finally {
+	 *    client.close();
+	 * }
+	 * }
*/ public void close() { cluster.close(); @@ -691,6 +724,15 @@ public void close() { /** * Determine if we are ready to talk to the database server cluster. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     if (client.isConnected()) { // use cluster
+	 *     }
+	 * } finally { client.close(); }
+	 * }
+ * * @return true if cluster is ready, * false if cluster is not ready */ @@ -700,6 +742,16 @@ public final boolean isConnected() { /** * Return array of active server nodes in the cluster. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     for (Node n : client.getNodes()) { System.out.println(n.getName()); }
+	 * } finally { client.close(); }
+	 * }
+ * + * @return array of active cluster nodes */ public final Node[] getNodes() { return cluster.getNodes(); @@ -707,6 +759,16 @@ public final Node[] getNodes() { /** * Return list of active server node names in the cluster. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     List names = client.getNodeNames();
+	 * } finally { client.close(); }
+	 * }
+ * + * @return list of node names */ public final List getNodeNames() { Node[] nodes = cluster.getNodes(); @@ -720,6 +782,17 @@ public final List getNodeNames() { /** * Return node given its name. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Node n = client.getNode("BB9020011AC4202");
+	 * } finally { client.close(); }
+	 * }
+ * + * @param nodeName node name + * @return the node * @throws AerospikeException.InvalidNode if node does not exist. */ public final Node getNode(String nodeName) @@ -729,6 +802,16 @@ public final Node getNode(String nodeName) /** * Enable extended periodic cluster and node latency metrics. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.enableMetrics(new MetricsPolicy());
+	 * } finally { client.close(); }
+	 * }
+ * + * @param policy metrics policy, or null for defaults */ public final void enableMetrics(MetricsPolicy policy) { cluster.enableMetrics(policy); @@ -736,6 +819,14 @@ public final void enableMetrics(MetricsPolicy policy) { /** * Disable extended periodic cluster and node latency metrics. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.disableMetrics();
+	 * } finally { client.close(); }
+	 * }
*/ public final void disableMetrics() { cluster.disableMetrics(); @@ -743,6 +834,16 @@ public final void disableMetrics() { /** * Return operating cluster statistics snapshot. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     ClusterStats stats = client.getClusterStats();
+	 * } finally { client.close(); }
+	 * }
+ * + * @return current cluster statistics */ public final ClusterStats getClusterStats() { return cluster.getStats(); @@ -750,6 +851,19 @@ public final ClusterStats getClusterStats() { /** * Asynchronously return operating cluster statistics snapshot. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.getClusterStats((clusterStats, e) -> {
+	 *         if (e != null) throw new RuntimeException(e);
+	 *         // use clusterStats
+	 *     });
+	 * } finally { client.close(); }
+	 * }
+ * + * @param listener callback for the result or error */ public final void getClusterStats(ClusterStatsListener listener) { cluster.getStats(listener); @@ -757,13 +871,33 @@ public final void getClusterStats(ClusterStatsListener listener) { /** * Return operating cluster. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * Cluster c = client.getCluster();
+	 * client.close();
+	 * }
+ * + * @return the cluster instance */ public final Cluster getCluster() { return cluster; } /** - * Return the client version + * Return the client library version string. + * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     String v = client.getVersion();
+	 *     System.out.println("Client version: " + v);
+	 * } finally { client.close(); }
+	 * }
+ * + * @return the version string (e.g. "9.3.0") */ public String getVersion() { return version; @@ -780,6 +914,15 @@ public String getVersion() { *

* Requires server version 8.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     // txn is your transaction (e.g. from Txn.addRead/addWrite)
+	 *     CommitStatus status = client.commit(txn);
+	 * } finally { client.close(); }
+	 * }
+ * * @param txn transaction * @return status of the commit on success * @throws AerospikeException.Commit if verify commit fails @@ -816,6 +959,16 @@ public final CommitStatus commit(Txn txn) *

* Requires server version 8.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     // txn from your transaction flow; eventLoop may be null if not using async
+	 *     client.commit(eventLoop, (status, e) -> { if (e != null) throw new RuntimeException(e); }, txn);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -856,6 +1009,16 @@ public final void commit(EventLoop eventLoop, CommitListener listener, Txn txn) *

* Requires server version 8.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     // txn is your transaction to abort
+	 *     AbortStatus status = client.abort(txn);
+	 *     System.err.println(status.str);
+	 * } finally { client.close(); }
+	 * }
+ * * @param txn transaction * @return status of the abort */ @@ -884,6 +1047,15 @@ public final AbortStatus abort(Txn txn) { *

* Requires server version 8.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     client.abort(eventLoop, (status, e) -> { if (e != null) throw new RuntimeException(e); }, txn);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -923,6 +1095,15 @@ public final void abort(EventLoop eventLoop, AbortListener listener, Txn txn) * The policy specifies the command timeouts, record expiration and how the command is * handled when the record already exists. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.put(null, key, new Bin("name", "Alice"), new Bin("age", 30));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs @@ -952,6 +1133,17 @@ public final void put(WritePolicy policy, Key key, Bin... bins) * The policy specifies the command timeout, record expiration and how the command is * handled when the record already exists. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.put(eventLoop, (k, ex) -> { if (ex != null) throw new RuntimeException(ex); },
+	 *         null, key, new Bin("name", "Alice"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results, pass in null for fire and forget @@ -986,6 +1178,15 @@ public final void put(EventLoop eventLoop, WriteListener listener, WritePolicy p * handled when the record already exists. * This call only works for string values. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.append(null, key, new Bin("name", "_suffix"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs @@ -1016,6 +1217,16 @@ public final void append(WritePolicy policy, Key key, Bin... bins) * handled when the record already exists. * This call only works for string values. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.append(eventLoop, null, null, key, new Bin("name", "_suffix"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results, pass in null for fire and forget @@ -1046,6 +1257,15 @@ public final void append(EventLoop eventLoop, WriteListener listener, WritePolic * handled when the record already exists. * This call works only for string values. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.prepend(null, key, new Bin("name", "prefix_"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs @@ -1076,6 +1296,16 @@ public final void prepend(WritePolicy policy, Key key, Bin... bins) * handled when the record already exists. * This call only works for string values. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.prepend(eventLoop, null, null, key, new Bin("name", "prefix_"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results, pass in null for fire and forget @@ -1110,6 +1340,15 @@ public final void prepend(EventLoop eventLoop, WriteListener listener, WritePoli * command timeout, record expiration and how the command is handled when the record * already exists. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.add(null, key, new Bin("count", 1));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs @@ -1140,6 +1379,16 @@ public final void add(WritePolicy policy, Key key, Bin... bins) * This method registers the command with an event loop and returns. * The event loop thread will process the command and send the results to the listener. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.add(eventLoop, null, null, key, new Bin("count", 1));
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results, pass in null for fire and forget @@ -1172,6 +1421,15 @@ public final void add(EventLoop eventLoop, WriteListener listener, WritePolicy p * Delete record for specified key. * The policy specifies the command timeout. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     boolean existed = client.delete(null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy delete configuration parameters, pass in null for defaults * @param key unique record identifier * @return whether record existed on server before deletion @@ -1201,6 +1459,16 @@ public final boolean delete(WritePolicy policy, Key key) *

* The policy specifies the command timeout. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.delete(eventLoop, null, null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results, pass in null for fire and forget @@ -1230,6 +1498,15 @@ public final void delete(EventLoop eventLoop, DeleteListener listener, WritePoli *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     BatchResults results = client.delete(null, null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param batchPolicy batch configuration parameters, pass in null for defaults * @param deletePolicy delete configuration parameters, pass in null for defaults * @param keys array of unique record identifiers @@ -1302,6 +1579,21 @@ public final BatchResults delete(BatchPolicy batchPolicy, BatchDeletePolicy dele *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     client.delete(eventLoop, (records, status) -> {
+	 *         for (BatchRecord r : records) {
+	 *             if (r.record != null) { // use r.key, r.record
+	 *             }
+	 *         }
+	 *     }, null, null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -1378,6 +1670,19 @@ public final void delete( *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1") };
+	 *     client.delete(eventLoop, (record) -> {
+	 *         if (record.record != null) { // use record.key
+	 *         }
+	 *     }, null, null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -1448,6 +1753,14 @@ public final void delete( * write new records after the server call returns because new records will have last update times * greater than the truncate cutoff (set at the time of truncate call). * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.truncate(null, "test", "set1", null);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy info command configuration parameters, pass in null for defaults * @param ns required namespace * @param set optional set name. Pass in null to delete all sets in namespace. @@ -1500,6 +1813,15 @@ public final void truncate(InfoPolicy policy, String ns, String set, Calendar be * If the record does not exist, it can't be created because the server deletes empty records. * Throw an exception if the record does not exist. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.touch(null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @throws AerospikeException if touch fails @@ -1529,6 +1851,16 @@ public final void touch(WritePolicy policy, Key key) *

* Fail if the record does not exist. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.touch(eventLoop, null, null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results, pass in null for fire and forget @@ -1557,6 +1889,15 @@ public final void touch(EventLoop eventLoop, WriteListener listener, WritePolicy * If the record does not exist, it can't be created because the server deletes empty records. * Return true if the record exists and is touched. Return false if the record does not exist. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     boolean ok = client.touched(null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @throws AerospikeException if touch fails @@ -1588,6 +1929,19 @@ public final boolean touched(WritePolicy policy, Key key) * If the record does not exist, send a value of false to * {@link com.aerospike.client.listener.ExistsListener#onSuccess(Key, boolean)} * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.touched(eventLoop, (k, exists) -> {
+	 *         if (exists) { // record was touched
+	 *         }
+	 *     }, null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results, pass in null for fire and forget @@ -1619,6 +1973,15 @@ public final void touched(EventLoop eventLoop, ExistsListener listener, WritePol * Determine if a record key exists. * The policy can be used to specify timeouts. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     boolean found = client.exists(null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier * @return whether record exists or not @@ -1648,6 +2011,19 @@ public final boolean exists(Policy policy, Key key) *

* The policy can be used to specify timeouts. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.exists(eventLoop, (k, exists) -> {
+	 *         if (exists) { // key exists
+	 *         }
+	 *     }, null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -1679,6 +2055,15 @@ public final void exists(EventLoop eventLoop, ExistsListener listener, Policy po * Check if multiple record keys exist in one batch call. * The returned boolean array is in positional order with the original key array order. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     boolean[] results = client.exists(null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @return array key/existence status pairs @@ -1734,6 +2119,21 @@ public final boolean[] exists(BatchPolicy policy, Key[] keys) *

* The returned boolean array is in positional order with the original key array order. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     client.exists(eventLoop, (keyArray, existsArray) -> {
+	 *         for (int i = 0; i < keyArray.length; i++) {
+	 *             if (existsArray[i]) { // keyArray[i] exists
+	 *             }
+	 *         }
+	 *     }, null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -1790,6 +2190,19 @@ public final void exists(EventLoop eventLoop, ExistsArrayListener listener, Batc *

* Each key's result is returned in separate onExists() calls. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1") };
+	 *     client.exists(eventLoop, (key, exists) -> {
+	 *         if (exists) { // key exists
+	 *         }
+	 *     }, null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -1846,6 +2259,16 @@ public final void exists(EventLoop eventLoop, ExistsSequenceListener listener, B * Read entire record for specified key. * The policy can be used to specify timeouts. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     Record rec = client.get(null, key);
+	 *     if (rec != null) { Object val = rec.getValue("name"); }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier * @return if found, return record instance. If not found, return null. @@ -1875,6 +2298,18 @@ public final Record get(Policy policy, Key key) *

* The policy can be used to specify timeouts. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.get(eventLoop, (keyResult, record) -> {
+	 *         if (record != null) { Object val = record.getValue("mybin"); }
+	 *     }, null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -1906,6 +2341,16 @@ public final void get(EventLoop eventLoop, RecordListener listener, Policy polic * Read record header and bins for specified key. * The policy can be used to specify timeouts. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     Record rec = client.get(null, key, "name", "age");
+	 *     if (rec != null) { String name = rec.getString("name"); }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier * @param binNames bins to retrieve @@ -1936,6 +2381,18 @@ public final Record get(Policy policy, Key key, String... binNames) *

* The policy can be used to specify timeouts. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.get(eventLoop, (keyResult, record) -> {
+	 *         if (record != null) { Object name = record.getValue("name"); Object age = record.getValue("age"); }
+	 *     }, null, key, "name", "age");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -1968,6 +2425,16 @@ public final void get(EventLoop eventLoop, RecordListener listener, Policy polic * Read record generation and expiration only for specified key. Bins are not read. * The policy can be used to specify timeouts. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     Record rec = client.getHeader(null, key);
+	 *     if (rec != null) { int gen = rec.generation; }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier * @return if found, return record instance. If not found, return null. @@ -1997,6 +2464,18 @@ public final Record getHeader(Policy policy, Key key) *

* The policy can be used to specify timeouts. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.getHeader(eventLoop, (keyResult, record) -> {
+	 *         if (record != null) { int gen = record.generation; int exp = record.expiration; }
+	 *     }, null, key);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2034,6 +2513,18 @@ public final void getHeader(EventLoop eventLoop, RecordListener listener, Policy * The returned records are located in the same list. * If the BatchRead key field is not found, the corresponding record field will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     List records = new ArrayList<>();
+	 *     records.add(new BatchRead(new Key("test", "set1", "id1")));
+	 *     records.add(new BatchRead(new Key("test", "set1", "id2"), "name"));
+	 *     boolean ok = client.get(null, records);
+	 *     for (BatchRead r : records) { Record rec = r.record; }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy batch configuration parameters, pass in null for defaults * @param records list of unique record identifiers and the bins to retrieve. * The returned records are located in the same list. @@ -2083,6 +2574,21 @@ public final boolean get(BatchPolicy policy, List records) * The returned records are located in the same list. * If the BatchRead key field is not found, the corresponding record field will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     List records = new ArrayList<>();
+	 *     records.add(new BatchRead(new Key("test", "set1", "id1")));
+	 *     client.get(eventLoop, (list) -> {
+	 *         for (BatchRecord r : list) { if (r.record != null) { // use r.key, r.record
+	 *             }
+	 *         }
+	 *     }, null, records);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2138,6 +2644,19 @@ public final void get(EventLoop eventLoop, BatchListListener listener, BatchPoli * Each record result is returned in separate onRecord() calls. * If the BatchRead key field is not found, the corresponding record field will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     List records = new ArrayList<>();
+	 *     records.add(new BatchRead(new Key("test", "set1", "id1")));
+	 *     client.get(eventLoop, (key, record) -> {
+	 *         if (record != null) { Object val = record.getValue("mybin"); }
+	 *     }, null, records);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2191,6 +2710,16 @@ public final void get(EventLoop eventLoop, BatchSequenceListener listener, Batch * The returned records are in positional order with the original key array order. * If a key is not found, the positional record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     Record[] records = client.get(null, keys);
+	 *     for (Record r : records) { if (r != null) { } }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @return array of records @@ -2248,6 +2777,24 @@ public final Record[] get(BatchPolicy policy, Key[] keys) * The returned records are in positional order with the original key array order. * If a key is not found, the positional record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     client.get(eventLoop, (keyArray, recordArray) -> {
+	 *         for (int i = 0; i < keyArray.length; i++) {
+	 *             Record rec = recordArray[i];
+	 *             if (rec != null) {
+	 *                 Object value = rec.getValue("mybin");
+	 *                 // use keyArray[i], value
+	 *             }
+	 *         }
+	 *     }, null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2305,6 +2852,18 @@ public final void get(EventLoop eventLoop, RecordArrayListener listener, BatchPo * Each record result is returned in separate onRecord() calls. * If a key is not found, the record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     client.get(eventLoop, (key, record) -> {
+	 *         if (record != null) { Object val = record.getValue("mybin"); }
+	 *     }, null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2358,6 +2917,15 @@ public final void get(EventLoop eventLoop, RecordSequenceListener listener, Batc * The returned records are in positional order with the original key array order. * If a key is not found, the positional record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     Record[] records = client.get(null, keys, "name", "age");
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @param binNames array of bins to retrieve @@ -2418,6 +2986,21 @@ public final Record[] get(BatchPolicy policy, Key[] keys, String... binNames) * The returned records are in positional order with the original key array order. * If a key is not found, the positional record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     client.get(eventLoop, (keyArray, recordArray) -> {
+	 *         for (int i = 0; i < keyArray.length; i++) {
+	 *             Record rec = recordArray[i];
+	 *             if (rec != null) { Object name = rec.getValue("name"); Object age = rec.getValue("age"); }
+	 *         }
+	 *     }, null, keys, "name", "age");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2479,6 +3062,18 @@ public final void get(EventLoop eventLoop, RecordArrayListener listener, BatchPo * Each record result is returned in separate onRecord() calls. * If a key is not found, the record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     client.get(eventLoop, (key, record) -> {
+	 *         if (record != null) { Object name = record.getValue("name"); Object age = record.getValue("age"); }
+	 *     }, null, keys, "name", "age");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2535,6 +3130,15 @@ public final void get(EventLoop eventLoop, RecordSequenceListener listener, Batc * The returned records are in positional order with the original key array order. * If a key is not found, the positional record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1") };
+	 *     Record[] records = client.get(null, keys, Operation.get("name"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @param ops array of read operations on record @@ -2592,6 +3196,21 @@ public final Record[] get(BatchPolicy policy, Key[] keys, Operation... ops) * The returned records are in positional order with the original key array order. * If a key is not found, the positional record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1") };
+	 *     client.get(eventLoop, (keyArray, recordArray) -> {
+	 *         for (int i = 0; i < keyArray.length; i++) {
+	 *             Record rec = recordArray[i];
+	 *             if (rec != null) { Object name = rec.getValue("name"); }
+	 *         }
+	 *     }, null, keys, Operation.get("name"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2650,6 +3269,18 @@ public final void get(EventLoop eventLoop, RecordArrayListener listener, BatchPo * Each record result is returned in separate onRecord() calls. * If a key is not found, the record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1") };
+	 *     client.get(eventLoop, (key, record) -> {
+	 *         if (record != null) { Object name = record.getValue("name"); }
+	 *     }, null, keys, Operation.get("name"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2703,6 +3334,15 @@ public final void get(EventLoop eventLoop, RecordSequenceListener listener, Batc * The returned records are in positional order with the original key array order. * If a key is not found, the positional record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     Record[] records = client.getHeader(null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @return array of records @@ -2760,6 +3400,21 @@ public final Record[] getHeader(BatchPolicy policy, Key[] keys) * The returned records are in positional order with the original key array order. * If a key is not found, the positional record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     client.getHeader(eventLoop, (keyArray, recordArray) -> {
+	 *         for (int i = 0; i < keyArray.length; i++) {
+	 *             Record rec = recordArray[i];
+	 *             if (rec != null) { int gen = rec.generation; int exp = rec.expiration; }
+	 *         }
+	 *     }, null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2818,6 +3473,18 @@ public final void getHeader(EventLoop eventLoop, RecordArrayListener listener, B * Each record result is returned in separate onRecord() calls. * If a key is not found, the record will be null. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     client.getHeader(eventLoop, (key, record) -> {
+	 *         if (record != null) { int gen = record.generation; int exp = record.expiration; }
+	 *     }, null, keys);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -2882,6 +3549,16 @@ public final void getHeader(EventLoop eventLoop, RecordSequenceListener listener * Operation results are stored with their associated bin name in the returned record. * The bin's result type will be a list when multiple operations occur on the same bin. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     Record rec = client.operate(null, key, Operation.add(new Bin("count", 1)), Operation.get("count"));
+	 *     if (rec != null) { long count = rec.getLong("count"); }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param operations database operations to perform @@ -2932,6 +3609,19 @@ public final Record operate(WritePolicy policy, Key key, Operation... operations * Operation results are stored with their associated bin name in the returned record. * The bin's result type will be a list when multiple operations occur on the same bin. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.operate(eventLoop, (keyResult, record) -> {
+	 *         if (record != null) { Object val = record.getValue("count"); }
+	 *     }, null, key,
+	 *         Operation.add(new Bin("count", 1)), Operation.get("count"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results, pass in null for fire and forget @@ -2981,6 +3671,17 @@ public final void operate(EventLoop eventLoop, RecordListener listener, WritePol *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     List records = new ArrayList<>();
+	 *     records.add(new BatchRead(new Key("test", "set1", "id1")));
+	 *     records.add(new BatchWrite(new Key("test", "set1", "id2"), new Bin("x", 1)));
+	 *     boolean ok = client.operate(null, records);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy batch configuration parameters, pass in null for defaults * @param records list of unique record identifiers and read/write operations * @return true if all batch sub-commands succeeded @@ -3102,6 +3803,17 @@ public final boolean operate(BatchPolicy policy, List records) *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     List records = new ArrayList<>();
+	 *     records.add(new BatchRead(new Key("test", "set1", "id1")));
+	 *     client.operate(eventLoop, (list, e) -> { if (e != null) throw new RuntimeException(e); }, null, records);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -3228,6 +3940,20 @@ public final void operate( *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     List records = new ArrayList<>();
+	 *     records.add(new BatchRead(new Key("test", "set1", "id1")));
+	 *     client.operate(eventLoop, (record) -> {
+	 *         if (record.record != null) { // use record.key, record.record
+	 *         }
+	 *     }, null, records);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -3351,6 +4077,15 @@ public final void operate( *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     BatchResults results = client.operate(null, null, keys, Operation.get("name"), Operation.get("age"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param batchPolicy batch configuration parameters, pass in null for defaults * @param writePolicy write configuration parameters, pass in null for defaults * @param keys array of unique record identifiers @@ -3438,6 +4173,22 @@ public final BatchResults operate( *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     client.operate(eventLoop, (records, status) -> {
+	 *         for (BatchRecord r : records) {
+	 *             if (r.record != null) { // use r.key, r.record
+	 *             }
+	 *         }
+	 *     }, null, null, keys,
+	 *         Operation.get("name"), Operation.get("age"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -3525,6 +4276,18 @@ public final void operate( *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1") };
+	 *     client.operate(eventLoop, (record) -> {
+	 *         if (record.record != null) { Object name = record.record.getValue("name"); }
+	 *     }, null, null, keys, Operation.get("name"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -3608,6 +4371,16 @@ public final void operate( * This call will block until the scan is complete - callbacks are made * within the scope of this call. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.scanAll(null, "test", "set1", (key, record) -> {
+	 *         Object name = record.getValue("name"); Object age = record.getValue("age");
+	 *     }, "name", "age");
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy scan configuration parameters, pass in null for defaults * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table @@ -3640,6 +4413,17 @@ public final void scanAll(ScanPolicy policy, String namespace, String setName, S * This method registers the command with an event loop and returns. * The event loop thread will process the command and send the results to the listener. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     client.scanAll(eventLoop, (key, record) -> {
+	 *         Object name = record.getValue("name");
+	 *     }, null, "test", "set1", "name");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -3676,6 +4460,17 @@ public final void scanAll(EventLoop eventLoop, RecordSequenceListener listener, * This call will block until the scan is complete - callbacks are made * within the scope of this call. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     String nodeName = client.getNodeNames().get(0);
+	 *     client.scanNode(null, nodeName, "test", "set1", (key, record) -> {
+	 *         Object val = record.getValue("mybin");
+	 *     });
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy scan configuration parameters, pass in null for defaults * @param nodeName server node name * @param namespace namespace - equivalent to database name @@ -3699,6 +4494,17 @@ public final void scanNode(ScanPolicy policy, String nodeName, String namespace, * This call will block until the scan is complete - callbacks are made * within the scope of this call. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Node node = client.getNodes()[0];
+	 *     client.scanNode(null, node, "test", "set1", (key, record) -> {
+	 *         Object val = record.getValue("mybin");
+	 *     });
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy scan configuration parameters, pass in null for defaults * @param node server node * @param namespace namespace - equivalent to database name @@ -3728,6 +4534,17 @@ public final void scanNode(ScanPolicy policy, Node node, String namespace, Strin * This call will block until the scan is complete - callbacks are made * within the scope of this call. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     PartitionFilter filter = PartitionFilter.range(0, 4095);
+	 *     client.scanPartitions(null, filter, "test", "set1", (key, record) -> {
+	 *         Object val = record.getValue("mybin");
+	 *     });
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy scan configuration parameters, pass in null for defaults * @param partitionFilter filter on a subset of data partitions * @param namespace namespace - equivalent to database name @@ -3759,6 +4576,18 @@ public final void scanPartitions(ScanPolicy policy, PartitionFilter partitionFil * This method registers the command with an event loop and returns. * The event loop thread will process the command and send the results to the listener. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getCluster().eventLoops.next();
+	 *     PartitionFilter filter = PartitionFilter.range(0, 4095);
+	 *     client.scanPartitions(eventLoop, (key, record) -> {
+	 *         Object val = record.getValue("mybin");
+	 *     }, null, filter, "test", "set1");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -3799,6 +4628,15 @@ public final void scanPartitions(EventLoop eventLoop, RecordSequenceListener lis * The user can optionally wait for command completion by using the returned * RegisterTask instance. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     RegisterTask task = client.register(null, "myudf.lua", "myudf.lua", Language.LUA);
+	 *     task.waitTillComplete();
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param clientPath path of client file containing user defined functions, relative to current directory * @param serverPath path to store user defined functions on the server, relative to configured script directory. @@ -3823,6 +4661,15 @@ public final RegisterTask register(Policy policy, String clientPath, String serv * The user can optionally wait for command completion by using the returned * RegisterTask instance. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     RegisterTask task = client.register(null, MyClass.class.getClassLoader(), "udf/mymodule.lua", "mymodule.lua", Language.LUA);
+	 *     task.waitTillComplete();
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param resourceLoader class loader where resource is located. Example: MyClass.class.getClassLoader() or Thread.currentThread().getContextClassLoader() for webapps * @param resourcePath class path where Lua resource is located @@ -3865,6 +4712,16 @@ public final RegisterTask register(Policy policy, ClassLoader resourceLoader, St * The user can optionally wait for command completion by using the returned * RegisterTask instance. * + *

Self-contained example: register a UDF from a string and wait for completion.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     String code = "function myfunc(rec) return rec['bin'] end\n";
+	 *     RegisterTask task = client.registerUdfString(null, code, "myudf.lua", Language.LUA);
+	 *     task.waitTillComplete();
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param code code string containing user defined functions. * @param serverPath path to store user defined functions on the server, relative to configured script directory. @@ -3885,6 +4742,14 @@ public final RegisterTask registerUdfString(Policy policy, String code, String s /** * Remove user defined function from server nodes. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.removeUdf(null, "myudf.lua");
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy info configuration parameters, pass in null for defaults * @param serverPath location of UDF on server nodes. Example: mylua.lua * @throws AerospikeException if remove fails @@ -3917,6 +4782,15 @@ public final void removeUdf(InfoPolicy policy, String serverPath) *

* {@code udf file = /.lua} * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     Object result = client.execute(null, key, "myudf", "myFunc", Value.get("arg1"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param packageName server package name where user defined function resides @@ -3977,6 +4851,19 @@ public final Object execute(WritePolicy policy, Key key, String packageName, Str *

* {@code udf file = /.lua} * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key key = new Key("test", "set1", "id1");
+	 *     client.execute(eventLoop, (key2, obj) -> {
+	 *         if (obj != null) { // use UDF return value
+	 *         }
+	 *     }, null, key, "myudf", "myFunc");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results, pass in null for fire and forget @@ -4018,6 +4905,16 @@ public final void execute( *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1"), new Key("test", "set1", "id2") };
+	 *     BatchResults results = client.execute(null, null, keys, "myudf", "myFunc");
+	 *     for (BatchRecord r : results) { // use r.record }
+	 * } finally { client.close(); }
+	 * }
+ * * @param batchPolicy batch configuration parameters, pass in null for defaults * @param udfPolicy udf configuration parameters, pass in null for defaults * @param keys array of unique record identifiers @@ -4103,6 +5000,20 @@ public final BatchResults execute( *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1") };
+	 *     client.execute(eventLoop, (records, status) -> {
+	 *         for (BatchRecord r : records) {
+	 *             if (r.record != null) { Object result = r.record.getValue("SUCCESS"); }
+	 *         }
+	 *     }, null, null, keys, "myudf", "myFunc");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -4188,6 +5099,18 @@ public final void execute( *

* Requires server version 6.0+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Key[] keys = new Key[] { new Key("test", "set1", "id1") };
+	 *     client.execute(eventLoop, (key, record) -> {
+	 *         if (record != null) { Object result = record.getValue("SUCCESS"); }
+	 *     }, null, null, keys, "myudf", "myFunc");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -4267,6 +5190,16 @@ public final void execute( * The user can optionally wait for command completion by using the returned * ExecuteTask instance. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     ExecuteTask task = client.execute(null, stmt, "myudf", "myFunc");
+	 *     task.waitTillComplete();
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param statement background query definition * @param packageName server package where user defined function resides @@ -4310,6 +5243,16 @@ public final ExecuteTask execute( * The user can optionally wait for command completion by using the returned * ExecuteTask instance. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     ExecuteTask task = client.execute(null, stmt, Operation.touch());
+	 *     task.waitTillComplete();
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy write configuration parameters, pass in null for defaults * @param statement background query definition * @param operations list of operations to be performed on selected records @@ -4359,6 +5302,20 @@ public final ExecuteTask execute( * For this case, use {@link #query(QueryPolicy, Statement, QueryListener)} which uses a listener * callback (without a buffer) instead of a RecordSet. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     try (RecordSet rs = client.query(null, stmt)) {
+	 *         while (rs.next()) {
+	 *             KeyRecord kr = rs.getKeyRecord();
+	 *             // use kr.key, kr.record
+	 *         }
+	 *     }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @return record iterator @@ -4393,6 +5350,18 @@ public final RecordSet query(QueryPolicy policy, Statement statement) *

* Each record result is returned in separate onRecord() calls. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     client.query(eventLoop, (key, record) -> {
+	 *         Object val = record.getValue("mybin");
+	 *     }, null, stmt);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -4433,6 +5402,17 @@ public final void query(EventLoop eventLoop, RecordSequenceListener listener, Qu *

* Requires server version 6.0+ if using a secondary index query. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     client.query(null, stmt, (key, record) -> {
+	 *         Object val = record.getValue("mybin");
+	 *     });
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @param listener where to send results @@ -4474,6 +5454,18 @@ public final void query( *

* Requires server version 6.0+ if using a secondary index query. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     PartitionFilter filter = PartitionFilter.all();
+	 *     client.query(null, stmt, filter, (key, record) -> {
+	 *         Object val = record.getValue("mybin");
+	 *     });
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @param partitionFilter data partition filter. Set to @@ -4509,6 +5501,18 @@ public final void query( * records on a queue in a separate thread. The calling thread concurrently pops records off * the queue through the record iterator. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Node node = client.getNodes()[0];
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     try (RecordSet rs = client.queryNode(null, stmt, node)) {
+	 *         while (rs.next()) { KeyRecord kr = rs.getKeyRecord(); }
+	 *     }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @param node server node to execute query @@ -4542,6 +5546,18 @@ public final RecordSet queryNode(QueryPolicy policy, Statement statement, Node n *

* Requires server version 6.0+ if using a secondary index query. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     PartitionFilter filter = PartitionFilter.all();
+	 *     try (RecordSet rs = client.queryPartitions(null, stmt, filter)) {
+	 *         while (rs.next()) { KeyRecord kr = rs.getKeyRecord(); }
+	 *     }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @param partitionFilter filter on a subset of data partitions @@ -4579,6 +5595,19 @@ public final RecordSet queryPartitions( *

* Requires server version 6.0+ if using a secondary index query. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     PartitionFilter filter = PartitionFilter.all();
+	 *     client.queryPartitions(eventLoop, (key, record) -> {
+	 *         Object val = record.getValue("mybin");
+	 *     }, null, stmt, filter);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -4626,6 +5655,17 @@ public final void queryPartitions( *

* {@code udf file = /.lua} * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     try (ResultSet rs = client.queryAggregate(null, stmt, "myudf", "myReduce")) {
+	 *         while (rs.next()) { Object val = rs.getObject(); }
+	 *     }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @param packageName server package where user defined function resides @@ -4655,6 +5695,18 @@ public final ResultSet queryAggregate( * The aggregation function is called on both server and client (final reduce). * Therefore, the Lua script file must also reside on both server and client. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     stmt.setAggregateFunction("myudf", "myReduce");
+	 *     try (ResultSet rs = client.queryAggregate(null, stmt)) {
+	 *         while (rs.next()) { Object val = rs.getObject(); }
+	 *     }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @throws AerospikeException if query fails @@ -4683,6 +5735,19 @@ public final ResultSet queryAggregate(QueryPolicy policy, Statement statement) * The aggregation function is called on both server and client (final reduce). * Therefore, the Lua script file must also reside on both server and client. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Node node = client.getNodes()[0];
+	 *     Statement stmt = new Statement("test", "set1");
+	 *     stmt.setAggregateFunction("myudf", "myReduce");
+	 *     try (ResultSet rs = client.queryAggregateNode(null, stmt, node)) {
+	 *         while (rs.next()) { Object val = rs.getObject(); }
+	 *     }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @param node server node to execute query @@ -4710,6 +5775,15 @@ public final ResultSet queryAggregateNode(QueryPolicy policy, Statement statemen * The user can optionally wait for command completion by using the returned * IndexTask instance. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     IndexTask task = client.createIndex(null, "test", "set1", "idx_bin1", "bin1", IndexType.STRING);
+	 *     task.waitTillComplete();
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table @@ -4735,6 +5809,16 @@ public final IndexTask createIndex( * The user can optionally wait for command completion by using the returned * IndexTask instance. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     IndexTask task = client.createIndex(null, "test", "set1", "idx_mapbin", "mapbin",
+	 *         IndexType.STRING, IndexCollectionType.MAPKEYS);
+	 *     task.waitTillComplete();
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table @@ -4780,6 +5864,16 @@ public final IndexTask createIndex( * This method registers the command with an event loop and returns. * The event loop thread will process the command and send the results to the listener. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     client.createIndex(eventLoop, (task) -> { }, null, "test", "set1", "idx_mapbin", "mapbin",
+	 *         IndexType.STRING, IndexCollectionType.MAPKEYS);
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -4825,6 +5919,17 @@ public final void createIndex( * The user can optionally wait for command completion by using the returned * IndexTask instance. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Expression exp = Exp.build(Exp.eq(Exp.stringBin("tag"), Exp.val("active")));
+	 *     IndexTask task = client.createIndex(null, "test", "set1", "idx_expr", IndexType.STRING,
+	 *         IndexCollectionType.DEFAULT, exp);
+	 *     task.waitTillComplete();
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table @@ -4869,6 +5974,17 @@ public final IndexTask createIndex( * The user can optionally wait for command completion by using the returned * IndexTask instance. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Expression exp = Exp.build(Exp.eq(Exp.stringBin("tag"), Exp.val("active")));
+	 *     client.createIndex(eventLoop, (task) -> { }, null, "test", "set1", "idx_expr", IndexType.STRING,
+	 *         IndexCollectionType.DEFAULT, exp);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table @@ -4910,6 +6026,15 @@ public final void createIndex( * The user can optionally wait for command completion by using the returned * IndexTask instance. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     IndexTask task = client.dropIndex(null, "test", "set1", "idx_bin1");
+	 *     task.waitTillComplete();
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy generic configuration parameters, pass in null for defaults * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table @@ -4946,6 +6071,17 @@ public final IndexTask dropIndex( * This method registers the command with an event loop and returns. * The event loop thread will process the command and send the results to the listener. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     client.dropIndex(eventLoop, (task) -> {
+	 *         // task.isDone() to poll completion
+	 *     }, null, "test", "set1", "idx_bin1");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -4992,6 +6128,18 @@ public final void dropIndex( * The list of supported info commands can be found at: * https://www.aerospike.com/docs/reference/info/index.html * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     EventLoop eventLoop = client.getEventLoops().next();
+	 *     Node node = client.getNodes()[0];
+	 *     client.info(eventLoop, (map) -> {
+	 *         String build = map.get("build"); String stats = map.get("statistics");
+	 *     }, null, node, "build", "statistics");
+	 * } finally { client.close(); }
+	 * }
+ * * @param eventLoop event loop that will process the command. If NULL, the event * loop will be chosen by round-robin. * @param listener where to send results @@ -5032,6 +6180,14 @@ public final void info( * which records XDR should ship to the datacenter. If the expression filter is null, the * XDR filter will be removed. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.setXDRFilter(null, "DC1", "test", null);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy info configuration parameters, pass in null for defaults * @param datacenter XDR datacenter name * @param namespace namespace - equivalent to database name @@ -5070,6 +6226,14 @@ public final void setXDRFilter( * Create user with password and roles. Clear-text password will be hashed using bcrypt * before sending to server. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.createUser(null, "newuser", "password", java.util.Arrays.asList("read-write"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param user user name * @param password user password in clear-text format @@ -5087,6 +6251,14 @@ public final void createUser(AdminPolicy policy, String user, String password, L * Create PKI user with roles. PKI users are authenticated via TLS and a certificate instead of a password. * WARNING: This function should only be called for server versions 8.1+ * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.createPkiUser(null, "pkiuser", java.util.Arrays.asList("read-write"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param user user name * @param roles variable arguments array of role names. Predefined roles are listed in {@link com.aerospike.client.admin.Role} @@ -5101,6 +6273,14 @@ public final void createPkiUser(AdminPolicy policy, String user, List ro /** * Remove user from cluster. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.dropUser(null, "olduser");
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param user user name * @throws AerospikeException if command fails @@ -5114,6 +6294,14 @@ public final void dropUser(AdminPolicy policy, String user) /** * Change user's password. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.changePassword(null, "myuser", "newpassword");
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param user user name * @param password user password in clear-text format @@ -5147,6 +6335,14 @@ public final void changePassword(AdminPolicy policy, String user, String passwor /** * Add roles to user's list of roles. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.grantRoles(null, "myuser", java.util.Arrays.asList("read-write-udf"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param user user name * @param roles role names. Predefined roles are listed in {@link com.aerospike.client.admin.Role} @@ -5161,6 +6357,14 @@ public final void grantRoles(AdminPolicy policy, String user, List roles /** * Remove roles from user's list of roles. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.revokeRoles(null, "myuser", java.util.Arrays.asList("read-write-udf"));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param user user name * @param roles role names. Predefined roles are listed in {@link com.aerospike.client.admin.Role} @@ -5175,6 +6379,15 @@ public final void revokeRoles(AdminPolicy policy, String user, List role /** * Create user defined role. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Privilege p = new Privilege(); p.code = PrivilegeCode.READ; p.namespace = "test"; p.setName = "set1";
+	 *     client.createRole(null, "myrole", java.util.Collections.singletonList(p));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param privileges privileges assigned to the role. @@ -5189,6 +6402,17 @@ public final void createRole(AdminPolicy policy, String roleName, ListExample demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Privilege p = new Privilege(); p.code = PrivilegeCode.READ; p.namespace = "test";
+	 *     java.util.List privs = java.util.Collections.singletonList(p);
+	 *     java.util.List allowIps = java.util.Arrays.asList("10.1.2.0/24");
+	 *     client.createRole(null, "myrole", privs, allowIps);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param privileges optional list of privileges assigned to role. @@ -5206,6 +6430,17 @@ public final void createRole(AdminPolicy policy, String roleName, ListExample demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Privilege p = new Privilege(); p.code = PrivilegeCode.READ_WRITE; p.namespace = "test";
+	 *     java.util.List privs = java.util.Collections.singletonList(p);
+	 *     java.util.List allowIps = java.util.Arrays.asList("10.1.2.0/24");
+	 *     client.createRole(null, "myrole", privs, allowIps, 1000, 500);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param privileges optional list of privileges assigned to role. @@ -5230,6 +6465,14 @@ public final void createRole( /** * Drop user defined role. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.dropRole(null, "myrole");
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @throws AerospikeException if command fails @@ -5243,6 +6486,15 @@ public final void dropRole(AdminPolicy policy, String roleName) /** * Grant privileges to an user defined role. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Privilege p = new Privilege(); p.code = PrivilegeCode.READ_WRITE_UDF; p.namespace = "test";
+	 *     client.grantPrivileges(null, "myrole", java.util.Collections.singletonList(p));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param privileges privileges assigned to the role. @@ -5257,6 +6509,15 @@ public final void grantPrivileges(AdminPolicy policy, String roleName, ListExample demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Privilege p = new Privilege(); p.code = PrivilegeCode.READ_WRITE_UDF; p.namespace = "test";
+	 *     client.revokePrivileges(null, "myrole", java.util.Collections.singletonList(p));
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param privileges privileges assigned to the role. @@ -5271,6 +6532,15 @@ public final void revokePrivileges(AdminPolicy policy, String roleName, ListExample demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     java.util.List allowIps = java.util.Arrays.asList("10.1.2.0/24", "192.168.1.0/24");
+	 *     client.setWhitelist(null, "myrole", allowIps);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param whitelist list of allowable IP addresses or null. @@ -5287,6 +6557,14 @@ public final void setWhitelist(AdminPolicy policy, String roleName, List * Set maximum reads/writes per second limits for a role. If a quota is zero, the limit is removed. * Quotas require server security configuration "enable-quotas" to be set to true. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     client.setQuotas(null, "myrole", 1000, 500);
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param readQuota maximum reads per second limit, pass in zero for no limit. @@ -5302,6 +6580,15 @@ public final void setQuotas(AdminPolicy policy, String roleName, int readQuota, /** * Retrieve roles for a given user. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     User u = client.queryUser(null, "myuser");
+	 *     // use u.getRoles(), u.getConnections(), etc.
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param user user name filter * @throws AerospikeException if command fails @@ -5315,6 +6602,15 @@ public final User queryUser(AdminPolicy policy, String user) /** * Retrieve all users and their roles. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     java.util.List users = client.queryUsers(null);
+	 *     for (User u : users) { // u.getName(), u.getRoles() }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @throws AerospikeException if command fails */ @@ -5327,6 +6623,15 @@ public final List queryUsers(AdminPolicy policy) /** * Retrieve role definition. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     Role r = client.queryRole(null, "read-write");
+	 *     // use r.getPrivileges(), r.getWhitelist(), etc.
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name filter * @throws AerospikeException if command fails @@ -5340,6 +6645,15 @@ public final Role queryRole(AdminPolicy policy, String roleName) /** * Retrieve all roles. * + *

Example demonstrating usage of this method.

+ *
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * try {
+	 *     java.util.List roles = client.queryRoles(null);
+	 *     for (Role r : roles) { // r.getName(), r.getPrivileges() }
+	 * } finally { client.close(); }
+	 * }
+ * * @param policy admin configuration parameters, pass in null for defaults * @throws AerospikeException if command fails */ diff --git a/client/src/com/aerospike/client/AerospikeException.java b/client/src/com/aerospike/client/AerospikeException.java index b8bf673ff..047aafaee 100644 --- a/client/src/com/aerospike/client/AerospikeException.java +++ b/client/src/com/aerospike/client/AerospikeException.java @@ -23,7 +23,33 @@ import java.util.List; /** - * Aerospike exceptions that can be thrown from the client. + * Base exception thrown by the Aerospike client when a database command fails or a client-side error occurs. + * + *

Subclasses represent specific failure modes (e.g. {@link Timeout}, {@link Connection}, + * {@link InvalidNode}). Use {@link #getResultCode()} to get the numeric result code and + * {@link #getBaseMessage()} for the message without connection metadata. + * + *

Handle Timeout and generic AerospikeException; use getResultCode() and getInDoubt().

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * try {
+ *     client.get(policy, key);
+ * } catch (AerospikeException.Timeout e) {
+ *     // Client or server timeout
+ *     Policy p = e.getPolicy();
+ *     log.warn("Timeout after {} ms", p != null ? p.totalTimeout : 0);
+ * } catch (AerospikeException e) {
+ *     int code = e.getResultCode();
+ *     if (e.getInDoubt()) {
+ *         // Write may have completed; decide whether to retry
+ *     }
+ *     throw e;
+ * }
+ * }
+ * + * @see #getResultCode() + * @see #getBaseMessage() + * @see ResultCode */ public class AerospikeException extends RuntimeException { private static final long serialVersionUID = 1L; @@ -35,40 +61,86 @@ public class AerospikeException extends RuntimeException { protected int iteration = -1; protected boolean inDoubt; + /** + * Constructs an exception with the given result code and message. + * + * @param resultCode the Aerospike result code (e.g. from {@link ResultCode}) + * @param message the detail message; may be {@code null} + */ public AerospikeException(int resultCode, String message) { super(message); this.resultCode = resultCode; } + /** + * Constructs an exception with the given result code and cause. + * + * @param resultCode the Aerospike result code (e.g. from {@link ResultCode}) + * @param e the cause; may be {@code null} + */ public AerospikeException(int resultCode, Throwable e) { super(e); this.resultCode = resultCode; } + /** + * Constructs an exception with the given result code and no message. + * + * @param resultCode the Aerospike result code (e.g. from {@link ResultCode}) + */ public AerospikeException(int resultCode) { super(); this.resultCode = resultCode; } + /** + * Constructs an exception with the given result code and in-doubt flag. + * + * @param resultCode the Aerospike result code (e.g. from {@link ResultCode}) + * @param inDoubt whether the write may have completed on the server + */ public AerospikeException(int resultCode, boolean inDoubt) { super(); this.resultCode = resultCode; this.inDoubt = inDoubt; } + /** + * Constructs an exception with the given result code, message, and cause. + * + * @param resultCode the Aerospike result code (e.g. from {@link ResultCode}) + * @param message the detail message; may be {@code null} + * @param e the cause; may be {@code null} + */ public AerospikeException(int resultCode, String message, Throwable e) { super(message, e); this.resultCode = resultCode; } + /** + * Constructs an exception with the given message and cause (result code remains {@link ResultCode#CLIENT_ERROR}). + * + * @param message the detail message; may be {@code null} + * @param e the cause; may be {@code null} + */ public AerospikeException(String message, Throwable e) { super(message, e); } + /** + * Constructs an exception with the given message (result code remains {@link ResultCode#CLIENT_ERROR}). + * + * @param message the detail message; may be {@code null} + */ public AerospikeException(String message) { super(message); } + /** + * Constructs an exception with the given cause (result code remains {@link ResultCode#CLIENT_ERROR}). + * + * @param e the cause; may be {@code null} + */ public AerospikeException(Throwable e) { super(e); } @@ -121,7 +193,12 @@ public String getMessage() { } /** - * Return base message without extra metadata. + * Returns the exception message without connection or policy metadata. + * + *

Use this for user-facing or log messages when the full {@link #getMessage()} output + * is too verbose. + * + * @return the base message, or the result code string from {@link ResultCode} if the message is {@code null} */ public String getBaseMessage() { String message = super.getMessage(); @@ -129,86 +206,117 @@ public String getBaseMessage() { } /** - * Should connection be put back into pool. + * Indicates whether the connection that was in use for the failed command should be returned to the pool. + * + *

Some result codes indicate a bad connection; in those cases this returns {@code false}. + * + * @return {@code true} if the connection can be reused, {@code false} if it should be discarded */ public final boolean keepConnection() { return ResultCode.keepConnection(resultCode); } /** - * Get last node used. + * Returns the cluster node that was used for the command when the exception occurred. + * + * @return the node, or {@code null} if not set */ public final Node getNode() { return node; } /** - * Set last node used. + * Sets the cluster node associated with this exception. + * + * @param node the node; may be {@code null} */ public final void setNode(Node node) { this.node = node; } /** - * Get command policy. Will be null for non-command exceptions. + * Returns the policy used for the command that failed, when applicable. + * + * @return the policy, or {@code null} for non-command exceptions */ public final Policy getPolicy() { return policy; } /** - * Set command policy. + * Sets the policy associated with this exception. + * + * @param policy the policy; may be {@code null} */ public final void setPolicy(Policy policy) { this.policy = policy; } /** - * Get sub exceptions. Will be null if a retry did not occur. + * Returns the list of exceptions from individual retry attempts, when retries were performed. + * + * @return the list of sub-exceptions, or {@code null} if no retry occurred */ public final List getSubExceptions() { return subExceptions; } /** - * Set sub exceptions. + * Sets the list of exceptions from individual retry attempts. + * + * @param subExceptions the list of sub-exceptions; may be {@code null} */ public final void setSubExceptions(List subExceptions) { this.subExceptions = subExceptions; } /** - * Get integer result code. + * Returns the Aerospike result code for this exception. + * + * @return the result code (e.g. from {@link ResultCode}) */ public final int getResultCode() { return resultCode; } /** - * Get number of attempts before failing. + * Returns the number of command attempts made before the failure. + * + * @return the attempt count, or -1 if not set */ public final int getIteration() { return iteration; } /** - * Set number of attempts before failing. + * Sets the number of command attempts made before the failure. + * + * @param iteration the attempt count (e.g. 1 for first attempt) */ public final void setIteration(int iteration) { this.iteration = iteration; } /** - * Is it possible that write command may have completed. + * Indicates whether the write command may have completed on the server despite this exception. + * + *

When {@code true}, a timeout or connection error may have occurred after the write was + * applied; callers should decide whether to retry or treat as success based on idempotency. + * + * @return {@code true} if the write might have completed, {@code false} otherwise */ public final boolean getInDoubt() { return inDoubt; } /** - * Set whether it is possible that the write command may have completed - * even though this exception was generated. This may be the case when a - * client error occurs (like timeout) after the command was sent to the server. + * Sets the in-doubt flag based on whether this was a write and whether the command was sent. + * + *

The in-doubt flag is set when a client error (e.g. timeout) occurs after the command + * was sent to the server, so the write may have completed. + * + * @param isWrite {@code true} if the command was a write + * @param commandSentCounter number of times the command was sent (e.g. 1 for single send) */ public final void setInDoubt(boolean isWrite, int commandSentCounter) { if (isWrite && (commandSentCounter > 1 || (commandSentCounter == 1 && (resultCode == ResultCode.TIMEOUT || resultCode <= 0)))) { @@ -217,41 +325,57 @@ public final void setInDoubt(boolean isWrite, int commandSentCounter) { } /** - * Sets the inDoubt value to inDoubt. + * Sets whether the write command may have completed on the server. + * + * @param inDoubt {@code true} if the write might have completed, {@code false} otherwise */ public void setInDoubt(boolean inDoubt) { this.inDoubt = inDoubt; } /** - * Exception thrown when database request expires before completing. + * Thrown when a database request does not complete within the configured timeout. + * + *

Use {@link #client} to distinguish client-side timeouts from server-initiated timeouts. + * The policy timeouts are available via {@link #getPolicy()} or the redundant fields + * {@link #connectTimeout}, {@link #socketTimeout}, and {@link #timeout} for backward compatibility. + * + * @see #getPolicy() */ public static final class Timeout extends AerospikeException { private static final long serialVersionUID = 1L; /** - * Socket initial connect timeout in milliseconds. - * This field is redundant and is only left here for backwards compatibility. + * Socket initial connect timeout in milliseconds. Redundant with {@link Policy#connectTimeout}; + * retained for backward compatibility. */ public int connectTimeout; /** - * Socket idle timeout in milliseconds. - * This field is redundant and is only left here for backwards compatibility. + * Socket idle timeout in milliseconds. Redundant with {@link Policy#socketTimeout}; + * retained for backward compatibility. */ public int socketTimeout; /** - * Total timeout in milliseconds. - * This field is redundant and is only left here for backwards compatibility. + * Total timeout in milliseconds. Redundant with {@link Policy#totalTimeout}; + * retained for backward compatibility. */ public int timeout; /** - * If true, client initiated timeout. If false, server initiated timeout. + * {@code true} if the client enforced the timeout; {@code false} if the server reported a timeout. */ public boolean client; + /** + * Constructs a client timeout with the given message and metadata. + * + * @param message the detail message; may be {@code null} + * @param iteration the attempt count + * @param totalTimeout total timeout in milliseconds + * @param inDoubt whether the write may have completed + */ public Timeout(String message, int iteration, int totalTimeout, boolean inDoubt) { super(ResultCode.TIMEOUT, message); super.iteration = iteration; @@ -270,6 +394,12 @@ public Timeout(String message, int iteration, int totalTimeout, boolean inDoubt) this.client = true; } + /** + * Constructs a timeout with the policy that was used and whether it was client or server initiated. + * + * @param policy the command policy; used to populate timeout fields + * @param client {@code true} for client timeout, {@code false} for server timeout + */ public Timeout(Policy policy, boolean client) { // Other base exception fields are set after this constructor. super(ResultCode.TIMEOUT, (client ? "Client" : "Server") + " timeout"); @@ -280,6 +410,12 @@ public Timeout(Policy policy, boolean client) { this.client = client; } + /** + * Constructs a client timeout with the given policy and attempt count. + * + * @param policy the command policy; used to populate timeout fields + * @param iteration the attempt count + */ public Timeout(Policy policy, int iteration) { super(ResultCode.TIMEOUT, "Client timeout"); super.policy = policy; @@ -290,6 +426,14 @@ public Timeout(Policy policy, int iteration) { this.client = true; } + /** + * Constructs a client timeout with the node and timeout values. + * + * @param node the node that was used + * @param connectTimeout connect timeout in milliseconds + * @param socketTimeout socket idle timeout in milliseconds + * @param totalTimeout total timeout in milliseconds + */ public Timeout(Node node, int connectTimeout, int socketTimeout, int totalTimeout) { super(ResultCode.TIMEOUT, "Client timeout"); super.node = node; @@ -310,81 +454,149 @@ public Timeout(Node node, int connectTimeout, int socketTimeout, int totalTimeou } /** - * Exception thrown when a Java serialization error occurs. + * Thrown when a Java serialization error occurs while serializing or deserializing data. + * + * @see ResultCode#SERIALIZE_ERROR */ public static final class Serialize extends AerospikeException { private static final long serialVersionUID = 1L; + /** + * Constructs a serialize exception with the given cause. + * + * @param e the cause; may be {@code null} + */ public Serialize(Throwable e) { super(ResultCode.SERIALIZE_ERROR, "Serialize error", e); } + /** + * Constructs a serialize exception with the given message. + * + * @param message the detail message; may be {@code null} + */ public Serialize(String message) { super(ResultCode.SERIALIZE_ERROR, message); } } /** - * Exception thrown when client can't parse data returned from server. + * Thrown when the client cannot parse data returned from the server. + * + * @see ResultCode#PARSE_ERROR */ public static final class Parse extends AerospikeException { private static final long serialVersionUID = 1L; + /** + * Constructs a parse exception with the given message. + * + * @param message the detail message; may be {@code null} + */ public Parse(String message) { super(ResultCode.PARSE_ERROR, message); } } /** - * Exception thrown when client can't connect to the server. + * Thrown when the client cannot connect to the server (e.g. host unreachable, connection refused). + * + * @see ResultCode#SERVER_NOT_AVAILABLE */ public static final class Connection extends AerospikeException { private static final long serialVersionUID = 1L; + /** + * Constructs a connection exception with the given message. + * + * @param message the detail message; may be {@code null} + */ public Connection(String message) { super(ResultCode.SERVER_NOT_AVAILABLE, message); } + /** + * Constructs a connection exception with the given cause. + * + * @param e the cause; may be {@code null} + */ public Connection(Throwable e) { super(ResultCode.SERVER_NOT_AVAILABLE, "Connection failed", e); } + /** + * Constructs a connection exception with the given message and cause. + * + * @param message the detail message; may be {@code null} + * @param e the cause; may be {@code null} + */ public Connection(String message, Throwable e) { super(ResultCode.SERVER_NOT_AVAILABLE, message, e); } + /** + * Constructs a connection exception with the given result code and message. + * + * @param resultCode the result code + * @param message the detail message; may be {@code null} + */ public Connection(int resultCode, String message) { super(resultCode, message); } } /** - * Exception thrown when the selected node is not active, or when the namespace - * is removed after the client has connected. + * Thrown when the selected node is not active, or when the namespace is removed after the client has connected. + * + * @see ResultCode#INVALID_NODE_ERROR */ public static final class InvalidNode extends AerospikeException { private static final long serialVersionUID = 1L; + /** + * Constructs an invalid-node exception for the given cluster size and partition. + * + * @param clusterSize current cluster size (0 implies "cluster is empty") + * @param partition the partition that had no node + */ public InvalidNode(int clusterSize, Partition partition) { super(ResultCode.INVALID_NODE_ERROR, (clusterSize == 0) ? "Cluster is empty" : "Node not found for partition " + partition); } + /** + * Constructs an invalid-node exception for the given partition ID. + * + * @param partitionId the partition that had no node + */ public InvalidNode(int partitionId) { super(ResultCode.INVALID_NODE_ERROR, "Node not found for partition " + partitionId); } + /** + * Constructs an invalid-node exception with the given message. + * + * @param message the detail message; may be {@code null} + */ public InvalidNode(String message) { super(ResultCode.INVALID_NODE_ERROR, message); } } /** - * Exception thrown when namespace is invalid. + * Thrown when the namespace is invalid or not found in the partition map. + * + * @see ResultCode#INVALID_NAMESPACE */ public static final class InvalidNamespace extends AerospikeException { private static final long serialVersionUID = 1L; + /** + * Constructs an invalid-namespace exception for the given namespace and map size. + * + * @param ns the namespace name + * @param mapSize partition map size (0 implies "partition map empty") + */ public InvalidNamespace(String ns, int mapSize) { super(ResultCode.INVALID_NAMESPACE, (mapSize == 0) ? "Partition map empty" : "Namespace not found in partition map: " + ns); @@ -392,13 +604,24 @@ public InvalidNamespace(String ns, int mapSize) { } /** - * Exception thrown when a batch exists method fails. + * Thrown when a batch exists operation fails; partial results are available in {@link #exists}. + * + * @see ResultCode#BATCH_FAILED */ public static final class BatchExists extends AerospikeException { private static final long serialVersionUID = 1L; + /** + * Existence result for each key in the batch; one entry per key in request order. + */ public final boolean[] exists; + /** + * Constructs a batch-exists exception with the partial results and cause. + * + * @param exists existence result per key; may be {@code null} + * @param e the cause; may be {@code null} + */ public BatchExists(boolean[] exists, Throwable e) { super(ResultCode.BATCH_FAILED, "Batch failed", e); this.exists = exists; @@ -406,15 +629,26 @@ public BatchExists(boolean[] exists, Throwable e) { } /** - * Exception thrown when a batch read method fails. - * The records fields contains responses for key requests that succeeded and null - * records for key requests that failed. + * Thrown when a batch read operation fails; partial results are available in {@link #records}. + * + *

Each element corresponds to one key: non-null for succeeded requests, {@code null} for failed ones. + * + * @see ResultCode#BATCH_FAILED */ public static final class BatchRecords extends AerospikeException { private static final long serialVersionUID = 1L; + /** + * Record result for each key in the batch; {@code null} entries indicate failed keys. + */ public final Record[] records; + /** + * Constructs a batch-records exception with the partial results and cause. + * + * @param records record per key; {@code null} entries for failures; may be {@code null} + * @param e the cause; may be {@code null} + */ public BatchRecords(Record[] records, Throwable e) { super(ResultCode.BATCH_FAILED, "Batch failed", e); this.records = records; @@ -422,20 +656,38 @@ public BatchRecords(Record[] records, Throwable e) { } /** - * Exception thrown when a batch write method fails. - * The records fields contains responses for key requests that succeeded - * and resultCodes for key requests that failed. + * Thrown when a batch write operation fails; partial results are available in {@link #records}. + * + *

Each {@link BatchRecord} contains the result code and optional record for that key. + * + * @see ResultCode#BATCH_FAILED */ public static final class BatchRecordArray extends AerospikeException { private static final long serialVersionUID = 1L; + /** + * Result for each key in the batch; each element has result code and optional record. + */ public final BatchRecord[] records; + /** + * Constructs a batch-record-array exception with the partial results and cause. + * + * @param records result per key; may be {@code null} + * @param e the cause; may be {@code null} + */ public BatchRecordArray(BatchRecord[] records, Throwable e) { super(ResultCode.BATCH_FAILED, "Batch failed", e); this.records = records; } + /** + * Constructs a batch-record-array exception with the given message and cause. + * + * @param records result per key; may be {@code null} + * @param message the detail message; may be {@code null} + * @param e the cause; may be {@code null} + */ public BatchRecordArray(BatchRecord[] records, String message, Throwable e) { super(ResultCode.BATCH_FAILED, message, e); this.records = records; @@ -443,61 +695,87 @@ public BatchRecordArray(BatchRecord[] records, String message, Throwable e) { } /** - * Exception thrown when scan was terminated prematurely. + * Thrown when a scan was terminated before completion (e.g. by the user or due to an error). + * + * @see ResultCode#SCAN_TERMINATED */ public static final class ScanTerminated extends AerospikeException { private static final long serialVersionUID = 1L; + /** Constructs a scan-terminated exception with no message. */ public ScanTerminated() { super(ResultCode.SCAN_TERMINATED); } + /** + * Constructs a scan-terminated exception with the given cause. + * + * @param e the cause; may be {@code null} + */ public ScanTerminated(Throwable e) { super(ResultCode.SCAN_TERMINATED, "Scan terminated", e); } } /** - * Exception thrown when query was terminated prematurely. + * Thrown when a query was terminated before completion (e.g. by the user or due to an error). + * + * @see ResultCode#QUERY_TERMINATED */ public static final class QueryTerminated extends AerospikeException { private static final long serialVersionUID = 1L; + /** Constructs a query-terminated exception with no message. */ public QueryTerminated() { super(ResultCode.QUERY_TERMINATED); } + /** + * Constructs a query-terminated exception with the given cause. + * + * @param e the cause; may be {@code null} + */ public QueryTerminated(Throwable e) { super(ResultCode.QUERY_TERMINATED, "Query terminated", e); } } /** - * Exception thrown when async command was rejected because the - * async delay queue is full. + * Thrown when an async command was rejected because the async delay queue is full. + * + * @see ResultCode#ASYNC_QUEUE_FULL */ public static final class AsyncQueueFull extends Backoff { private static final long serialVersionUID = 1L; + /** Constructs an async-queue-full exception. */ public AsyncQueueFull() { super(ResultCode.ASYNC_QUEUE_FULL); } } /** - * Exception thrown when node is in backoff mode due to excessive - * number of errors. + * Thrown when a node is in backoff mode due to an excessive error rate (e.g. circuit breaker open). + * + * @see AerospikeException.AsyncQueueFull */ public static class Backoff extends AerospikeException { private static final long serialVersionUID = 1L; + /** + * Constructs a backoff exception with the given result code. + * + * @param resultCode the result code (e.g. {@link ResultCode#ASYNC_QUEUE_FULL}) + */ public Backoff(int resultCode) { super(resultCode); } } /** - * Exception thrown when a transaction commit fails. + * Thrown when a transaction commit fails; details are in {@link #error}, {@link #verifyRecords}, and {@link #rollRecords}. + * + * @see ResultCode#TXN_FAILED */ public static final class Commit extends AerospikeException { private static final long serialVersionUID = 1L; @@ -508,17 +786,22 @@ public static final class Commit extends AerospikeException { public final CommitError error; /** - * Verify result for each read key in the transaction. May be null if failure occurred - * before verify. + * Verify result for each read key in the transaction; {@code null} if failure occurred before verify. */ public final BatchRecord[] verifyRecords; /** - * Roll forward/backward result for each write key in the transaction. May be null if - * failure occurred before roll forward/backward. + * Roll forward/backward result for each write key; {@code null} if failure occurred before roll. */ public final BatchRecord[] rollRecords; + /** + * Constructs a commit exception with the given error and partial results. + * + * @param error the commit error status + * @param verifyRecords verify result per read key; may be {@code null} + * @param rollRecords roll result per write key; may be {@code null} + */ public Commit(CommitError error, BatchRecord[] verifyRecords, BatchRecord[] rollRecords) { super(ResultCode.TXN_FAILED, error.str); this.error = error; @@ -526,6 +809,14 @@ public Commit(CommitError error, BatchRecord[] verifyRecords, BatchRecord[] roll this.rollRecords = rollRecords; } + /** + * Constructs a commit exception with the given error, partial results, and cause. + * + * @param error the commit error status + * @param verifyRecords verify result per read key; may be {@code null} + * @param rollRecords roll result per write key; may be {@code null} + * @param cause the cause; may be {@code null} + */ public Commit(CommitError error, BatchRecord[] verifyRecords, BatchRecord[] rollRecords, Throwable cause) { super(ResultCode.TXN_FAILED, error.str, cause); this.error = error; diff --git a/client/src/com/aerospike/client/BatchDelete.java b/client/src/com/aerospike/client/BatchDelete.java index 931babd94..de1ccb436 100644 --- a/client/src/com/aerospike/client/BatchDelete.java +++ b/client/src/com/aerospike/client/BatchDelete.java @@ -23,7 +23,23 @@ import com.aerospike.client.policy.Policy; /** - * Batch delete operation. + * Batch delete operation. Extends {@link BatchRecord}; each record specifies a key and optional + * {@link BatchDeletePolicy}. Pass a list of {@code BatchDelete} to + * {@link IAerospikeClient#delete}. + *

Build a list of BatchDelete with keys, then call delete.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * List<BatchRecord> records = new ArrayList<>();
+ * records.add(new BatchDelete(new Key("test", "set1", "id1")));
+ * records.add(new BatchDelete(new Key("test", "set1", "id2")));
+ * client.delete(new BatchPolicy(), records);
+ * for (BatchRecord br : records) {
+ *   if (br.resultCode == ResultCode.OK) { /* delete succeeded *\/ }
+ * }
+ * }
+ * + * @see BatchRecord + * @see IAerospikeClient#delete */ public final class BatchDelete extends BatchRecord { /** diff --git a/client/src/com/aerospike/client/BatchRead.java b/client/src/com/aerospike/client/BatchRead.java index c9454171f..684c3c785 100644 --- a/client/src/com/aerospike/client/BatchRead.java +++ b/client/src/com/aerospike/client/BatchRead.java @@ -23,8 +23,24 @@ import com.aerospike.client.policy.Policy; /** - * Batch key and read only operations with default policy. - * Used in batch read commands where different bins are needed for each key. + * Batch key and read-only operations with optional per-key policy. Extends {@link BatchRecord}; + * used in batch read commands where different bins or operations are needed for each key. + * Pass a list of {@code BatchRead} to {@link IAerospikeClient#get}. + *

Build a list of BatchRead with keys and bin names or operations, then call get.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * List<BatchRecord> records = new ArrayList<>();
+ * records.add(new BatchRead(new Key("test", "set1", "id1"), new String[] {"a", "b"}));
+ * records.add(new BatchRead(new Key("test", "set1", "id2"), true)); // read all bins
+ * client.get(BatchPolicy.ReadDefault(), records);
+ * for (BatchRecord br : records) {
+ *   BatchRead r = (BatchRead) br;
+ *   if (r.record != null) { /* use r.record *\/ }
+ * }
+ * }
+ * + * @see BatchRecord + * @see IAerospikeClient#get */ public final class BatchRead extends BatchRecord { /** diff --git a/client/src/com/aerospike/client/BatchRecord.java b/client/src/com/aerospike/client/BatchRecord.java index 7a1b32ca6..851fe37d1 100644 --- a/client/src/com/aerospike/client/BatchRecord.java +++ b/client/src/com/aerospike/client/BatchRecord.java @@ -20,40 +20,65 @@ import com.aerospike.client.policy.Policy; /** - * Batch key and record result. + * Holds the key and result (record or error) for one item in a batch operation. + * + *

After a batch call completes, each {@code BatchRecord} has a {@link #resultCode}; when it is + * {@link ResultCode#OK}, {@link #record} is set. When an error occurred, {@link #record} is {@code null} + * and {@link #inDoubt} indicates whether a write might have completed on the server. + * + *

Build a list of BatchRecords, call get, then check resultCode and record on each.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * List records = new ArrayList<>();
+ * for (Key k : keys) {
+ *     records.add(new BatchRecord(k, false));
+ * }
+ * client.get(null, records);
+ * for (BatchRecord br : records) {
+ *     if (br.resultCode == ResultCode.OK && br.record != null) {
+ *         // use br.record
+ *     } else {
+ *         // handle br.resultCode, check br.inDoubt for writes
+ *     }
+ * }
+ * }
+ * + * @see ResultCode + * @see AerospikeException.BatchRecords + * @see AerospikeException.BatchRecordArray */ public class BatchRecord { /** - * Key. + * The key for this batch item; never {@code null}. */ public final Key key; /** - * Record result after batch command has completed. Will be null if record was not found - * or an error occurred. See {@link BatchRecord#resultCode}. + * The record returned for this key after the batch completes; {@code null} if the record was not found or an error occurred (see {@link #resultCode}). */ public Record record; /** - * Result code for this returned record. See {@link com.aerospike.client.ResultCode}. - * If not {@link com.aerospike.client.ResultCode#OK}, the record will be null. + * Result code for this batch item (e.g. {@link ResultCode#OK}, {@link ResultCode#KEY_NOT_FOUND_ERROR}). + * When not {@link ResultCode#OK}, {@link #record} is typically {@code null}. */ public int resultCode; /** - * Is it possible that the write command may have completed even though an error - * occurred for this record. This may be the case when a client error occurs (like timeout) - * after the command was sent to the server. + * When {@code true}, a write may have completed on the server even though an error was reported (e.g. timeout after send). */ public boolean inDoubt; /** - * Does this command contain a write operation. For internal use only. + * Whether this batch item includes a write operation; for internal use. */ public final boolean hasWrite; /** - * Initialize batch key. + * Constructs a batch record for the given key; result fields are reset for the upcoming batch call. + * + * @param key the key for this batch item; must not be {@code null} + * @param hasWrite whether this item performs a write */ public BatchRecord(Key key, boolean hasWrite) { this.key = key; @@ -62,7 +87,11 @@ public BatchRecord(Key key, boolean hasWrite) { } /** - * Initialize batch key and record. + * Constructs a batch record with a successful read result. + * + * @param key the key; must not be {@code null} + * @param record the record returned; may be {@code null} if key not found + * @param hasWrite whether this item performs a write */ public BatchRecord(Key key, Record record, boolean hasWrite) { this.key = key; @@ -72,7 +101,13 @@ public BatchRecord(Key key, Record record, boolean hasWrite) { } /** - * Error constructor. + * Constructs a batch record with an error or partial result. + * + * @param key the key; must not be {@code null} + * @param record optional partial record; often {@code null} on error + * @param resultCode the result code (e.g. from {@link ResultCode}) + * @param inDoubt whether a write may have completed on the server + * @param hasWrite whether this item performs a write */ public BatchRecord(Key key, Record record, int resultCode, boolean inDoubt, boolean hasWrite) { this.key = key; @@ -109,7 +144,9 @@ public final void setError(int resultCode, boolean inDoubt) { } /** - * Convert to string. + * Returns a string representation of this batch record (the key). + * + * @return string representation of the key */ @Override public String toString() { @@ -139,12 +176,16 @@ public int size(Policy parentPolicy, ConfigurationProvider configProvider) { } /** - * Batch command type. + * Batch command type for classifying a batch record. */ public enum Type { + /** Batch read operation. */ BATCH_READ, + /** Batch write operation. */ BATCH_WRITE, + /** Batch delete operation. */ BATCH_DELETE, + /** Batch UDF execute operation. */ BATCH_UDF } } diff --git a/client/src/com/aerospike/client/BatchUDF.java b/client/src/com/aerospike/client/BatchUDF.java index 665a264dd..f1043684f 100644 --- a/client/src/com/aerospike/client/BatchUDF.java +++ b/client/src/com/aerospike/client/BatchUDF.java @@ -25,7 +25,22 @@ import com.aerospike.client.util.Packer; /** - * Batch user defined functions. + * Batch user-defined function (UDF) execute. Extends {@link BatchRecord}; each record specifies + * a key, package/module name, function name, and optional arguments. Pass a list of {@code BatchUDF} + * to {@link IAerospikeClient#execute}. + *

Build a list of BatchUDF with keys and UDF package/function/args, then call execute.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * List<BatchRecord> records = new ArrayList<>();
+ * records.add(new BatchUDF(new Key("test", "set1", "id1"), "mymodule", "myfunc", new Value[] { Value.get(1) }));
+ * client.execute(new BatchPolicy(), records);
+ * for (BatchRecord br : records) {
+ *   if (br.resultCode == ResultCode.OK && br.record != null) { /* use br.record *\/ }
+ * }
+ * }
+ * + * @see BatchRecord + * @see IAerospikeClient#execute */ public final class BatchUDF extends BatchRecord { /** diff --git a/client/src/com/aerospike/client/BatchWrite.java b/client/src/com/aerospike/client/BatchWrite.java index b83c7e216..7ba10a21c 100644 --- a/client/src/com/aerospike/client/BatchWrite.java +++ b/client/src/com/aerospike/client/BatchWrite.java @@ -24,7 +24,23 @@ import com.aerospike.client.policy.Policy; /** - * Batch key and read/write operations with write policy. + * Batch key and read/write operations with optional per-key write policy. Extends {@link BatchRecord}; + * used in batch operate commands where each key has a list of {@link Operation}s (e.g. put, add, get). + * Pass a list of {@code BatchWrite} to {@link IAerospikeClient#operate}. + *

Build a list of BatchWrite with keys and operations, then call operate.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * List<BatchRecord> records = new ArrayList<>();
+ * Key key = new Key("test", "set1", "id1");
+ * records.add(new BatchWrite(key, Operation.put(new Bin("name", "x")), Operation.get("name")));
+ * client.operate(BatchPolicy.WriteDefault(), records);
+ * for (BatchRecord br : records) {
+ *   if (br.record != null) { /* use br.record *\/ }
+ * }
+ * }
+ * + * @see BatchRecord + * @see IAerospikeClient#operate */ public final class BatchWrite extends BatchRecord { /** diff --git a/client/src/com/aerospike/client/Bin.java b/client/src/com/aerospike/client/Bin.java index add44fbb2..8896fc1d4 100644 --- a/client/src/com/aerospike/client/Bin.java +++ b/client/src/com/aerospike/client/Bin.java @@ -24,17 +24,34 @@ import com.aerospike.client.cdt.MapOrder; /** - * Column name/value pair. + * A named bin (column) and its value for use in put and operate calls. + * + *

Bin names are limited to {@link #MAX_BIN_NAME_LENGTH} characters. Use the constructors or + * static helpers ({@link #asNull}, {@link #asGeoJSON}) to create bins; the server accepts string, + * numeric, blob, list, map, and GeoJSON values. + * + *

Example: + *

{@code
+ * client.put(writePolicy, key,
+ *     new Bin("name", "Alice"),
+ *     new Bin("count", 42),
+ *     new Bin("tags", Arrays.asList("a", "b")));
+ * }
+ * + * @see Value + * @see com.aerospike.client.AerospikeClient#put(com.aerospike.client.policy.WritePolicy, Key, Bin...) */ public final class Bin { + /** Maximum allowed length for a bin name (15 characters). */ public static final int MAX_BIN_NAME_LENGTH = 15; + /** - * Bin name. Current limit is 15 characters. + * Bin name; must not exceed {@link #MAX_BIN_NAME_LENGTH} characters. */ public final String name; /** - * Bin value. + * Bin value (string, number, blob, list, map, GeoJSON, etc.). */ public final Value value; @@ -231,10 +248,10 @@ public Bin(String name, List> value, MapOrder mapOrder) { } /** - * Constructor, specifying bin name and value. + * Constructs a bin with the given name and Value. * - * @param name bin name, current limit is 15 characters - * @param value bin value + * @param name bin name; must not exceed {@link #MAX_BIN_NAME_LENGTH} characters + * @param value the value; may be {@code null} (use {@link #asNull} for explicit null) */ public Bin(String name, Value value) { this.name = name; @@ -242,26 +259,30 @@ public Bin(String name, Value value) { } /** - * Create bin with a null value. This is useful for bin deletions within a record. + * Creates a bin with a null value, used for bin deletions within a record. * - * @param name bin name, current limit is 15 characters + * @param name bin name; must not exceed {@link #MAX_BIN_NAME_LENGTH} characters + * @return a bin whose value is null */ public static Bin asNull(String name) { return new Bin(name, Value.getAsNull()); } /** - * Create bin with a GeoJSON value. + * Creates a bin with a GeoJSON string value. * - * @param name bin name, current limit is 15 characters - * @param value bin value + * @param name bin name; must not exceed {@link #MAX_BIN_NAME_LENGTH} characters + * @param value GeoJSON string (e.g. point, polygon) + * @return a bin with the given GeoJSON value */ public static Bin asGeoJSON(String name, String value) { return new Bin(name, Value.getAsGeoJSON(value)); } /** - * Return string representation of bin. + * Returns a string representation of this bin (name:value). + * + * @return string representation */ @Override public String toString() { @@ -269,7 +290,10 @@ public String toString() { } /** - * Compare Bin for equality. + * Compares this bin to the specified object for equality (name and value). + * + * @param obj the object to compare to + * @return {@code true} if equal, {@code false} otherwise */ @Override public boolean equals(Object obj) { @@ -294,7 +318,9 @@ public boolean equals(Object obj) { } /** - * Return hash code for Bin. + * Returns a hash code for this bin (based on name and value). + * + * @return the hash code */ @Override public int hashCode() { diff --git a/client/src/com/aerospike/client/CommitError.java b/client/src/com/aerospike/client/CommitError.java index 92be65dbc..549809c90 100644 --- a/client/src/com/aerospike/client/CommitError.java +++ b/client/src/com/aerospike/client/CommitError.java @@ -17,16 +17,53 @@ package com.aerospike.client; /** - * Transaction error status. + * Error status for a failed transaction commit, used in {@link AerospikeException.Commit}. + * + *

Indicates whether verify failed, abort/close was abandoned, or roll-forward was abandoned. + * The {@link #str} field holds the full message for logging or display. + * + *

Catch AerospikeException.Commit and switch on the error field.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * try {
+ *     CommitStatus status = client.commit(txn);
+ * } catch (AerospikeException.Commit e) {
+ *     CommitError err = e.error;
+ *     switch (err) {
+ *         case VERIFY_FAIL: // handle verify failure; break;
+ *         case VERIFY_FAIL_CLOSE_ABANDONED: // handle; break;
+ *         default: System.err.println(err.str);
+ *     }
+ * }
+ * }
+ * + * @see AerospikeException.Commit#error + * @see CommitStatus + * @see AbortStatus */ public enum CommitError { + /** Transaction verify failed and the transaction was aborted. */ VERIFY_FAIL("Transaction verify failed. Transaction aborted."), + + /** Transaction verify failed; transaction aborted and client close was abandoned; server will eventually close. */ VERIFY_FAIL_CLOSE_ABANDONED("Transaction verify failed. Transaction aborted. Transaction client close abandoned. Server will eventually close the transaction."), + + /** Transaction verify failed; client abort was abandoned; server will eventually abort. */ VERIFY_FAIL_ABORT_ABANDONED("Transaction verify failed. Transaction client abort abandoned. Server will eventually abort the transaction."), + + /** Client mark roll-forward was abandoned; server will eventually abort the transaction. */ MARK_ROLL_FORWARD_ABANDONED("Transaction client mark roll forward abandoned. Server will eventually abort the transaction."); + /** + * Full error message for this status; suitable for logging or user display. + */ public final String str; + /** + * Constructor for enum constant. + * + * @param str the full error message for this status + */ CommitError(String str) { this.str = str; } diff --git a/client/src/com/aerospike/client/CommitStatus.java b/client/src/com/aerospike/client/CommitStatus.java index 435192827..3252715d2 100644 --- a/client/src/com/aerospike/client/CommitStatus.java +++ b/client/src/com/aerospike/client/CommitStatus.java @@ -17,16 +17,53 @@ package com.aerospike.client; /** - * Transaction commit status code. + * Status code for a transaction commit operation. + * + *

Indicates success ({@link #OK}, {@link #ALREADY_COMMITTED}) or that the client commit/close was abandoned + * and the server will eventually complete. The {@link #str} field holds the full message for logging or display. + * + *

Call commit on a transaction and switch on the returned status.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * CommitStatus status = client.commit(txn);
+ * switch (status) {
+ *     case OK:
+ *     case ALREADY_COMMITTED:
+ *         // transaction committed successfully
+ *         break;
+ *     case ROLL_FORWARD_ABANDONED:
+ *     case CLOSE_ABANDONED:
+ *         // server will eventually complete; log status.str if needed
+ *         break;
+ * }
+ * }
+ * + * @see AbortStatus + * @see CommitError */ public enum CommitStatus { + /** Commit completed successfully. */ OK("Commit succeeded"), + + /** Transaction was already committed (e.g. duplicate commit). */ ALREADY_COMMITTED("Already committed"), + + /** Client roll-forward was abandoned; server will eventually commit the transaction. */ ROLL_FORWARD_ABANDONED("Transaction client roll forward abandoned. Server will eventually commit the transaction."), + + /** Transaction was rolled forward but client close was abandoned; server will eventually close. */ CLOSE_ABANDONED("Transaction has been rolled forward, but transaction client close was abandoned. Server will eventually close the transaction."); + /** + * Full status message for this value; suitable for logging or user display. + */ public final String str; + /** + * Constructor for enum constant. + * + * @param str the full status message + */ CommitStatus(String str) { this.str = str; } diff --git a/client/src/com/aerospike/client/Host.java b/client/src/com/aerospike/client/Host.java index a4c9e16e7..cc44714ef 100644 --- a/client/src/com/aerospike/client/Host.java +++ b/client/src/com/aerospike/client/Host.java @@ -20,26 +20,41 @@ import java.util.List; /** - * Host name/port of database server. + * Represents a database server endpoint by host name (or IP) and port, with optional TLS name. + * + *

Used as seed nodes when constructing {@link com.aerospike.client.AerospikeClient}. Parse from a string + * using {@link #parseHosts(String, int)} or {@link #parseServiceHosts(String)}. + * + *

Parse hosts from a string and create a client with the Host array.

+ *
{@code
+ * Host[] hosts = Host.parseHosts("192.168.1.10:3000,192.168.1.11:3000", 3000);
+ * IAerospikeClient client = new AerospikeClient(clientPolicy, hosts);
+ * }
+ * + * @see #parseHosts(String, int) + * @see #parseServiceHosts(String) */ public final class Host { /** - * Host name or IP address of database server. + * Host name or IP address of the server; never {@code null}. */ public final String name; /** - * TLS certificate name used for secure connections. + * TLS certificate name for secure connections; {@code null} for non-TLS. */ public final String tlsName; /** - * Port of database server. + * Port number of the server. */ public final int port; /** - * Initialize host. + * Constructs a host with the given name and port (no TLS). + * + * @param name host name or IP address; must not be {@code null} + * @param port port number */ public Host(String name, int port) { this.name = name; @@ -48,7 +63,11 @@ public Host(String name, int port) { } /** - * Initialize host. + * Constructs a host with the given name, optional TLS name, and port. + * + * @param name host name or IP address; must not be {@code null} + * @param tlsName TLS certificate name for secure connections, or {@code null} + * @param port port number */ public Host(String name, String tlsName, int port) { this.name = name; @@ -85,7 +104,8 @@ public boolean equals(Object obj) { } /** - * Parse command-line hosts from string format: hostname1[:tlsname1][:port1],... + * Parses a comma-separated list of hosts from the format: hostname1[:tlsname1][:port1],... + * *

* Hostname may also be an IP address in the following formats. *

    @@ -94,7 +114,12 @@ public boolean equals(Object obj) { *
  • IPv6: [xxxx::xxxx]
  • *
* IPv6 addresses must be enclosed by brackets. - * tlsname and port are optional. + * TLS name and port are optional; if port is omitted, {@code defaultPort} is used. + * + * @param str the host string (e.g. "host1:3000,host2:3000"); must not be {@code null} + * @param defaultPort port to use when not specified in the string + * @return array of parsed hosts + * @throws AerospikeException when the string format is invalid (e.g. missing host:port or bad port). */ public static Host[] parseHosts(String str, int defaultPort) { try { @@ -106,7 +131,7 @@ public static Host[] parseHosts(String str, int defaultPort) { } /** - * Parse server service hosts from string format: hostname1:port1,... + * Parses a comma-separated list of service hosts from the format: hostname1:port1,... *

* Hostname may also be an IP address in the following formats. *

    @@ -115,6 +140,10 @@ public static Host[] parseHosts(String str, int defaultPort) { *
  • IPv6: [xxxx::xxxx]
  • *
* IPv6 addresses must be enclosed by brackets. + * + * @param str the service host string (e.g. "host1:3000,host2:3000"); must not be {@code null} + * @return list of parsed hosts + * @throws AerospikeException when the string format is invalid (e.g. missing host:port or bad port). */ public static List parseServiceHosts(String str) { try { diff --git a/client/src/com/aerospike/client/IAerospikeClient.java b/client/src/com/aerospike/client/IAerospikeClient.java index 2e2f77de2..194b06328 100644 --- a/client/src/com/aerospike/client/IAerospikeClient.java +++ b/client/src/com/aerospike/client/IAerospikeClient.java @@ -74,17 +74,25 @@ import com.aerospike.client.task.RegisterTask; /** - * This interface's sole purpose is to allow mock frameworks to operate on - * AerospikeClient without being constrained by final methods. + * Interface for the Aerospike client API, implemented by {@link AerospikeClient}. + * + *

Exposes the same operations as {@link AerospikeClient} so that mock frameworks and tests can substitute + * a different implementation without being constrained by final methods. + * + * @see AerospikeClient */ public interface IAerospikeClient extends Closeable { /** - * Return the client version + * Returns the client library version string. + * + * @return the version string (e.g. "5.0.0") */ public String getVersion(); /** - * Returns the client's ConfigurationProvider, if any was added to the clientPolicy + * Returns the client's configuration provider, if one was set on the clientPolicy. + * + * @return the configuration provider, or {@code null} if none was set */ public ConfigurationProvider getConfigProvider(); @@ -93,22 +101,30 @@ public interface IAerospikeClient extends Closeable { //------------------------------------------------------- /** - * Return read policy default. Use when the policy will not be modified. + * Returns the default read policy (do not modify; use for commands that do not need custom policy). + * + * @return the default read policy */ public Policy getReadPolicyDefault(); /** - * Copy read policy default. Use when the policy will be modified for use in a specific command. + * Returns a copy of the default read policy for use when the policy will be modified per command. + * + * @return a copy of the default read policy */ public Policy copyReadPolicyDefault(); /** - * Return write policy default. Use when the policy will not be modified. + * Returns the default write policy (do not modify; use for commands that do not need custom policy). + * + * @return the default write policy */ public WritePolicy getWritePolicyDefault(); /** - * Copy write policy default. Use when the policy will be modified for use in a specific command. + * Returns a copy of the default write policy for use when the policy will be modified per command. + * + * @return a copy of the default write policy */ public WritePolicy copyWritePolicyDefault(); @@ -266,7 +282,7 @@ public interface IAerospikeClient extends Closeable { /** * Return node given its name. - * @throws AerospikeException.InvalidNode if node does not exist. + * @throws AerospikeException.InvalidNode when the node name does not exist in the cluster. */ public Node getNode(String nodeName) throws AerospikeException.InvalidNode; @@ -309,7 +325,7 @@ public Node getNode(String nodeName) * * @param txn transaction * @return status of the commit on success - * @throws AerospikeException.Commit if verify commit fails + * @throws AerospikeException.Commit when verify or commit fails (e.g. version mismatch or transaction conflict). */ CommitStatus commit(Txn txn) throws AerospikeException.Commit; @@ -328,7 +344,7 @@ CommitStatus commit(Txn txn) * loop will be chosen by round-robin. * @param listener where to send results * @param txn transaction - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ void commit(EventLoop eventLoop, CommitListener listener, Txn txn) throws AerospikeException; @@ -355,7 +371,7 @@ void commit(EventLoop eventLoop, CommitListener listener, Txn txn) * loop will be chosen by round-robin. * @param listener where to send results * @param txn transaction - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ void abort(EventLoop eventLoop, AbortListener listener, Txn txn) throws AerospikeException; @@ -372,7 +388,7 @@ void abort(EventLoop eventLoop, AbortListener listener, Txn txn) * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs - * @throws AerospikeException if write fails + * @throws AerospikeException when the write fails (e.g. timeout, connection error, or record policy violation). */ public void put(WritePolicy policy, Key key, Bin... bins) throws AerospikeException; @@ -391,7 +407,7 @@ public void put(WritePolicy policy, Key key, Bin... bins) * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void put(EventLoop eventLoop, WriteListener listener, WritePolicy policy, Key key, Bin... bins) throws AerospikeException; @@ -409,7 +425,7 @@ public void put(EventLoop eventLoop, WriteListener listener, WritePolicy policy, * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs - * @throws AerospikeException if append fails + * @throws AerospikeException when the append fails (e.g. timeout or connection error). */ public void append(WritePolicy policy, Key key, Bin... bins) throws AerospikeException; @@ -429,7 +445,7 @@ public void append(WritePolicy policy, Key key, Bin... bins) * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void append(EventLoop eventLoop, WriteListener listener, WritePolicy policy, Key key, Bin... bins) throws AerospikeException; @@ -443,7 +459,7 @@ public void append(EventLoop eventLoop, WriteListener listener, WritePolicy poli * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs - * @throws AerospikeException if prepend fails + * @throws AerospikeException when the prepend fails (e.g. timeout or connection error). */ public void prepend(WritePolicy policy, Key key, Bin... bins) throws AerospikeException; @@ -463,7 +479,7 @@ public void prepend(WritePolicy policy, Key key, Bin... bins) * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void prepend(EventLoop eventLoop, WriteListener listener, WritePolicy policy, Key key, Bin... bins) throws AerospikeException; @@ -481,7 +497,7 @@ public void prepend(EventLoop eventLoop, WriteListener listener, WritePolicy pol * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs - * @throws AerospikeException if add fails + * @throws AerospikeException when the add fails (e.g. timeout or connection error). */ public void add(WritePolicy policy, Key key, Bin... bins) throws AerospikeException; @@ -501,7 +517,7 @@ public void add(WritePolicy policy, Key key, Bin... bins) * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param bins array of bin name/value pairs - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void add(EventLoop eventLoop, WriteListener listener, WritePolicy policy, Key key, Bin... bins) throws AerospikeException; @@ -517,7 +533,7 @@ public void add(EventLoop eventLoop, WriteListener listener, WritePolicy policy, * @param policy delete configuration parameters, pass in null for defaults * @param key unique record identifier * @return whether record existed on server before deletion - * @throws AerospikeException if delete fails + * @throws AerospikeException when the delete fails (e.g. timeout or connection error). */ public boolean delete(WritePolicy policy, Key key) throws AerospikeException; @@ -534,7 +550,7 @@ public boolean delete(WritePolicy policy, Key key) * @param listener where to send results, pass in null for fire and forget * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void delete(EventLoop eventLoop, DeleteListener listener, WritePolicy policy, Key key) throws AerospikeException; @@ -548,7 +564,7 @@ public void delete(EventLoop eventLoop, DeleteListener listener, WritePolicy pol * @param batchPolicy batch configuration parameters, pass in null for defaults * @param deletePolicy delete configuration parameters, pass in null for defaults * @param keys array of unique record identifiers - * @throws AerospikeException.BatchRecordArray which contains results for keys that did complete + * @throws AerospikeException.BatchRecordArray when the batch is terminated by a fatal error; the exception contains results for keys that did complete. */ public BatchResults delete(BatchPolicy batchPolicy, BatchDeletePolicy deletePolicy, Key[] keys) throws AerospikeException; @@ -569,7 +585,7 @@ public BatchResults delete(BatchPolicy batchPolicy, BatchDeletePolicy deletePoli * @param batchPolicy batch configuration parameters, pass in null for defaults * @param deletePolicy delete configuration parameters, pass in null for defaults * @param keys array of unique record identifiers - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void delete( EventLoop eventLoop, @@ -596,7 +612,7 @@ public void delete( * @param batchPolicy batch configuration parameters, pass in null for defaults * @param deletePolicy delete configuration parameters, pass in null for defaults * @param keys array of unique record identifiers - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void delete( EventLoop eventLoop, @@ -622,7 +638,7 @@ public void delete( * @param beforeLastUpdate optional delete records before record last update time. * If specified, value must be before the current time. * Pass in null to delete all records in namespace/set. - * @throws AerospikeException if truncate fails + * @throws AerospikeException when the truncate fails (e.g. timeout, connection error, or insufficient privileges). */ public void truncate(InfoPolicy policy, String ns, String set, Calendar beforeLastUpdate) throws AerospikeException; @@ -638,7 +654,7 @@ public void truncate(InfoPolicy policy, String ns, String set, Calendar beforeLa * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier - * @throws AerospikeException if touch fails + * @throws AerospikeException when the touch fails (e.g. record does not exist, timeout, or connection error). */ public void touch(WritePolicy policy, Key key) throws AerospikeException; @@ -657,7 +673,7 @@ public void touch(WritePolicy policy, Key key) * @param listener where to send results, pass in null for fire and forget * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void touch(EventLoop eventLoop, WriteListener listener, WritePolicy policy, Key key) throws AerospikeException; @@ -669,7 +685,7 @@ public void touch(EventLoop eventLoop, WriteListener listener, WritePolicy polic * * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier - * @throws AerospikeException if touch fails + * @throws AerospikeException when the touch fails (e.g. record does not exist, timeout, or connection error). */ public boolean touched(WritePolicy policy, Key key) throws AerospikeException; @@ -689,7 +705,7 @@ public boolean touched(WritePolicy policy, Key key) * @param listener where to send results, pass in null for fire and forget * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void touched(EventLoop eventLoop, ExistsListener listener, WritePolicy policy, Key key) throws AerospikeException; @@ -705,7 +721,7 @@ public void touched(EventLoop eventLoop, ExistsListener listener, WritePolicy po * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier * @return whether record exists or not - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public boolean exists(Policy policy, Key key) throws AerospikeException; @@ -722,7 +738,7 @@ public boolean exists(Policy policy, Key key) * @param listener where to send results * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void exists(EventLoop eventLoop, ExistsListener listener, Policy policy, Key key) throws AerospikeException; @@ -734,7 +750,7 @@ public void exists(EventLoop eventLoop, ExistsListener listener, Policy policy, * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @return array key/existence status pairs - * @throws AerospikeException.BatchExists which contains results for keys that did complete + * @throws AerospikeException.BatchExists when the batch is terminated by a fatal error; the exception contains results for keys that did complete. */ public boolean[] exists(BatchPolicy policy, Key[] keys) throws AerospikeException; @@ -751,7 +767,7 @@ public boolean[] exists(BatchPolicy policy, Key[] keys) * @param listener where to send results * @param policy batch configuration parameters, pass in null for defaults * @param keys unique record identifiers - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void exists(EventLoop eventLoop, ExistsArrayListener listener, BatchPolicy policy, Key[] keys) throws AerospikeException; @@ -768,7 +784,7 @@ public void exists(EventLoop eventLoop, ExistsArrayListener listener, BatchPolic * @param listener where to send results * @param policy batch configuration parameters, pass in null for defaults * @param keys unique record identifiers - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void exists(EventLoop eventLoop, ExistsSequenceListener listener, BatchPolicy policy, Key[] keys) throws AerospikeException; @@ -784,7 +800,7 @@ public void exists(EventLoop eventLoop, ExistsSequenceListener listener, BatchPo * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier * @return if found, return record instance. If not found, return null. - * @throws AerospikeException if read fails + * @throws AerospikeException when the read fails (e.g. timeout or connection error). */ public Record get(Policy policy, Key key) throws AerospikeException; @@ -801,7 +817,7 @@ public Record get(Policy policy, Key key) * @param listener where to send results * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, RecordListener listener, Policy policy, Key key) throws AerospikeException; @@ -814,7 +830,7 @@ public void get(EventLoop eventLoop, RecordListener listener, Policy policy, Key * @param key unique record identifier * @param binNames bins to retrieve * @return if found, return record instance. If not found, return null. - * @throws AerospikeException if read fails + * @throws AerospikeException when the read fails (e.g. timeout or connection error). */ public Record get(Policy policy, Key key, String... binNames) throws AerospikeException; @@ -832,7 +848,7 @@ public Record get(Policy policy, Key key, String... binNames) * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier * @param binNames bins to retrieve - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, RecordListener listener, Policy policy, Key key, String... binNames) throws AerospikeException; @@ -844,7 +860,7 @@ public void get(EventLoop eventLoop, RecordListener listener, Policy policy, Key * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier * @return if found, return record instance. If not found, return null. - * @throws AerospikeException if read fails + * @throws AerospikeException when the read fails (e.g. timeout or connection error). */ public Record getHeader(Policy policy, Key key) throws AerospikeException; @@ -861,7 +877,7 @@ public Record getHeader(Policy policy, Key key) * @param listener where to send results * @param policy generic configuration parameters, pass in null for defaults * @param key unique record identifier - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void getHeader(EventLoop eventLoop, RecordListener listener, Policy policy, Key key) throws AerospikeException; @@ -880,7 +896,7 @@ public void getHeader(EventLoop eventLoop, RecordListener listener, Policy polic * @param records list of unique record identifiers and the bins to retrieve. * The returned records are located in the same list. * @return true if all batch key requests succeeded - * @throws AerospikeException if read fails + * @throws AerospikeException when the read fails (e.g. timeout or connection error). */ public boolean get(BatchPolicy policy, List records) throws AerospikeException; @@ -900,7 +916,7 @@ public boolean get(BatchPolicy policy, List records) * @param policy batch configuration parameters, pass in null for defaults * @param records list of unique record identifiers and the bins to retrieve. * The returned records are located in the same list. - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, BatchListListener listener, BatchPolicy policy, List records) throws AerospikeException; @@ -920,7 +936,7 @@ public void get(EventLoop eventLoop, BatchListListener listener, BatchPolicy pol * @param policy batch configuration parameters, pass in null for defaults * @param records list of unique record identifiers and the bins to retrieve. * The returned records are located in the same list. - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, BatchSequenceListener listener, BatchPolicy policy, List records) throws AerospikeException; @@ -933,7 +949,7 @@ public void get(EventLoop eventLoop, BatchSequenceListener listener, BatchPolicy * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @return array of records - * @throws AerospikeException.BatchRecords which contains results for keys that did complete + * @throws AerospikeException.BatchRecords when the batch is terminated by a fatal error; the exception contains results for keys that did complete. */ public Record[] get(BatchPolicy policy, Key[] keys) throws AerospikeException; @@ -951,7 +967,7 @@ public Record[] get(BatchPolicy policy, Key[] keys) * @param listener where to send results * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, RecordArrayListener listener, BatchPolicy policy, Key[] keys) throws AerospikeException; @@ -969,7 +985,7 @@ public void get(EventLoop eventLoop, RecordArrayListener listener, BatchPolicy p * @param listener where to send results * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, RecordSequenceListener listener, BatchPolicy policy, Key[] keys) throws AerospikeException; @@ -983,7 +999,7 @@ public void get(EventLoop eventLoop, RecordSequenceListener listener, BatchPolic * @param keys array of unique record identifiers * @param binNames array of bins to retrieve * @return array of records - * @throws AerospikeException.BatchRecords which contains results for keys that did complete + * @throws AerospikeException.BatchRecords when the batch is terminated by a fatal error; the exception contains results for keys that did complete. */ public Record[] get(BatchPolicy policy, Key[] keys, String... binNames) throws AerospikeException; @@ -1002,7 +1018,7 @@ public Record[] get(BatchPolicy policy, Key[] keys, String... binNames) * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @param binNames array of bins to retrieve - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, RecordArrayListener listener, BatchPolicy policy, Key[] keys, String... binNames) throws AerospikeException; @@ -1021,7 +1037,7 @@ public void get(EventLoop eventLoop, RecordArrayListener listener, BatchPolicy p * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @param binNames array of bins to retrieve - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, RecordSequenceListener listener, BatchPolicy policy, Key[] keys, String... binNames) throws AerospikeException; @@ -1035,7 +1051,7 @@ public void get(EventLoop eventLoop, RecordSequenceListener listener, BatchPolic * @param keys array of unique record identifiers * @param ops array of read operations on record * @return array of records - * @throws AerospikeException.BatchRecords which contains results for keys that did complete + * @throws AerospikeException.BatchRecords when the batch is terminated by a fatal error; the exception contains results for keys that did complete. */ public Record[] get(BatchPolicy policy, Key[] keys, Operation... ops) throws AerospikeException; @@ -1054,7 +1070,7 @@ public Record[] get(BatchPolicy policy, Key[] keys, Operation... ops) * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @param ops array of read operations on record - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, RecordArrayListener listener, BatchPolicy policy, Key[] keys, Operation... ops) throws AerospikeException; @@ -1073,7 +1089,7 @@ public void get(EventLoop eventLoop, RecordArrayListener listener, BatchPolicy p * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @param ops array of read operations on record - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void get(EventLoop eventLoop, RecordSequenceListener listener, BatchPolicy policy, Key[] keys, Operation... ops) throws AerospikeException; @@ -1086,7 +1102,7 @@ public void get(EventLoop eventLoop, RecordSequenceListener listener, BatchPolic * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @return array of records - * @throws AerospikeException.BatchRecords which contains results for keys that did complete + * @throws AerospikeException.BatchRecords when the batch is terminated by a fatal error; the exception contains results for keys that did complete. */ public Record[] getHeader(BatchPolicy policy, Key[] keys) throws AerospikeException; @@ -1104,7 +1120,7 @@ public Record[] getHeader(BatchPolicy policy, Key[] keys) * @param listener where to send results * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void getHeader(EventLoop eventLoop, RecordArrayListener listener, BatchPolicy policy, Key[] keys) throws AerospikeException; @@ -1122,7 +1138,7 @@ public void getHeader(EventLoop eventLoop, RecordArrayListener listener, BatchPo * @param listener where to send results * @param policy batch configuration parameters, pass in null for defaults * @param keys array of unique record identifiers - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void getHeader(EventLoop eventLoop, RecordSequenceListener listener, BatchPolicy policy, Key[] keys) throws AerospikeException; @@ -1144,7 +1160,7 @@ public void getHeader(EventLoop eventLoop, RecordSequenceListener listener, Batc * @param key unique record identifier * @param operations database operations to perform * @return record if there is a read in the operations list - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public Record operate(WritePolicy policy, Key key, Operation... operations) throws AerospikeException; @@ -1167,7 +1183,7 @@ public Record operate(WritePolicy policy, Key key, Operation... operations) * @param policy write configuration parameters, pass in null for defaults * @param key unique record identifier * @param operations database operations to perform - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void operate(EventLoop eventLoop, RecordListener listener, WritePolicy policy, Key key, Operation... operations) throws AerospikeException; @@ -1189,7 +1205,7 @@ public void operate(EventLoop eventLoop, RecordListener listener, WritePolicy po * @param policy batch configuration parameters, pass in null for defaults * @param records list of unique record identifiers and read/write operations * @return true if all batch sub-commands succeeded - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public boolean operate(BatchPolicy policy, List records) throws AerospikeException; @@ -1212,7 +1228,7 @@ public boolean operate(BatchPolicy policy, List records) * @param listener where to send results * @param policy batch configuration parameters, pass in null for defaults * @param records list of unique record identifiers and read/write operations - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void operate( EventLoop eventLoop, @@ -1239,7 +1255,7 @@ public void operate( * @param listener where to send results * @param policy batch configuration parameters, pass in null for defaults * @param records list of unique record identifiers and read/write operations - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void operate( EventLoop eventLoop, @@ -1258,7 +1274,7 @@ public void operate( * @param writePolicy write configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @param ops database operations to perform - * @throws AerospikeException.BatchRecordArray which contains results for keys that did complete + * @throws AerospikeException.BatchRecordArray when the batch is terminated by a fatal error; the exception contains results for keys that did complete. */ public BatchResults operate( BatchPolicy batchPolicy, @@ -1284,7 +1300,7 @@ public BatchResults operate( * @param writePolicy write configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @param ops array of read/write operations on record - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void operate( EventLoop eventLoop, @@ -1313,7 +1329,7 @@ public void operate( * @param writePolicy write configuration parameters, pass in null for defaults * @param keys array of unique record identifiers * @param ops array of read operations on record - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void operate( EventLoop eventLoop, @@ -1341,7 +1357,7 @@ public void operate( * @param setName optional set name - equivalent to database table * @param callback read callback method - called with record data * @param binNames optional bin to retrieve. All bins will be returned if not specified. - * @throws AerospikeException if scan fails + * @throws AerospikeException when the scan fails (e.g. timeout or connection error). * @deprecated Use {@link #query(QueryPolicy, Statement, QueryListener)} with a {@link Statement} with * namespace, set name and bin names set and no filter (primary index query). It will eventually be removed. */ @@ -1364,7 +1380,7 @@ public void scanAll(ScanPolicy policy, String namespace, String setName, ScanCal * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table * @param binNames optional bin to retrieve. All bins will be returned if not specified. - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). * @deprecated Use {@link #query(EventLoop, RecordSequenceListener, QueryPolicy, Statement)} with a {@link Statement} * with namespace, set name and bin names set and no filter (primary index query). It will eventually be removed. */ @@ -1385,7 +1401,7 @@ public void scanAll(EventLoop eventLoop, RecordSequenceListener listener, ScanPo * @param setName optional set name - equivalent to database table * @param callback read callback method - called with record data * @param binNames optional bin to retrieve. All bins will be returned if not specified. - * @throws AerospikeException if scan fails + * @throws AerospikeException when the scan fails (e.g. timeout or connection error). * @deprecated Use {@link #queryNode(QueryPolicy, Statement, Node)} with a {@link Statement} with namespace, set name * and bin names set and no filter (primary index query). Use {@link #getNode(String)} to get the Node. It will eventually be removed. */ @@ -1405,7 +1421,7 @@ public void scanNode(ScanPolicy policy, String nodeName, String namespace, Strin * @param setName optional set name - equivalent to database table * @param callback read callback method - called with record data * @param binNames optional bin to retrieve. All bins will be returned if not specified. - * @throws AerospikeException if scan fails + * @throws AerospikeException when the scan fails (e.g. timeout or connection error). * @deprecated Use {@link #queryNode(QueryPolicy, Statement, Node)} with a {@link Statement} with namespace, set name * and bin names set and no filter (primary index query). It will eventually be removed. */ @@ -1425,7 +1441,7 @@ public void scanNode(ScanPolicy policy, Node node, String namespace, String setN * @param setName optional set name - equivalent to database table * @param callback read callback method - called with record data * @param binNames optional bin to retrieve. All bins will be returned if not specified. - * @throws AerospikeException if scan fails + * @throws AerospikeException when the scan fails (e.g. timeout or connection error). * @deprecated Use {@link #query(QueryPolicy, Statement, PartitionFilter, QueryListener)} or * {@link #queryPartitions(QueryPolicy, Statement, PartitionFilter)} with a {@link Statement} with namespace, set name * and bin names set and no filter (primary index query). It will eventually be removed. @@ -1448,7 +1464,7 @@ public void scanPartitions(ScanPolicy policy, PartitionFilter partitionFilter, S * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table * @param binNames optional bin to retrieve. All bins will be returned if not specified. - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). * @deprecated Use {@link #queryPartitions(EventLoop, RecordSequenceListener, QueryPolicy, Statement, PartitionFilter)} * with a {@link Statement} with namespace, set name and bin names set and no filter (primary index query). It will eventually be removed. */ @@ -1470,7 +1486,7 @@ public void scanPartitions(EventLoop eventLoop, RecordSequenceListener listener, * @param clientPath path of client file containing user defined functions, relative to current directory * @param serverPath path to store user defined functions on the server, relative to configured script directory. * @param language language of user defined functions - * @throws AerospikeException if register fails + * @throws AerospikeException when the register fails (e.g. timeout, connection error, or invalid UDF). */ public RegisterTask register(Policy policy, String clientPath, String serverPath, Language language) throws AerospikeException; @@ -1486,7 +1502,7 @@ public RegisterTask register(Policy policy, String clientPath, String serverPath * @param resourcePath class path where Lua resource is located * @param serverPath path to store user defined functions on the server, relative to configured script directory. * @param language language of user defined functions - * @throws AerospikeException if register fails + * @throws AerospikeException when the register fails (e.g. timeout, connection error, or invalid UDF). */ public RegisterTask register(Policy policy, ClassLoader resourceLoader, String resourcePath, String serverPath, Language language) throws AerospikeException; @@ -1519,7 +1535,7 @@ public RegisterTask register(Policy policy, ClassLoader resourceLoader, String r * @param code code string containing user defined functions. * @param serverPath path to store user defined functions on the server, relative to configured script directory. * @param language language of user defined functions - * @throws AerospikeException if register fails + * @throws AerospikeException when the register fails (e.g. timeout, connection error, or invalid UDF). */ public RegisterTask registerUdfString(Policy policy, String code, String serverPath, Language language) throws AerospikeException; @@ -1529,7 +1545,7 @@ public RegisterTask registerUdfString(Policy policy, String code, String serverP * * @param policy info configuration parameters, pass in null for defaults * @param serverPath location of UDF on server nodes. Example: mylua.lua - * @throws AerospikeException if remove fails + * @throws AerospikeException when the remove fails (e.g. timeout, connection error, or UDF not found). */ public void removeUdf(InfoPolicy policy, String serverPath) throws AerospikeException; @@ -1547,7 +1563,7 @@ public void removeUdf(InfoPolicy policy, String serverPath) * @param functionName user defined function * @param args arguments passed in to user defined function * @return return value of user defined function - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public Object execute(WritePolicy policy, Key key, String packageName, String functionName, Value... args) throws AerospikeException; @@ -1570,7 +1586,7 @@ public Object execute(WritePolicy policy, Key key, String packageName, String fu * @param packageName server package name where user defined function resides * @param functionName user defined function * @param functionArgs arguments passed in to user defined function - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void execute( EventLoop eventLoop, @@ -1596,7 +1612,7 @@ public void execute( * @param packageName server package name where user defined function resides * @param functionName user defined function * @param functionArgs arguments passed in to user defined function - * @throws AerospikeException.BatchRecordArray which contains results for keys that did complete + * @throws AerospikeException.BatchRecordArray when the batch is terminated by a fatal error; the exception contains results for keys that did complete. */ public BatchResults execute( BatchPolicy batchPolicy, @@ -1627,7 +1643,7 @@ public BatchResults execute( * @param packageName server package name where user defined function resides * @param functionName user defined function * @param functionArgs arguments passed in to user defined function - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void execute( EventLoop eventLoop, @@ -1661,7 +1677,7 @@ public void execute( * @param packageName server package name where user defined function resides * @param functionName user defined function * @param functionArgs arguments passed in to user defined function - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void execute( EventLoop eventLoop, @@ -1690,7 +1706,7 @@ public void execute( * @param packageName server package where user defined function resides * @param functionName function name * @param functionArgs to pass to function name, if any - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public ExecuteTask execute( WritePolicy policy, @@ -1710,7 +1726,7 @@ public ExecuteTask execute( * @param policy write configuration parameters, pass in null for defaults * @param statement background query definition * @param operations list of operations to be performed on selected records - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public ExecuteTask execute( WritePolicy policy, @@ -1730,7 +1746,7 @@ public ExecuteTask execute( * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @return record iterator - * @throws AerospikeException if query fails + * @throws AerospikeException when the query fails (e.g. timeout, connection error, or invalid statement). */ public RecordSet query(QueryPolicy policy, Statement statement) throws AerospikeException; @@ -1747,7 +1763,7 @@ public RecordSet query(QueryPolicy policy, Statement statement) * @param listener where to send results * @param policy query configuration parameters, pass in null for defaults * @param statement query definition - * @throws AerospikeException if event loop registration fails + * @throws AerospikeException when event loop registration fails (e.g. event loop is closed or shutdown). */ public void query(EventLoop eventLoop, RecordSequenceListener listener, QueryPolicy policy, Statement statement) throws AerospikeException; @@ -1765,7 +1781,7 @@ public void query(EventLoop eventLoop, RecordSequenceListener listener, QueryPol * @param policy query configuration parameters, pass in null for defaults * @param statement query definition. * @param listener where to send results - * @throws AerospikeException if query fails + * @throws AerospikeException when the query fails (e.g. timeout, connection error, or invalid statement). */ public void query( QueryPolicy policy, @@ -1792,7 +1808,7 @@ public void query( * @param partitionFilter data partition filter. Set to * {@link com.aerospike.client.query.PartitionFilter#all()} for all partitions. * @param listener where to send results - * @throws AerospikeException if query fails + * @throws AerospikeException when the query fails (e.g. timeout, connection error, or invalid statement). */ public void query( QueryPolicy policy, @@ -1810,7 +1826,7 @@ public void query( * @param statement query definition * @param node server node to execute query * @return record iterator - * @throws AerospikeException if query fails + * @throws AerospikeException when the query fails (e.g. timeout, connection error, or invalid statement). */ public RecordSet queryNode(QueryPolicy policy, Statement statement, Node node) throws AerospikeException; @@ -1825,7 +1841,7 @@ public RecordSet queryNode(QueryPolicy policy, Statement statement, Node node) * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @param partitionFilter filter on a subset of data partitions - * @throws AerospikeException if query fails + * @throws AerospikeException when the query fails (e.g. timeout, connection error, or invalid statement). */ public RecordSet queryPartitions(QueryPolicy policy, Statement statement, PartitionFilter partitionFilter) throws AerospikeException; @@ -1845,7 +1861,7 @@ public RecordSet queryPartitions(QueryPolicy policy, Statement statement, Partit * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @param partitionFilter filter on a subset of data partitions - * @throws AerospikeException if query fails + * @throws AerospikeException when the query fails (e.g. timeout, connection error, or invalid statement). */ public void queryPartitions(EventLoop eventLoop, RecordSequenceListener listener, QueryPolicy policy, Statement statement, PartitionFilter partitionFilter) throws AerospikeException; @@ -1867,7 +1883,7 @@ public void queryPartitions(EventLoop eventLoop, RecordSequenceListener listener * @param functionName aggregation function name * @param functionArgs arguments to pass to function name, if any * @return result iterator - * @throws AerospikeException if query fails + * @throws AerospikeException when the query fails (e.g. timeout, connection error, or invalid statement). */ public ResultSet queryAggregate( QueryPolicy policy, @@ -1889,7 +1905,7 @@ public ResultSet queryAggregate( * * @param policy query configuration parameters, pass in null for defaults * @param statement query definition - * @throws AerospikeException if query fails + * @throws AerospikeException when the query fails (e.g. timeout, connection error, or invalid statement). */ public ResultSet queryAggregate(QueryPolicy policy, Statement statement) throws AerospikeException; @@ -1908,7 +1924,7 @@ public ResultSet queryAggregate(QueryPolicy policy, Statement statement) * @param policy query configuration parameters, pass in null for defaults * @param statement query definition * @param node server node to execute query - * @throws AerospikeException if query fails + * @throws AerospikeException when the query fails (e.g. timeout, connection error, or invalid statement). */ public ResultSet queryAggregateNode(QueryPolicy policy, Statement statement, Node node) throws AerospikeException; @@ -1929,7 +1945,7 @@ public ResultSet queryAggregateNode(QueryPolicy policy, Statement statement, Nod * @param indexName name of secondary index * @param binName bin name that data is indexed on * @param indexType underlying data type of secondary index - * @throws AerospikeException if index create fails + * @throws AerospikeException when the index create fails (e.g. timeout, connection error, or index already exists). */ public IndexTask createIndex( Policy policy, @@ -1954,7 +1970,7 @@ public IndexTask createIndex( * @param indexType underlying data type of secondary index * @param indexCollectionType index collection type * @param ctx optional context to index on elements within a CDT - * @throws AerospikeException if index create fails + * @throws AerospikeException when the index create fails (e.g. timeout, connection error, or index already exists). */ public IndexTask createIndex( Policy policy, @@ -1983,7 +1999,7 @@ public IndexTask createIndex( * @param indexType underlying data type of secondary index * @param indexCollectionType index collection type * @param ctx optional context to index on elements within a CDT - * @throws AerospikeException if index create fails + * @throws AerospikeException when the index create fails (e.g. timeout, connection error, or index already exists). */ public void createIndex( EventLoop eventLoop, @@ -2011,7 +2027,7 @@ public void createIndex( * @param indexType underlying data type of secondary index * @param indexCollectionType index collection type * @param exp expression on which to build the index - * @throws AerospikeException + * @throws AerospikeException when the index create fails (e.g. timeout, connection error, or index already exists). */ public IndexTask createIndex( Policy policy, @@ -2036,7 +2052,7 @@ public IndexTask createIndex( * @param indexType underlying data type of secondary index * @param indexCollectionType index collection type * @param exp expression on which to build the index - * @throws AerospikeException + * @throws AerospikeException when event loop registration fails or the index create fails (e.g. timeout, connection error, or index already exists). */ public void createIndex( EventLoop eventLoop, @@ -2060,7 +2076,7 @@ public void createIndex( * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table * @param indexName name of secondary index - * @throws AerospikeException if index drop fails + * @throws AerospikeException when the index drop fails (e.g. timeout, connection error, or index not found). */ public IndexTask dropIndex( Policy policy, @@ -2081,7 +2097,7 @@ public IndexTask dropIndex( * @param namespace namespace - equivalent to database name * @param setName optional set name - equivalent to database table * @param indexName name of secondary index - * @throws AerospikeException if index drop fails + * @throws AerospikeException when the index drop fails (e.g. timeout, connection error, or index not found). */ public void dropIndex( EventLoop eventLoop, @@ -2112,7 +2128,7 @@ public void dropIndex( * @param policy info configuration parameters, pass in null for defaults * @param node server node to execute command, pass in null for random node * @param commands list of info commands - * @throws AerospikeException if info commands fail + * @throws AerospikeException when the info command fails (e.g. timeout or connection error). */ public void info( EventLoop eventLoop, @@ -2135,7 +2151,7 @@ public void info( * @param datacenter XDR datacenter name * @param namespace namespace - equivalent to database name * @param filter expression filter - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void setXDRFilter( InfoPolicy policy, @@ -2156,7 +2172,7 @@ public void setXDRFilter( * @param user user name * @param password user password in clear-text format * @param roles variable arguments array of role names. Valid roles are listed in {@link com.aerospike.client.admin.Role} - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void createUser(AdminPolicy policy, String user, String password, List roles) throws AerospikeException; @@ -2168,7 +2184,7 @@ public void createUser(AdminPolicy policy, String user, String password, List roles) throws AerospikeException; @@ -2178,7 +2194,7 @@ public void createPkiUser(AdminPolicy policy, String user, List roles) * * @param policy admin configuration parameters, pass in null for defaults * @param user user name - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void dropUser(AdminPolicy policy, String user) throws AerospikeException; @@ -2189,7 +2205,7 @@ public void dropUser(AdminPolicy policy, String user) * @param policy admin configuration parameters, pass in null for defaults * @param user user name * @param password user password in clear-text format - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void changePassword(AdminPolicy policy, String user, String password) throws AerospikeException; @@ -2200,7 +2216,7 @@ public void changePassword(AdminPolicy policy, String user, String password) * @param policy admin configuration parameters, pass in null for defaults * @param user user name * @param roles role names. Valid roles are listed in {@link com.aerospike.client.admin.Role} - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void grantRoles(AdminPolicy policy, String user, List roles) throws AerospikeException; @@ -2211,7 +2227,7 @@ public void grantRoles(AdminPolicy policy, String user, List roles) * @param policy admin configuration parameters, pass in null for defaults * @param user user name * @param roles role names. Valid roles are listed in {@link com.aerospike.client.admin.Role} - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void revokeRoles(AdminPolicy policy, String user, List roles) throws AerospikeException; @@ -2222,7 +2238,7 @@ public void revokeRoles(AdminPolicy policy, String user, List roles) * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param privileges privileges assigned to the role. - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void createRole(AdminPolicy policy, String roleName, List privileges) throws AerospikeException; @@ -2235,7 +2251,7 @@ public void createRole(AdminPolicy policy, String roleName, List priv * @param privileges optional list of privileges assigned to role. * @param whitelist optional list of allowable IP addresses assigned to role. * IP addresses can contain wildcards (ie. 10.1.2.0/24). - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void createRole(AdminPolicy policy, String roleName, List privileges, List whitelist) throws AerospikeException; @@ -2251,7 +2267,7 @@ public void createRole(AdminPolicy policy, String roleName, List priv * IP addresses can contain wildcards (ie. 10.1.2.0/24). * @param readQuota optional maximum reads per second limit, pass in zero for no limit. * @param writeQuota optional maximum writes per second limit, pass in zero for no limit. - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void createRole( AdminPolicy policy, @@ -2267,7 +2283,7 @@ public void createRole( * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void dropRole(AdminPolicy policy, String roleName) throws AerospikeException; @@ -2278,7 +2294,7 @@ public void dropRole(AdminPolicy policy, String roleName) * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param privileges privileges assigned to the role. - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void grantPrivileges(AdminPolicy policy, String roleName, List privileges) throws AerospikeException; @@ -2289,7 +2305,7 @@ public void grantPrivileges(AdminPolicy policy, String roleName, List * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name * @param privileges privileges assigned to the role. - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void revokePrivileges(AdminPolicy policy, String roleName, List privileges) throws AerospikeException; @@ -2301,7 +2317,7 @@ public void revokePrivileges(AdminPolicy policy, String roleName, List whitelist) throws AerospikeException; @@ -2314,7 +2330,7 @@ public void setWhitelist(AdminPolicy policy, String roleName, List white * @param roleName role name * @param readQuota maximum reads per second limit, pass in zero for no limit. * @param writeQuota maximum writes per second limit, pass in zero for no limit. - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public void setQuotas(AdminPolicy policy, String roleName, int readQuota, int writeQuota) throws AerospikeException; @@ -2324,7 +2340,7 @@ public void setQuotas(AdminPolicy policy, String roleName, int readQuota, int wr * * @param policy admin configuration parameters, pass in null for defaults * @param user user name filter - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public User queryUser(AdminPolicy policy, String user) throws AerospikeException; @@ -2333,7 +2349,7 @@ public User queryUser(AdminPolicy policy, String user) * Retrieve all users and their roles. * * @param policy admin configuration parameters, pass in null for defaults - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public List queryUsers(AdminPolicy policy) throws AerospikeException; @@ -2343,7 +2359,7 @@ public List queryUsers(AdminPolicy policy) * * @param policy admin configuration parameters, pass in null for defaults * @param roleName role name filter - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public Role queryRole(AdminPolicy policy, String roleName) throws AerospikeException; @@ -2352,7 +2368,7 @@ public Role queryRole(AdminPolicy policy, String roleName) * Retrieve all roles. * * @param policy admin configuration parameters, pass in null for defaults - * @throws AerospikeException if command fails + * @throws AerospikeException when the command fails (e.g. timeout or connection error). */ public List queryRoles(AdminPolicy policy) throws AerospikeException; diff --git a/client/src/com/aerospike/client/Info.java b/client/src/com/aerospike/client/Info.java index 68f267db6..28b456576 100644 --- a/client/src/com/aerospike/client/Info.java +++ b/client/src/com/aerospike/client/Info.java @@ -30,13 +30,23 @@ import com.aerospike.client.util.ThreadLocalData; /** - * Access server's info monitoring protocol. - *

- * The info protocol is a name/value pair based system, where an individual - * database server node is queried to determine its configuration and status. - * The list of supported names can be found at: - *

- * https://www.aerospike.com/docs/reference/info/index.html + * Queries a server node's info protocol for configuration and status (name/value pairs). + * + *

Use the static {@link #request} methods to send an info command to a {@link com.aerospike.client.cluster.Node} + * and receive the response string. Typically used for administration or monitoring rather than application logic. + * + *

Request info from a node using Info.request for build or statistics.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * try {
+ *     Node node = client.getNodes()[0];
+ *     String build = Info.request(node, "build");
+ *     Map map = Info.request(null, node, "build", "statistics");
+ * } finally { client.close(); }
+ * }
+ * + * @see com.aerospike.client.cluster.Node + * @see InfoPolicy */ public class Info { //------------------------------------------------------- @@ -50,11 +60,20 @@ public class Info { //------------------------------------------------------- /** - * Get one info value by name from the specified database server node. - * This method supports user authentication. + * Requests one info value by name from the given node (uses default timeout and no auth). * - * @param node server node - * @param name name of variable to retrieve + *

Example: + *

{@code
+	 * Node node = client.getNodes()[0];
+	 * String build = Info.request(node, "build");
+	 * }
+ * + * @param node the server node to query; must not be {@code null} + * @param name the info variable name (e.g. "build", "statistics"); must not be {@code null} + * @return the value returned by the server for that variable + * @throws AerospikeException when the request fails (e.g. timeout, connection error, or invalid command). + * @see #request(InfoPolicy, Node, String) + * @see #request(InfoPolicy, Node, String...) */ public static String request(Node node, String name) throws AerospikeException { Connection conn = node.getConnection(DEFAULT_TIMEOUT); @@ -72,12 +91,13 @@ public static String request(Node node, String name) throws AerospikeException { } /** - * Get one info value by name from the specified database server node. - * This method supports user authentication. + * Requests one info value by name from the given node using the specified policy (timeout, auth). * - * @param policy info command configuration parameters, pass in null for defaults - * @param node server node - * @param name name of variable to retrieve + * @param policy info command policy; {@code null} for defaults + * @param node the server node to query; must not be {@code null} + * @param name the info variable name; must not be {@code null} + * @return the value returned by the server for that variable + * @throws AerospikeException when the request fails (e.g. timeout, connection error, or invalid command). */ public static String request(InfoPolicy policy, Node node, String name) throws AerospikeException { int timeout = (policy == null) ? DEFAULT_TIMEOUT : policy.timeout; @@ -96,12 +116,13 @@ public static String request(InfoPolicy policy, Node node, String name) throws A } /** - * Get many info values by name from the specified database server node. - * This method supports user authentication. + * Requests multiple info values by name from the given node. * - * @param policy info command configuration parameters, pass in null for defaults - * @param node server node - * @param names names of variables to retrieve + * @param policy info command policy; {@code null} for defaults + * @param node the server node to query; must not be {@code null} + * @param names the info variable names to retrieve; must not be {@code null} or empty + * @return a map of variable name to value + * @throws AerospikeException when the request fails (e.g. timeout, connection error, or invalid command). */ public static Map request(InfoPolicy policy, Node node, String... names) throws AerospikeException { int timeout = (policy == null) ? DEFAULT_TIMEOUT : policy.timeout; diff --git a/client/src/com/aerospike/client/Key.java b/client/src/com/aerospike/client/Key.java index f03e098c0..75b29fcc3 100644 --- a/client/src/com/aerospike/client/Key.java +++ b/client/src/com/aerospike/client/Key.java @@ -22,68 +22,57 @@ import com.aerospike.client.util.Crypto; /** - * Unique record identifier. Records can be identified using a specified namespace, - * an optional set name, and a user defined key which must be unique within a set. - * Records can also be identified by namespace/digest which is the combination used - * on the server. + * Unique record identifier combining namespace, optional set name, and a user-defined key (or digest). + * + *

The server identifies records by namespace and a digest (hash of set name + user key). The user key + * is not stored or returned by the server unless {@link com.aerospike.client.policy.WritePolicy#sendKey} is {@code true} or you store + * it in a bin. Key size is limited by the thread's buffer (min 8KB); see constructors for large-key handling. + * + *

Example: + *

{@code
+ * Key key = new Key("test", "users", "user-123");
+ * Record rec = client.get(policy, key);
+ * }
+ * + * @see com.aerospike.client.policy.WritePolicy#sendKey + * @see #computeDigest(String, Value) */ public final class Key { /** - * Namespace. Equivalent to database name. + * Namespace name (equivalent to database name); must not be {@code null}. */ public final String namespace; /** - * Optional set name. Equivalent to database table. + * Optional set name (equivalent to database table); {@code null} when the set does not exist. */ public final String setName; /** - * Unique server hash value generated from set name and user key. + * Unique server hash (digest) computed from set name and user key; used by the server to identify the record. */ public final byte[] digest; /** - * Original user key. This key is immediately converted to a hash digest. - * This key is not used or returned by the server by default. If the user key needs - * to persist on the server, use one of the following methods: - *
    - *
  • Set "WritePolicy.sendKey" to true. In this case, the key will be sent to the server for storage on writes - * and retrieved on multi-record scans and queries.
  • - *
  • Explicitly store and retrieve the key in a bin.
  • - *
+ * Original user key; converted to {@link #digest} for the server. + * + *

Not stored or returned by the server unless {@link com.aerospike.client.policy.WritePolicy#sendKey} is {@code true} or the key + * is stored in a bin explicitly. */ public final Value userKey; /** - * Initialize key from namespace, optional set name and user key. - * The set name and user defined key are converted to a digest before sending to the server. - * The user key is not used or returned by the server by default. If the user key needs - * to persist on the server, use one of the following methods: - *

    - *
  • Set "WritePolicy.sendKey" to true. In this case, the key will be sent to the server for storage on writes - * and retrieved on multi-record scans and queries.
  • - *
  • Explicitly store and retrieve the key in a bin.
  • - *
- *

- * The key is converted to bytes to compute the digest. The key's byte size is - * limited to the current thread's buffer size (min 8KB). To store keys > 8KB, do one of the - * following: - *

    - *
  • Set once:
    {@code ThreadLocalData.DefaultBufferSize = maxKeySize + maxSetNameSize + 1;}
  • - *
  • Or for every key: - *
    -	 * {@code int len = key.length() + setName.length() + 1;
    -	 * if (len > ThreadLocalData.getBuffer().length))
    -	 *     ThreadLocalData.resizeBuffer(len);}
    -	 * 
    - *
  • - *
+ * Initializes a key from namespace, optional set name, and string user key. + * + *

The user key is hashed into {@link #digest}; it is not stored or returned by the server unless + * {@link com.aerospike.client.policy.WritePolicy#sendKey} is {@code true} or you store it in a bin. Key byte size is limited by the + * thread buffer (min 8KB). For keys > 8KB, set {@code ThreadLocalData.DefaultBufferSize} or call + * {@code ThreadLocalData.resizeBuffer(len)} before creating the key. * - * @param namespace namespace - * @param setName optional set name, enter null when set does not exist - * @param key user defined unique identifier within set. - * @throws AerospikeException if digest computation fails + * @param namespace namespace name; must not be {@code null} + * @param setName set name, or {@code null} when the set does not exist + * @param key user-defined unique identifier within the set; must not be {@code null} + * @throws AerospikeException when digest computation fails (e.g. unsupported or invalid key type). */ public Key(String namespace, String setName, String key) throws AerospikeException { this.namespace = namespace; @@ -93,33 +82,16 @@ public Key(String namespace, String setName, String key) throws AerospikeExcepti } /** - * Initialize key from namespace, optional set name and user key. - * The set name and user defined key are converted to a digest before sending to the server. - * The user key is not used or returned by the server by default. If the user key needs - * to persist on the server, use one of the following methods: - *

    - *
  • Set "WritePolicy.sendKey" to true. In this case, the key will be sent to the server for storage on writes - * and retrieved on multi-record scans and queries.
  • - *
  • Explicitly store and retrieve the key in a bin.
  • - *
- *

- * The key's byte size is limited to the current thread's buffer size (min 8KB). To store keys > 8KB, do one of the - * following: - *

    - *
  • Set once:
    {@code ThreadLocalData.DefaultBufferSize = maxKeySize + maxSetNameSize + 1;}
  • - *
  • Or for every key: - *
    -	 * {@code int len = key.length + setName.length() + 1;
    -	 * if (len > ThreadLocalData.getBuffer().length))
    -	 *     ThreadLocalData.resizeBuffer(len);}
    -	 * 
    - *
  • - *
+ * Initializes a key from namespace, optional set name, and byte-array user key. + * + *

The user key is hashed into {@link #digest}; it is not stored or returned by the server unless + * {@link com.aerospike.client.policy.WritePolicy#sendKey} is {@code true} or you store it in a bin. Key byte size is limited by the + * thread buffer (min 8KB). For larger keys, resize the buffer before creating the key. * - * @param namespace namespace - * @param setName optional set name, enter null when set does not exist - * @param key user defined unique identifier within set. - * @throws AerospikeException if digest computation fails + * @param namespace namespace name; must not be {@code null} + * @param setName set name, or {@code null} when the set does not exist + * @param key user-defined unique identifier within the set; must not be {@code null} + * @throws AerospikeException when digest computation fails (e.g. unsupported or invalid key type). */ public Key(String namespace, String setName, byte[] key) throws AerospikeException { this.namespace = namespace; @@ -129,35 +101,16 @@ public Key(String namespace, String setName, byte[] key) throws AerospikeExcepti } /** - * Initialize key from namespace, optional set name and user key. - * The set name and user defined key are converted to a digest before sending to the server. - * The user key is not used or returned by the server by default. If the user key needs - * to persist on the server, use one of the following methods: - *

    - *
  • Set "WritePolicy.sendKey" to true. In this case, the key will be sent to the server for storage on writes - * and retrieved on multi-record scans and queries.
  • - *
  • Explicitly store and retrieve the key in a bin.
  • - *
- *

- * The key's byte size is limited to the current thread's buffer size (min 8KB). To store keys > 8KB, do one of the - * following: - *

    - *
  • Set once:
    {@code ThreadLocalData.DefaultBufferSize = maxKeySize + maxSetNameSize + 1;}
  • - *
  • Or for every key: - *
    -	 * {@code int len = length + setName.length() + 1;
    -	 * if (len > ThreadLocalData.getBuffer().length))
    -	 *     ThreadLocalData.resizeBuffer(len);}
    -	 * 
    - *
  • - *
+ * Initializes a key from namespace, optional set name, and a segment of a byte array as user key. * - * @param namespace namespace - * @param setName optional set name, enter null when set does not exist - * @param key user defined unique identifier within set. - * @param offset byte array segment offset - * @param length byte array segment length - * @throws AerospikeException if digest computation fails + *

The user key segment is hashed into {@link #digest}. Key byte size is limited by the thread buffer (min 8KB). + * + * @param namespace namespace name; must not be {@code null} + * @param setName set name, or {@code null} when the set does not exist + * @param key byte array containing the user key; must not be {@code null} + * @param offset offset into {@code key} of the segment + * @param length length of the segment in bytes + * @throws AerospikeException when digest computation fails (e.g. unsupported or invalid key type). */ public Key(String namespace, String setName, byte[] key, int offset, int length) throws AerospikeException { this.namespace = namespace; @@ -167,20 +120,12 @@ public Key(String namespace, String setName, byte[] key, int offset, int length) } /** - * Initialize key from namespace, optional set name and user key. - * The set name and user defined key are converted to a digest before sending to the server. - * The user key is not used or returned by the server by default. If the user key needs - * to persist on the server, use one of the following methods: - *

    - *
  • Set "WritePolicy.sendKey" to true. In this case, the key will be sent to the server for storage on writes - * and retrieved on multi-record scans and queries.
  • - *
  • Explicitly store and retrieve the key in a bin.
  • - *
+ * Initializes a key from namespace, optional set name, and integer user key. * - * @param namespace namespace - * @param setName optional set name, enter null when set does not exist - * @param key user defined unique identifier within set. - * @throws AerospikeException if digest computation fails + * @param namespace namespace name; must not be {@code null} + * @param setName set name, or {@code null} when the set does not exist + * @param key user-defined unique identifier within the set + * @throws AerospikeException when digest computation fails (e.g. unsupported or invalid key type). */ public Key(String namespace, String setName, int key) throws AerospikeException { this.namespace = namespace; @@ -190,20 +135,12 @@ public Key(String namespace, String setName, int key) throws AerospikeException } /** - * Initialize key from namespace, optional set name and user key. - * The set name and user defined key are converted to a digest before sending to the server. - * The user key is not used or returned by the server by default. If the user key needs - * to persist on the server, use one of the following methods: - *
    - *
  • Set "WritePolicy.sendKey" to true. In this case, the key will be sent to the server for storage on writes - * and retrieved on multi-record scans and queries.
  • - *
  • Explicitly store and retrieve the key in a bin.
  • - *
+ * Initializes a key from namespace, optional set name, and long user key. * - * @param namespace namespace - * @param setName optional set name, enter null when set does not exist - * @param key user defined unique identifier within set. - * @throws AerospikeException if digest computation fails + * @param namespace namespace name; must not be {@code null} + * @param setName set name, or {@code null} when the set does not exist + * @param key user-defined unique identifier within the set + * @throws AerospikeException when digest computation fails (e.g. unsupported or invalid key type). */ public Key(String namespace, String setName, long key) throws AerospikeException { this.namespace = namespace; @@ -213,20 +150,14 @@ public Key(String namespace, String setName, long key) throws AerospikeException } /** - * Initialize key from namespace, optional set name and user key. - * The set name and user defined key are converted to a digest before sending to the server. - * The user key is not used or returned by the server by default. If the user key needs - * to persist on the server, use one of the following methods: - *
    - *
  • Set "WritePolicy.sendKey" to true. In this case, the key will be sent to the server for storage on writes - * and retrieved on multi-record scans and queries.
  • - *
  • Explicitly store and retrieve the key in a bin.
  • - *
+ * Initializes a key from namespace, optional set name, and {@link Value} user key. + * + *

Only key-capable value types are allowed (e.g. string, long, bytes); list, map, and null are not valid. * - * @param namespace namespace - * @param setName optional set name, enter null when set does not exist - * @param key user defined unique identifier within set. - * @throws AerospikeException if digest computation fails + * @param namespace namespace name; must not be {@code null} + * @param setName set name, or {@code null} when the set does not exist + * @param key user-defined key as a Value; must not be {@code null} and must be a valid key type + * @throws AerospikeException when digest computation fails or the key type is invalid (e.g. unsupported type such as list or map). */ public Key(String namespace, String setName, Value key) throws AerospikeException { this.namespace = namespace; @@ -256,12 +187,12 @@ public Key(String namespace, String setName, Object key) throws AerospikeExcepti } */ /** - * Initialize key from namespace, digest, optional set name and optional userKey. + * Initializes a key from namespace, digest, optional set name, and optional user key (e.g. when reconstructing from scan/query). * - * @param namespace namespace - * @param digest unique server hash value - * @param setName optional set name, enter null when set does not exist - * @param userKey optional original user key (not hash digest). + * @param namespace namespace name; must not be {@code null} + * @param digest unique server hash (digest) for the record; must not be {@code null} + * @param setName set name, or {@code null} when the set does not exist + * @param userKey original user key if known, or {@code null} */ public Key(String namespace, byte[] digest, String setName, Value userKey) { this.namespace = namespace; @@ -272,7 +203,9 @@ public Key(String namespace, byte[] digest, String setName, Value userKey) { } /** - * Hash lookup uses namespace and digest. + * Returns a hash code based on namespace and digest (for use in hash-based collections). + * + * @return the hash code */ @Override public int hashCode() { @@ -283,7 +216,10 @@ public int hashCode() { } /** - * Equality uses namespace and digest. + * Compares this key to the specified object for equality (namespace and digest). + * + * @param obj the object to compare to + * @return {@code true} if equal, {@code false} otherwise */ @Override public boolean equals(Object obj) { @@ -304,13 +240,15 @@ public boolean equals(Object obj) { } /** - * Generate unique server hash value from set name, key type and user defined key. - * The hash function is RIPEMD-160 (a 160 bit hash). + * Computes the unique server digest (RIPEMD-160 hash) from set name and user key. + * + *

Used when you need the digest without constructing a full {@link Key} (e.g. for custom partitioning). * - * @param setName optional set name, enter null when set does not exist - * @param key record identifier, unique within set - * @return unique server hash value - * @throws AerospikeException if digest computation fails + * @param setName set name, or {@code null} when the set does not exist + * @param key record identifier as a Value; must not be {@code null} and must be a valid key type + * @return 20-byte digest used by the server to identify the record + * @throws AerospikeException when digest computation fails (e.g. unsupported or invalid key type). + * @see Key */ public static byte[] computeDigest(String setName, Value key) throws AerospikeException { return Crypto.computeDigest(setName, key); diff --git a/client/src/com/aerospike/client/Language.java b/client/src/com/aerospike/client/Language.java index 625a23ce6..0af72a5a6 100644 --- a/client/src/com/aerospike/client/Language.java +++ b/client/src/com/aerospike/client/Language.java @@ -17,11 +17,20 @@ package com.aerospike.client; /** - * User defined function languages. + * Language for user-defined functions (UDFs) registered with the server. + * + *

Register a UDF with Language.LUA and wait for completion.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * try {
+ *     RegisterTask task = client.register(null, "myudf.lua", "myudf.lua", Language.LUA);
+ *     task.waitTillComplete();
+ * } finally { client.close(); }
+ * }
+ * + * @see com.aerospike.client.AerospikeClient#register(com.aerospike.client.policy.Policy, String, String, Language) */ public enum Language { - /** - * Lua embedded programming language. - */ + /** Lua; the supported UDF language for Aerospike. */ LUA; } diff --git a/client/src/com/aerospike/client/Operation.java b/client/src/com/aerospike/client/Operation.java index 6bb342fc7..330240539 100644 --- a/client/src/com/aerospike/client/Operation.java +++ b/client/src/com/aerospike/client/Operation.java @@ -17,77 +17,118 @@ package com.aerospike.client; /** - * Database operation definition. The class is used in client's operate() method. + * Defines a single read or write operation for use in {@link com.aerospike.client.AerospikeClient#operate}. + * + *

Use the static factory methods ({@link #get}, {@link #put}, {@link #add}, {@link #delete}, etc.) to build + * operations; then pass an array of operations to operate(). Multiple operations in one call are applied atomically. + * + *

Use operate with add and get operations for atomic read-modify-write.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * try {
+ *     Key key = new Key("test", "set1", "id1");
+ *     Record rec = client.operate(null, key,
+ *         Operation.add(new Bin("count", 1)),
+ *         Operation.get("count"));
+ *     long count = (Long) rec.getValue("count");
+ * } finally { client.close(); }
+ * }
+ * + * @see com.aerospike.client.AerospikeClient#operate + * @see Bin */ public final class Operation { /** - * Create read bin database operation. + * Creates a read operation for the given bin. + * + * @param binName the bin name to read; must not be {@code null} + * @return a read operation for that bin */ public static Operation get(String binName) { return new Operation(Type.READ, binName); } /** - * Create read all record bins database operation. + * Creates a read operation for all bins in the record. + * + * @return a read-all-bins operation */ public static Operation get() { return new Operation(Type.READ); } /** - * Create read record header database operation. + * Creates a read operation for record metadata only (generation, expiration), no bins. + * + * @return a read-header operation */ public static Operation getHeader() { return new Operation(Type.READ_HEADER); } /** - * Create set database operation. + * Creates a write operation that sets the given bin. + * + * @param bin the bin name and value; must not be {@code null} + * @return a write operation for that bin */ public static Operation put(Bin bin) { return new Operation(Type.WRITE, bin.name, bin.value); } /** - * Create string append database operation. + * Creates an append operation that appends the value to the string in the given bin. + * + * @param bin the bin name and value to append; must not be {@code null} + * @return an append operation */ public static Operation append(Bin bin) { return new Operation(Type.APPEND, bin.name, bin.value); } /** - * Create string prepend database operation. + * Creates a prepend operation that prepends the value to the string in the given bin. + * + * @param bin the bin name and value to prepend; must not be {@code null} + * @return a prepend operation */ public static Operation prepend(Bin bin) { return new Operation(Type.PREPEND, bin.name, bin.value); } /** - * Create integer/double add database operation. If the record or bin does not exist, the - * record/bin will be created by default with the value to be added. + * Creates an add operation (integer or double). If the record or bin does not exist, it is created with the added value. + * + * @param bin the bin name and value to add; must not be {@code null} + * @return an add operation */ public static Operation add(Bin bin) { return new Operation(Type.ADD, bin.name, bin.value); } /** - * Create touch record database operation. + * Creates a touch operation that updates the record's expiration (TTL) without reading or writing bins. + * + * @return a touch operation */ public static Operation touch() { return new Operation(Type.TOUCH); } /** - * Create delete record database operation. + * Creates a delete operation that deletes the record. + * + * @return a delete operation */ public static Operation delete() { return new Operation(Type.DELETE); } /** - * Create array of operations from varargs. This method can be useful when - * its important to save identical array pointer references. Using varargs - * directly always generates new references. + * Returns the given operations as an array (useful when you need a stable array reference). + * + * @param ops one or more operations + * @return the same operations as an array */ public static Operation[] array(Operation... ops) { return ops; diff --git a/client/src/com/aerospike/client/Record.java b/client/src/com/aerospike/client/Record.java index f2d1293fb..f9096fe87 100644 --- a/client/src/com/aerospike/client/Record.java +++ b/client/src/com/aerospike/client/Record.java @@ -25,26 +25,45 @@ import com.aerospike.client.Value.HLLValue; /** - * Container object for records. Records are equivalent to rows. + * Holds the bins (name/value pairs), generation, and expiration returned for a single record from the server. + * + *

Records are the result of get, query, and scan operations. Use the {@code get*} methods to read bin values + * by name; each method returns a typed value or a default (e.g. 0 for numeric, false for boolean) if the bin is missing. + * + *

Example: + *

{@code
+ * Record rec = client.get(policy, key);
+ * if (rec != null) {
+ *     String name = rec.getString("name");
+ *     long count = rec.getLong("count");
+ * }
+ * }
+ * + * @see AerospikeClient#get(com.aerospike.client.policy.Policy, Key) + * @see #getValue(String) */ public final class Record { /** - * Map of requested name/value bins. + * Map of bin names to values; may be {@code null} if no bins were requested or returned. */ public final Map bins; /** - * Record modification count. + * Record modification count (generation); incremented by the server on each write. */ public final int generation; /** - * Date record will expire, in seconds from Jan 01 2010 00:00:00 GMT + * Record expiration in seconds from Jan 01 2010 00:00:00 GMT; 0 means never expire. */ public final int expiration; /** - * Initialize record. + * Constructs a record with the given bins, generation, and expiration. + * + * @param bins map of bin names to values; may be {@code null} + * @param generation modification count from the server + * @param expiration expiration in seconds from Jan 01 2010 00:00:00 GMT; 0 for never expire */ public Record( Map bins, @@ -57,28 +76,42 @@ public Record( } /** - * Get bin value given bin name. + * Returns the bin value for the given bin name, or {@code null} if the bin is not present. + * + * @param name the bin name; must not be {@code null} + * @return the value, or {@code null} if the bin is missing or {@link #bins} is {@code null} + * @see #getString(String) + * @see #getLong(String) */ public Object getValue(String name) { return (bins == null)? null : bins.get(name); } /** - * Get bin value as String. + * Returns the bin value as a {@link String}, or {@code null} if the bin is missing or not a string. + * + * @param name the bin name; must not be {@code null} + * @return the string value, or {@code null} */ public String getString(String name) { return (String)getValue(name); } /** - * Get bin value as byte[]. + * Returns the bin value as a byte array, or {@code null} if the bin is missing or not bytes. + * + * @param name the bin name; must not be {@code null} + * @return the byte array, or {@code null} */ public byte[] getBytes(String name) { return (byte[])getValue(name); } /** - * Get bin value as double. + * Returns the bin value as a {@code double}; returns 0.0 if the bin is missing or not numeric. + * + * @param name the bin name; must not be {@code null} + * @return the double value, or 0.0 if absent or not numeric */ public double getDouble(String name) { // The server may return number as double or long. @@ -88,14 +121,20 @@ public double getDouble(String name) { } /** - * Get bin value as float. + * Returns the bin value as a {@code float}; equivalent to casting {@link #getDouble(String)}. + * + * @param name the bin name; must not be {@code null} + * @return the float value, or 0.0f if absent or not numeric */ public float getFloat(String name) { return (float)getDouble(name); } /** - * Get bin value as long. + * Returns the bin value as a {@code long}; returns 0 if the bin is missing or not numeric. + * + * @param name the bin name; must not be {@code null} + * @return the long value, or 0 if absent or not numeric */ public long getLong(String name) { // The server always returns numbers as longs if bin found. @@ -105,7 +144,10 @@ public long getLong(String name) { } /** - * Get bin value as int. + * Returns the bin value as an {@code int}; equivalent to casting {@link #getLong(String)}. + * + * @param name the bin name; must not be {@code null} + * @return the int value, or 0 if absent or not numeric */ public int getInt(String name) { // The server always returns numbers as longs, so get long and cast. @@ -113,7 +155,10 @@ public int getInt(String name) { } /** - * Get bin value as short. + * Returns the bin value as a {@code short}; equivalent to casting {@link #getLong(String)}. + * + * @param name the bin name; must not be {@code null} + * @return the short value, or 0 if absent or not numeric */ public short getShort(String name) { // The server always returns numbers as longs, so get long and cast. @@ -121,7 +166,10 @@ public short getShort(String name) { } /** - * Get bin value as byte. + * Returns the bin value as a {@code byte}; equivalent to casting {@link #getLong(String)}. + * + * @param name the bin name; must not be {@code null} + * @return the byte value, or 0 if absent or not numeric */ public byte getByte(String name) { // The server always returns numbers as longs, so get long and cast. @@ -129,7 +177,12 @@ public byte getByte(String name) { } /** - * Get bin value as boolean. + * Returns the bin value as a {@code boolean}; returns {@code false} if the bin is missing or zero. + * + *

Accepts both server boolean type and legacy long (0/1) representation. + * + * @param name the bin name; must not be {@code null} + * @return the boolean value, or {@code false} if absent or zero */ public boolean getBoolean(String name) { // The server may return boolean as boolean or long (created by older clients). @@ -147,39 +200,55 @@ public boolean getBoolean(String name) { } /** - * Get bin value as list. + * Returns the bin value as a list, or {@code null} if the bin is missing or not a list. + * + * @param name the bin name; must not be {@code null} + * @return the list, or {@code null} */ public List getList(String name) { return (List)getValue(name); } /** - * Get bin value as map. + * Returns the bin value as a map, or {@code null} if the bin is missing or not a map. + * + * @param name the bin name; must not be {@code null} + * @return the map, or {@code null} */ public Map getMap(String name) { return (Map)getValue(name); } /** - * Get the value returned by a UDF execute in a batch. - * The result may be null. + * Returns the value returned by a UDF execute when used in a batch operation. + * + *

This reads the special "SUCCESS" bin written by the server for UDF results. + * + * @return the UDF return value, or {@code null} if not present or not a UDF result record + * @see #getUDFError() */ public Object getUDFResult() { return getValue("SUCCESS"); } /** - * Get the error string returned by a UDF execute in a batch. - * Return null if an error did not occur. + * Returns the error string returned by a UDF execute when the UDF failed in a batch operation. + * + *

This reads the special "FAILURE" bin written by the server when the UDF raises an error. + * + * @return the UDF error message, or {@code null} if no error occurred + * @see #getUDFResult() */ public String getUDFError() { return getString("FAILURE"); } /** - * This method is deprecated. Use {@link #getGeoJSONString(String)} instead. + * Returns the bin value as a GeoJSON string; retained for backward compatibility. * - * Get bin value as GeoJSON (backward compatibility). + * @param name the bin name; must not be {@code null} + * @return the GeoJSON string, or {@code null} + * @deprecated Use {@link #getGeoJSONString(String)} instead */ @Deprecated public String getGeoJSON(String name) { @@ -187,7 +256,10 @@ public String getGeoJSON(String name) { } /** - * Get bin value as GeoJSON String. + * Returns the bin value as a GeoJSON string representation, or {@code null} if the bin is missing. + * + * @param name the bin name; must not be {@code null} + * @return the GeoJSON string, or {@code null} */ public String getGeoJSONString(String name) { Object value = getValue(name); @@ -195,22 +267,32 @@ public String getGeoJSONString(String name) { } /** - * Get bin value as GeoJSON Value. + * Returns the bin value as a {@link GeoJSONValue}, or {@code null} if the bin is missing or not GeoJSON. + * + * @param name the bin name; must not be {@code null} + * @return the GeoJSON value, or {@code null} */ public GeoJSONValue getGeoJSONValue(String name) { return (GeoJSONValue)getValue(name); } /** - * Get bin value as HLL Value. + * Returns the bin value as an {@link HLLValue}, or {@code null} if the bin is missing or not an HLL. + * + * @param name the bin name; must not be {@code null} + * @return the HLL value, or {@code null} */ public HLLValue getHLLValue(String name) { return (HLLValue)getValue(name); } /** - * Convert record expiration (seconds from Jan 01 2010 00:00:00 GMT) to - * ttl (seconds from now). + * Converts the record expiration (seconds from Jan 01 2010 00:00:00 GMT) to TTL in seconds from now. + * + *

Returns -1 if the record never expires (server expiration 0). Otherwise returns the remaining seconds + * until expiration, or at least 1 if already past expiration (to avoid legacy "never expire" interpretation). + * + * @return TTL in seconds from now, -1 for never expire, or ≥1 for remaining/expired */ public int getTimeToLive() { // This is the server's flag indicating the record never expires. @@ -230,7 +312,9 @@ public int getTimeToLive() { } /** - * Return String representation of record. + * Returns a string representation of this record (generation, expiration, and bins). + * + * @return a string representation of this record */ @Override public String toString() { @@ -277,7 +361,10 @@ public int hashCode() { } /** - * Compare records for equality. + * Compares this record to the specified object for equality (bins, generation, expiration). + * + * @param obj the object to compare to + * @return {@code true} if equal, {@code false} otherwise */ @Override public boolean equals(Object obj) { diff --git a/client/src/com/aerospike/client/ResultCode.java b/client/src/com/aerospike/client/ResultCode.java index ba90d0ee5..eedb639e4 100644 --- a/client/src/com/aerospike/client/ResultCode.java +++ b/client/src/com/aerospike/client/ResultCode.java @@ -17,8 +17,29 @@ package com.aerospike.client; /** - * Database operation error codes. The positive numbers align with the server - * side file proto.h. + * Integer result codes returned by the server or set by the client for failed operations. + * + *

Positive values align with server-defined codes (see server proto.h); negative values denote + * client-side errors. Use {@link #getResultString(int)} for a human-readable message and + * {@link AerospikeException#getResultCode()} to obtain the code from an exception. + * + *

Catch AerospikeException and use getResultCode() with ResultCode constants.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * try {
+ *     client.get(policy, key);
+ * } catch (AerospikeException e) {
+ *     int code = e.getResultCode();
+ *     if (code == ResultCode.KEY_NOT_FOUND_ERROR) {
+ *         // handle missing key
+ *     }
+ *     String msg = ResultCode.getResultString(code);
+ * }
+ * }
+ * + * @see AerospikeException#getResultCode() + * @see #getResultString(int) + * @see #keepConnection(int) */ public final class ResultCode { /** @@ -439,7 +460,11 @@ public final class ResultCode { * Secondary index already exists. */ public static final int INDEX_ALREADY_EXISTS = 200; - public static final int INDEX_FOUND = 200; // For legacy reasons. + + /** + * Same value as {@link #INDEX_ALREADY_EXISTS}; retained for legacy compatibility. + */ + public static final int INDEX_FOUND = 200; /** * Requested secondary index does not exist. @@ -492,7 +517,14 @@ public final class ResultCode { public static final int QUERY_GENERIC = 213; /** - * Should connection be put back into pool. + * Returns whether the connection used for the command that returned this result code should be returned to the pool. + * + *

Client errors (resultCode ≤ 0) and certain server codes (e.g. {@link #SCAN_ABORT}, {@link #QUERY_ABORTED}) + * return {@code false}; the connection should be discarded. Other server errors return {@code true}. + * + * @param resultCode the result code from the failed or completed operation + * @return {@code true} if the connection can be reused, {@code false} if it should be discarded + * @see AerospikeException#keepConnection() */ public static boolean keepConnection(int resultCode) { if (resultCode <= 0) { @@ -513,7 +545,11 @@ public static boolean keepConnection(int resultCode) { } /** - * Return result code as a string. + * Returns a human-readable string for the given result code. + * + * @param resultCode the result code (e.g. from {@link AerospikeException#getResultCode()} or this class's constants) + * @return a short description of the result, or an empty string for unknown codes + * @see AerospikeException#getBaseMessage() */ public static String getResultString(int resultCode) { switch (resultCode) { diff --git a/client/src/com/aerospike/client/ScanCallback.java b/client/src/com/aerospike/client/ScanCallback.java index 9e6703680..065c7beed 100644 --- a/client/src/com/aerospike/client/ScanCallback.java +++ b/client/src/com/aerospike/client/ScanCallback.java @@ -17,28 +17,37 @@ package com.aerospike.client; /** - * An object implementing this interface is passed in scan() calls, so the caller can - * be notified with scan results. + * Callback invoked for each record returned by a legacy scan operation. * - * @deprecated Use {@link com.aerospike.client.AerospikeClient#query(com.aerospike.client.policy.QueryPolicy, com.aerospike.client.query.Statement, com.aerospike.client.query.QueryListener)} - * with a {@link com.aerospike.client.query.Statement} that has no filter set (primary index query) instead. It will eventually be removed. + *

Implement this interface and pass it to scan methods. Throw {@link AerospikeException.ScanTerminated} to + * abort the scan. If {@link com.aerospike.client.policy.ScanPolicy#concurrentNodes} is true and + * maxConcurrentNodes is not 1, the implementation must be thread-safe. + * + *

Implement a callback and pass it to scanAll to process each record.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * try {
+ *     ScanCallback callback = (key, record) -> {
+ *         Object val = record.getValue("mybin");
+ *         // process key, record; throw new AerospikeException.ScanTerminated() to abort
+ *     };
+ *     client.scanAll(null, "test", "set1", callback, "mybin");
+ * } finally { client.close(); }
+ * }
+ * + * @deprecated Use {@link com.aerospike.client.AerospikeClient#query(com.aerospike.client.policy.QueryPolicy, com.aerospike.client.query.Statement, com.aerospike.client.query.QueryListener)} with a + * {@link com.aerospike.client.query.Statement} that has no filter (primary index query) and a {@link com.aerospike.client.query.QueryListener} instead */ @Deprecated public interface ScanCallback { /** - * This method will be called for each record returned from a scan. The user may throw a - * {@link com.aerospike.client.AerospikeException.ScanTerminated AerospikeException.ScanTerminated} - * exception if the scan should be aborted. If any exception is thrown, parallel scan threads - * to other nodes will also be terminated and the exception will be propagated back through the - * initiating scan call. - *

- * If {@link com.aerospike.client.policy.ScanPolicy#concurrentNodes} is true and - * {@link com.aerospike.client.policy.ScanPolicy#maxConcurrentNodes} is not equal one, then - * your scanCallback implementation must be thread safe. + * Invoked for each record returned from the scan. + * + *

Throw {@link AerospikeException.ScanTerminated} to abort the scan; the exception is propagated to the caller. * - * @param key unique record identifier - * @param record container for bins and record meta-data - * @throws AerospikeException if error occurs or scan should be terminated. + * @param key the record key; must not be {@code null} + * @param record the record (bins, generation, expiration); may be {@code null} if only digests requested + * @throws AerospikeException when the callback wishes to abort the scan or report an error (e.g. throw {@link AerospikeException.ScanTerminated} to abort). */ public void scanCallback(Key key, Record record) throws AerospikeException; } diff --git a/client/src/com/aerospike/client/Txn.java b/client/src/com/aerospike/client/Txn.java index 17823bd8a..2bc4b3d99 100644 --- a/client/src/com/aerospike/client/Txn.java +++ b/client/src/com/aerospike/client/Txn.java @@ -23,16 +23,39 @@ import java.util.concurrent.atomic.AtomicLong; /** - * Multi-record transaction. Each command in the transaction must use the same namespace. + * Multi-record transaction context for grouping read and write commands into a single logical transaction. + * + *

Attach a {@code Txn} to a policy ({@link com.aerospike.client.policy.Policy#txn}) so that get/put/operate commands participate in the + * same transaction. All commands in the transaction must use the same namespace. Commit or abort via batch APIs. + * + *

Create a transaction, attach to a write policy, perform get/put, then commit.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * try {
+ *     Txn txn = new Txn();
+ *     WritePolicy policy = new WritePolicy(); policy.txn = txn;
+ *     Key key1 = new Key("test", "set1", "id1");
+ *     Key key2 = new Key("test", "set1", "id2");
+ *     client.get(policy, key1);
+ *     client.put(policy, key2, new Bin("name", "value"));
+ *     CommitStatus status = client.commit(txn);
+ * } finally { client.close(); }
+ * }
+ * + * @see com.aerospike.client.policy.Policy#txn */ public final class Txn { /** - * Transaction state. + * Current state of the transaction. */ public static enum State { + /** Transaction is open; reads and writes can be added. */ OPEN, + /** Reads have been verified; commit or abort can proceed. */ VERIFIED, + /** Transaction has been committed. */ COMMITTED, + /** Transaction has been aborted. */ ABORTED; } @@ -49,11 +72,9 @@ public static enum State { private boolean inDoubt; /** - * Create transaction, assign random transaction id and initialize reads/writes hashmaps with - * default capacities. - *

- * The default client transaction timeout is zero. This means use the server configuration - * mrt-duration as the transaction timeout. The default mrt-duration is 10 seconds. + * Constructs a new transaction with default capacities for read and write sets. + * + *

Client transaction timeout defaults to 0 (use server mrt-duration, typically 10 seconds). */ public Txn() { id = createId(); @@ -63,14 +84,12 @@ public Txn() { } /** - * Create transaction, assign random transaction id and initialize reads/writes hashmaps with - * given capacities. - *

- * The default client transaction timeout is zero. This means use the server configuration - * mrt-duration as the transaction timeout. The default mrt-duration is 10 seconds. + * Constructs a new transaction with the given initial capacities for the read and write sets. + * + *

Minimum capacity for each is 16. Client transaction timeout defaults to 0 (use server mrt-duration). * - * @param readsCapacity expected number of record reads in the transaction. Minimum value is 16. - * @param writesCapacity expected number of record writes in the transaction. Minimum value is 16. + * @param readsCapacity expected number of record reads; minimum 16 + * @param writesCapacity expected number of record writes; minimum 16 */ public Txn(int readsCapacity, int writesCapacity) { if (readsCapacity < 16) { @@ -105,6 +124,8 @@ private static long createId() { /** * Return transaction ID. + * + * @return the unique transaction ID */ public long getId() { return id; @@ -118,6 +139,8 @@ public long getId() { *

* If the transaction timeout is zero, the server configuration mrt-duration is used. * The default mrt-duration is 10 seconds. + * + * @param timeout timeout in seconds; 0 for server default (mrt-duration) */ public void setTimeout(int timeout) { this.timeout = timeout; @@ -125,6 +148,8 @@ public void setTimeout(int timeout) { /** * Return transaction timeout in seconds. + * + * @return timeout in seconds; 0 means use server mrt-duration */ public int getTimeout() { return timeout; @@ -184,6 +209,9 @@ public void onRead(Key key, Long version) { /** * Get record version for a given key. + * + * @param key the key to look up + * @return the read version for the key, or null if not present */ public Long getReadVersion(Key key) { return reads.get(key); @@ -191,6 +219,8 @@ public Long getReadVersion(Key key) { /** * Get all read keys and their versions. + * + * @return the set of read key/version entries */ public Set> getReads() { return reads.entrySet(); @@ -222,6 +252,8 @@ public void onWriteInDoubt(Key key) { /** * Get all write keys and their versions. + * + * @return the set of keys written in this transaction */ public Set getWrites() { return writes; @@ -263,6 +295,8 @@ private void setNamespace(List records) { /** * Return transaction namespace. + * + * @return the namespace for this transaction, or null if not yet set */ public String getNamespace() { return namespace; @@ -279,6 +313,8 @@ public void setDeadline(int deadline) { /** * Get transaction deadline. For internal use only. + * + * @return the server-calculated deadline */ public int getDeadline() { return deadline; @@ -286,6 +322,8 @@ public int getDeadline() { /** * Return if the transaction monitor record should be closed/deleted. For internal use only. + * + * @return true if the monitor record should be closed */ public boolean closeMonitor() { return deadline != 0 && !writeInDoubt; @@ -293,6 +331,8 @@ public boolean closeMonitor() { /** * Does transaction monitor record exist. + * + * @return true if the transaction monitor record exists on the server */ public boolean monitorExists() { return deadline != 0; @@ -307,6 +347,8 @@ public void setState(Txn.State state) { /** * Return transaction state. + * + * @return the current transaction state (OPEN, VERIFIED, COMMITTED, or ABORTED) */ public Txn.State getState() { return state; @@ -321,6 +363,8 @@ public void setInDoubt(boolean inDoubt) { /** * Return if transaction is inDoubt. + * + * @return true if the transaction outcome is in doubt (e.g. after timeout before commit/abort) */ public boolean getInDoubt() { return inDoubt; diff --git a/client/src/com/aerospike/client/Value.java b/client/src/com/aerospike/client/Value.java index e35d3eafc..54508e1d6 100644 --- a/client/src/com/aerospike/client/Value.java +++ b/client/src/com/aerospike/client/Value.java @@ -39,7 +39,40 @@ import com.aerospike.client.util.Packer; /** - * Polymorphic value classes used to efficiently serialize objects into the wire protocol. + * Polymorphic value types used to serialize and deserialize data for the Aerospike wire protocol. + * + *

Use the static {@link #get(Object)} and typed {@code get(type)} methods to obtain {@code Value} instances + * for bin values and keys. {@code null} inputs yield {@link #NULL}. Supported types include String, numeric, + * byte[], list, map, and GeoJSON. + * + *

Example using Value.get() for string and integer in a client put.

+ *
{@code
+ * client.put(writePolicy, key, new Bin("name", Value.get("Alice")), new Bin("count", Value.get(42)));
+ * }
+ * + * @see #get(String) + * @see #get(long) + * @see #NULL + * @see NullValue + * @see BytesValue + * @see ByteSegmentValue + * @see ByteValue + * @see StringValue + * @see ShortValue + * @see IntegerValue + * @see LongValue + * @see DoubleValue + * @see FloatValue + * @see BooleanValue + * @see BoolIntValue + * @see GeoJSONValue + * @see HLLValue + * @see ValueArray + * @see ListValue + * @see MapValue + * @see SortedMapValue + * @see InfinityValue + * @see WildcardValue */ public abstract class Value { /** @@ -352,7 +385,7 @@ public static Value getFromRecordObject(Object value) { /** * Validate if value type can be used as a key. - * @throws AerospikeException if type can't be used as a key. + * @throws AerospikeException when the type cannot be used as a key (e.g. list or map type). */ public void validateKeyType() throws AerospikeException { } @@ -388,6 +421,12 @@ public long toLong() { /** * Empty value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.NULL;
+	 * Value v2 = Value.get((String) null);
+	 * }
*/ public static final class NullValue extends Value { public static final NullValue INSTANCE = new NullValue(); @@ -448,6 +487,11 @@ public final int hashCode() { /** * Byte array value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get(new byte[] { 1, 2, 3 });
+	 * }
*/ public static final class BytesValue extends Value { private final byte[] bytes; @@ -514,6 +558,12 @@ public int hashCode() { /** * Byte segment value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * byte[] buf = new byte[] { 1, 2, 3, 4, 5 };
+	 * Value v = Value.get(buf, 1, 3);
+	 * }
*/ public static final class ByteSegmentValue extends Value { private final byte[] bytes; @@ -610,6 +660,11 @@ public int getLength() { /** * Byte value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get((byte) 42);
+	 * }
*/ public static final class ByteValue extends Value { private final byte value; @@ -680,6 +735,11 @@ public long toLong() { /** * String value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get("hello");
+	 * }
*/ public static final class StringValue extends Value { private final String value; @@ -738,6 +798,11 @@ public int hashCode() { /** * Short value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get((short) 100);
+	 * }
*/ public static final class ShortValue extends Value { private final short value; @@ -807,6 +872,11 @@ public long toLong() { /** * Integer value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get(42);
+	 * }
*/ public static final class IntegerValue extends Value { private final int value; @@ -876,6 +946,11 @@ public long toLong() { /** * Long value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get(42L);
+	 * }
*/ public static final class LongValue extends Value { private final long value; @@ -945,6 +1020,11 @@ public long toLong() { /** * Double value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get(3.14);
+	 * }
*/ public static final class DoubleValue extends Value { private final double value; @@ -1015,6 +1095,11 @@ public long toLong() { /** * Float value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get(3.14f);
+	 * }
*/ public static final class FloatValue extends Value { private final float value; @@ -1084,6 +1169,11 @@ public long toLong() { /** * Boolean value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get(true);
+	 * }
*/ public static final class BooleanValue extends Value { private final boolean value; @@ -1160,6 +1250,11 @@ public long toLong() { * Boolean value that converts to integer when sending a bin to the server. * This class will be deleted once full conversion to boolean particle type * is complete. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = new Value.BoolIntValue(true);
+	 * }
*/ public static final class BoolIntValue extends Value { private final boolean value; @@ -1235,6 +1330,11 @@ public long toLong() { /** * GeoJSON value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.getAsGeoJSON("{\"type\":\"Point\",\"coordinates\":[0.0,0.0]}");
+	 * }
*/ public static final class GeoJSONValue extends Value { private final String value; @@ -1301,6 +1401,12 @@ public int hashCode() { /** * HyperLogLog value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * byte[] hllBytes = new byte[] { 0, 1, 2 };
+	 * Value v = new Value.HLLValue(hllBytes);
+	 * }
*/ public static final class HLLValue extends Value { private final byte[] bytes; @@ -1369,6 +1475,11 @@ public int hashCode() { /** * Value array. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get(new Value[] { Value.get(1), Value.get("a") });
+	 * }
*/ public static final class ValueArray extends Value { private final Value[] array; @@ -1435,6 +1546,11 @@ public int hashCode() { /** * List value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.get(java.util.Arrays.asList(1, "a", true));
+	 * }
*/ public static final class ListValue extends Value { private final List list; @@ -1501,6 +1617,13 @@ public int hashCode() { /** * Map value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * java.util.Map m = new java.util.HashMap<>();
+	 * m.put("k", 1);
+	 * Value v = Value.get(m);
+	 * }
*/ public static final class MapValue extends Value { private final Map map; @@ -1582,6 +1705,13 @@ public static MapOrder getMapOrder(Map map) { /** * Sorted map value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * List> entries = new java.util.ArrayList<>();
+	 * entries.add(new java.util.AbstractMap.SimpleEntry<>(Value.get("k"), Value.get(1)));
+	 * Value v = Value.get(entries, MapOrder.KEY_ORDERED);
+	 * }
*/ public static final class SortedMapValue extends Value { private final List> list; @@ -1652,6 +1782,11 @@ public int hashCode() { /** * Infinity value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.INFINITY;
+	 * }
*/ public static final class InfinityValue extends Value { @Override @@ -1708,6 +1843,11 @@ public final int hashCode() { /** * Wildcard value. + * + *

Example creating and using this value type with a client put/get.

+ *
{@code
+	 * Value v = Value.WILDCARD;
+	 * }
*/ public static final class WildcardValue extends Value { @Override diff --git a/client/src/com/aerospike/client/admin/Privilege.java b/client/src/com/aerospike/client/admin/Privilege.java index 3cb1fcb2c..f475554c1 100644 --- a/client/src/com/aerospike/client/admin/Privilege.java +++ b/client/src/com/aerospike/client/admin/Privilege.java @@ -17,23 +17,39 @@ package com.aerospike.client.admin; /** - * User privilege. + * User privilege defining a permission and optional namespace/set scope. + * Used with role administration APIs such as {@link com.aerospike.client.AerospikeClient#createRole createRole} + * and {@link com.aerospike.client.AerospikeClient#grantPrivileges grantPrivileges}. + * + *

Create a privilege for read-write on namespace "test" and set "users", then create a role with that privilege.

+ *
{@code
+ * Privilege p = new Privilege();
+ * p.code = PrivilegeCode.READ_WRITE;
+ * p.namespace = "test";
+ * p.setName = "users";
+ * List privileges = Collections.singletonList(p);
+ * client.createRole(null, "myrole", privileges);
+ * }
+ * + * @see PrivilegeCode + * @see com.aerospike.client.AerospikeClient#createRole + * @see com.aerospike.client.AerospikeClient#grantPrivileges */ public final class Privilege { /** - * Privilege code. + * Privilege code; must not be null. */ public PrivilegeCode code; /** - * Namespace scope. Apply permission to this namespace only. - * If namespace is null, the privilege applies to all namespaces. + * Namespace scope. Apply permission to this namespace only. + * If null, the privilege applies to all namespaces. */ public String namespace; /** - * Set name scope. Apply permission to this set within namespace only. - * If set is null, the privilege applies to all sets within namespace. + * Set name scope. Apply permission to this set within namespace only. + * If null, the privilege applies to all sets within namespace. */ public String setName; } diff --git a/client/src/com/aerospike/client/admin/PrivilegeCode.java b/client/src/com/aerospike/client/admin/PrivilegeCode.java index 2533ff7c5..b9e78550b 100644 --- a/client/src/com/aerospike/client/admin/PrivilegeCode.java +++ b/client/src/com/aerospike/client/admin/PrivilegeCode.java @@ -107,7 +107,9 @@ private PrivilegeCode(int id, String value) { } /** - * Can privilege be scoped with namespace and set. + * Returns whether this privilege can be scoped with namespace and set. + * + * @return true if the privilege supports namespace/set scope (e.g. READ, WRITE) */ public boolean canScope() { return id >= 10; @@ -117,6 +119,10 @@ public boolean canScope() { * Convert ID to privilege code enum. * Returns UNKNOWN for unrecognized privilege codes to support * forward compatibility with newer server versions. + * + * @param id privilege code ID from wire protocol + * @return the corresponding enum constant + * @throws AerospikeException when the given ID is not a known privilege code (e.g. invalid or reserved). */ public static PrivilegeCode fromId(int id) { switch (id) { diff --git a/client/src/com/aerospike/client/async/AsyncIndexTask.java b/client/src/com/aerospike/client/async/AsyncIndexTask.java index 8bd64aa96..8b5b8ee2e 100644 --- a/client/src/com/aerospike/client/async/AsyncIndexTask.java +++ b/client/src/com/aerospike/client/async/AsyncIndexTask.java @@ -29,7 +29,23 @@ import com.aerospike.client.policy.InfoPolicy; /** - * Async index task monitor. + * Async index task monitor. Returned from + * {@link com.aerospike.client.IAerospikeClient#createIndex} + * or dropIndex; use {@link #queryStatus} to poll for completion. + *

Create index asynchronously and poll task status until complete.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.createIndex(eventLoop, new IndexListener() {
+ *   public void onSuccess(AsyncIndexTask task) {
+ *     task.queryStatus(eventLoop, null, client.getNodes()[0], new TaskStatusListener() {
+ *       public void onSuccess(int status) { // 100 = done
+ *       }
+ *       public void onFailure(AerospikeException ae) { }
+ *     });
+ *   }
+ *   public void onFailure(AerospikeException ae) { }
+ * }, null, "ns", "set", "idx1", "bin1", IndexType.STRING, IndexCollectionType.DEFAULT);
+ * }
*/ public class AsyncIndexTask { private final IAerospikeClient client; diff --git a/client/src/com/aerospike/client/async/EventLoop.java b/client/src/com/aerospike/client/async/EventLoop.java index b619a3fb8..73d76f879 100644 --- a/client/src/com/aerospike/client/async/EventLoop.java +++ b/client/src/com/aerospike/client/async/EventLoop.java @@ -22,7 +22,24 @@ import com.aerospike.client.cluster.Node; /** - * Aerospike event loop interface. + * Aerospike event loop interface. One event loop is used to run async commands; obtain from + * {@link EventLoops#next()} or {@link EventLoops#get(int)} and pass to async API methods. + *

+ * Implementations: {@link NioEventLoop}, {@link NettyEventLoop} (obtained via {@link EventLoops}, not constructed directly). + *

Obtain an event loop from EventLoops and pass it to async get.

+ *
{@code
+ * EventLoops eventLoops = new NioEventLoops(2);
+ * IAerospikeClient client = new AerospikeClient(new ClientPolicy(), new Host("localhost", 3000), eventLoops);
+ * EventLoop eventLoop = eventLoops.next();
+ * client.get(eventLoop, new RecordListener() {
+ *   public void onSuccess(Key key, Record record) { }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, key);
+ * }
+ * + * @see NioEventLoop + * @see NettyEventLoop + * @see EventLoops */ public interface EventLoop { /** diff --git a/client/src/com/aerospike/client/async/EventLoopType.java b/client/src/com/aerospike/client/async/EventLoopType.java index f2073b7e4..3f40bffb5 100644 --- a/client/src/com/aerospike/client/async/EventLoopType.java +++ b/client/src/com/aerospike/client/async/EventLoopType.java @@ -17,7 +17,13 @@ package com.aerospike.client.async; /** - * Type of async event loop used. + * Type of async event loop used. Used by {@link NettyEventLoops} to select transport (NIO, epoll, kqueue, io_uring). + *

Pass EventLoopType when creating NettyEventLoops to choose transport.

+ *
{@code
+ * EventLoopGroup group = new NioEventLoopGroup(4);
+ * EventLoops eventLoops = new NettyEventLoops(new EventPolicy(), group, EventLoopType.NETTY_NIO);
+ * IAerospikeClient client = new AerospikeClient(new ClientPolicy(), new Host("localhost", 3000), eventLoops);
+ * }
*/ public enum EventLoopType { /** diff --git a/client/src/com/aerospike/client/async/EventLoops.java b/client/src/com/aerospike/client/async/EventLoops.java index a2741122c..1bd4a95ac 100644 --- a/client/src/com/aerospike/client/async/EventLoops.java +++ b/client/src/com/aerospike/client/async/EventLoops.java @@ -19,7 +19,22 @@ import java.io.Closeable; /** - * Aerospike event loops interface. + * Aerospike event loops interface. Supplies event loops for async operations; pass to + * {@link com.aerospike.client.AerospikeClient} + * or use with {@link EventLoop#execute(Runnable)}. + *

+ * Implementations: {@link NioEventLoops}, {@link NettyEventLoops}. + *

Create NioEventLoops or NettyEventLoops and pass to AerospikeClient for async usage.

+ *
{@code
+ * EventLoops eventLoops = new NioEventLoops(2);
+ * IAerospikeClient client = new AerospikeClient(new ClientPolicy(), new Host("localhost", 3000), eventLoops);
+ * EventLoop loop = eventLoops.next();
+ * client.put(loop, writeListener, null, key, bins);
+ * eventLoops.close();
+ * }
+ * + * @see NioEventLoops + * @see NettyEventLoops */ public interface EventLoops extends Closeable { /** diff --git a/client/src/com/aerospike/client/async/EventPolicy.java b/client/src/com/aerospike/client/async/EventPolicy.java index 7971cd5cb..d0e8d7832 100644 --- a/client/src/com/aerospike/client/async/EventPolicy.java +++ b/client/src/com/aerospike/client/async/EventPolicy.java @@ -17,7 +17,16 @@ package com.aerospike.client.async; /** - * Asynchronous event loop configuration. + * Asynchronous event loop configuration. Used when creating {@link NioEventLoops} or + * {@link NettyEventLoops} to limit commands in process and delay queue size. + *

Set maxCommandsInProcess and maxCommandsInQueue then pass policy to NioEventLoops.

+ *
{@code
+ * EventPolicy policy = new EventPolicy();
+ * policy.maxCommandsInProcess = 40;
+ * policy.maxCommandsInQueue = 1000;
+ * EventLoops eventLoops = new NioEventLoops(policy, 4);
+ * IAerospikeClient client = new AerospikeClient(new ClientPolicy(), new Host("localhost", 3000), eventLoops);
+ * }
*/ public final class EventPolicy { /** diff --git a/client/src/com/aerospike/client/async/NettyEventLoops.java b/client/src/com/aerospike/client/async/NettyEventLoops.java index 8cfc996a6..41e8550cc 100644 --- a/client/src/com/aerospike/client/async/NettyEventLoops.java +++ b/client/src/com/aerospike/client/async/NettyEventLoops.java @@ -36,8 +36,18 @@ import io.netty.util.concurrent.EventExecutor; /** - * Aerospike wrapper around netty event loops. - * Implements the Aerospike EventLoops interface. + * Aerospike wrapper around Netty event loops. Implements {@link EventLoops}; create from a + * Netty {@link io.netty.channel.EventLoopGroup} and pass to + * {@link com.aerospike.client.AerospikeClient}. + *

Wrap an existing Netty EventLoopGroup and use with AerospikeClient for async operations.

+ *
{@code
+ * EventLoopGroup group = new NioEventLoopGroup(4);
+ * EventLoops eventLoops = new NettyEventLoops(group);
+ * IAerospikeClient client = new AerospikeClient(new ClientPolicy(), new Host("localhost", 3000), eventLoops);
+ * EventLoop loop = eventLoops.next();
+ * client.get(loop, recordListener, null, key);
+ * eventLoops.close();
+ * }
*/ public final class NettyEventLoops implements EventLoops { diff --git a/client/src/com/aerospike/client/async/NioEventLoops.java b/client/src/com/aerospike/client/async/NioEventLoops.java index 9cb22dba0..e957dbf28 100644 --- a/client/src/com/aerospike/client/async/NioEventLoops.java +++ b/client/src/com/aerospike/client/async/NioEventLoops.java @@ -23,7 +23,16 @@ import com.aerospike.client.util.Util; /** - * Asynchronous event loops. + * Asynchronous event loops using direct NIO. Implements {@link EventLoops}; create and pass to + * {@link com.aerospike.client.AerospikeClient} + *

Create NIO event loops (e.g. 2 or 4) and use with AerospikeClient for async operations.

+ *
{@code
+ * EventLoops eventLoops = new NioEventLoops(4);
+ * IAerospikeClient client = new AerospikeClient(new ClientPolicy(), new Host("localhost", 3000), eventLoops);
+ * EventLoop loop = eventLoops.next();
+ * client.get(loop, recordListener, null, key);
+ * eventLoops.close();
+ * }
*/ public final class NioEventLoops implements EventLoops { diff --git a/client/src/com/aerospike/client/cdt/ListOperation.java b/client/src/com/aerospike/client/cdt/ListOperation.java index 44ea0be62..4c5358a66 100644 --- a/client/src/com/aerospike/client/cdt/ListOperation.java +++ b/client/src/com/aerospike/client/cdt/ListOperation.java @@ -24,34 +24,54 @@ import com.aerospike.client.util.Packer; /** - * List bin operations. Create list operations used by client operate command. + * List bin operations for the client operate command. List operations support negative indexing. + * Index out of bounds returns a parameter error; a range partially out of bounds returns the valid + * part. Use optional {@link CTX} for nested list/map paths. Prefer {@link #appendItems} over + * multiple {@link #append} for better performance. *

- * List operations support negative indexing. If the index is negative, the - * resolved index starts backwards from end of list. If an index is out of bounds, - * a parameter error will be returned. If a range is partially out of bounds, the - * valid part of the range will be returned. Index/Range examples: + * Index (item offset from start; negative = from end): *

    - *
  • Index 0: First item in list.
  • - *
  • Index 4: Fifth item in list.
  • - *
  • Index -1: Last item in list.
  • - *
  • Index -3: Third to last item in list.
  • - *
  • Index 1 Count 2: Second and third items in list.
  • - *
  • Index -3 Count 3: Last three items in list.
  • - *
  • Index -5 Count 4: Range between fifth to last item to second to last item inclusive.
  • - *
- *

- * Nested CDT operations are supported by optional CTX context arguments. Examples: - *

    - *
  • bin = [[7,9,5],[1,2,3],[6,5,4,1]]
  • - *
  • Append 11 to last list.
  • - *
  • ListOperation.append("bin", Value.get(11), CTX.listIndex(-1))
  • - *
  • bin result = [[7,9,5],[1,2,3],[6,5,4,1,11]]
  • - *
  • - *
  • bin = {key1=[[7,9,5],[13]], key2=[[9],[2,4],[6,1,9]], key3=[[6,5]]}
  • - *
  • Append 11 to lowest ranked list in map identified by "key2".
  • - *
  • ListOperation.append("bin", Value.get(11), CTX.mapKey(Value.get("key2")), CTX.listRank(0))
  • - *
  • bin result = {key1=[[7,9,5],[13]], key2=[[9],[2,4,11],[6,1,9]], key3=[[6,5]]}
  • + *
  • Index 0: first item; 4: fifth item; -1: last item; -3: third to last.
  • + *
  • Index 1 Count 2: second and third items; Index -3 Count 3: last three items.
  • + *
  • Index -5 Count 4: range from fifth-to-last to second-to-last inclusive.
  • *
+ *

Append, pop, size, appendItems, getRange; get by index/range; nested append with CTX.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Key key = new Key("ns", "set", "listkey");
+ * client.delete(null, key);
+ *
+ * Record rec = client.operate(null, key,
+ *     ListOperation.append("bin", Value.get(55)),
+ *     ListOperation.append("bin", Value.get(77)),
+ *     ListOperation.pop("bin", -1),
+ *     ListOperation.size("bin"));
+ * long size = (Long) rec.getList("bin").get(3);
+ *
+ * java.util.List itemList = new java.util.ArrayList<>();
+ * itemList.add(Value.get(12));
+ * itemList.add(Value.get("my string"));
+ * client.operate(null, key, ListOperation.appendItems("bin", itemList));
+ * rec = client.operate(null, key, ListOperation.getRange("bin", 0, 4));
+ * java.util.List range = (java.util.List) rec.getList("bin").get(0);
+ *
+ * // Index/range: get by index 0 or -1, range (1, 2), last three (-3, 3), -5 count 4
+ * client.operate(null, key, ListOperation.getByIndex("bin", 0, ListReturnType.VALUE));
+ * client.operate(null, key, ListOperation.getByIndex("bin", -1, ListReturnType.VALUE));
+ * client.operate(null, key, ListOperation.getByIndexRange("bin", 1, 2, ListReturnType.VALUE));
+ * client.operate(null, key, ListOperation.getByIndexRange("bin", -3, 3, ListReturnType.VALUE));
+ * client.operate(null, key, ListOperation.getByIndexRange("bin", -5, 4, ListReturnType.VALUE));
+ *
+ * // Nested: append 11 to last list (bin = [[7,9,5],[1,2,3],[6,5,4,1]] -> last list gets 11)
+ * client.operate(null, key, ListOperation.append("bin", Value.get(11), CTX.listIndex(-1)));
+ * // Nested with map: append 11 to lowest-ranked list in map "key2"
+ * client.operate(null, key, ListOperation.append("bin", Value.get(11), CTX.mapKey(Value.get("key2")), CTX.listRank(0)));
+ * }
+ * + * @see com.aerospike.client.AerospikeClient#operate + * @see CTX + * @see ListPolicy + * @see ListReturnType */ public class ListOperation { private static final int SET_TYPE = 0; diff --git a/client/src/com/aerospike/client/cdt/ListReturnType.java b/client/src/com/aerospike/client/cdt/ListReturnType.java index 6b764d591..ce6903f25 100644 --- a/client/src/com/aerospike/client/cdt/ListReturnType.java +++ b/client/src/com/aerospike/client/cdt/ListReturnType.java @@ -80,9 +80,9 @@ public final class ListReturnType { public static final int EXISTS = 13; /** - * Invert meaning of list command and return values. For example: + * Invert meaning of list command and return values. + *

With INVERTED, items outside the specified index range are removed and returned.

*
{@code ListOperation.removeByIndexRange(binName, index, count, ListReturnType.VALUE | ListReturnType.INVERTED);}
- * With the INVERTED flag enabled, the items outside of the specified index range will be removed and returned. */ public static final int INVERTED = 0x10000; } diff --git a/client/src/com/aerospike/client/cdt/ListWriteFlags.java b/client/src/com/aerospike/client/cdt/ListWriteFlags.java index 5680e63ff..b6ac8c1f5 100644 --- a/client/src/com/aerospike/client/cdt/ListWriteFlags.java +++ b/client/src/com/aerospike/client/cdt/ListWriteFlags.java @@ -17,8 +17,8 @@ package com.aerospike.client.cdt; /** - * List write bit flags. Use BITWISE OR to combine flags. Example: - * + * List write bit flags. Use BITWISE OR to combine flags. + *

Combine flags with bitwise OR for list operations.

*
{@code 
  * int flags = ListWriteFlags.ADD_UNIQUE | ListWriteFlags.NO_FAIL | ListWriteFlags.PARTIAL;
  * }
diff --git a/client/src/com/aerospike/client/cdt/MapOperation.java b/client/src/com/aerospike/client/cdt/MapOperation.java index 1329ab6a3..d4b070565 100644 --- a/client/src/com/aerospike/client/cdt/MapOperation.java +++ b/client/src/com/aerospike/client/cdt/MapOperation.java @@ -25,53 +25,58 @@ import com.aerospike.client.util.Packer; /** - * Map bin operations. Create map operations used by the client operate command. - * The default unique key map is unordered. Valid map key types are: - *
    - *
  • String
  • - *
  • Integer
  • - *
  • byte[]
  • - *
- *

- * The server will validate map key types in an upcoming release. - *

- * All maps maintain an index and a rank. The index is the item offset from the start of the map, - * for both unordered and ordered maps. The rank is the sorted index of the value component. - * Map supports negative indexing for index and rank. + * Map bin operations for the client operate command. Default unique-key map is unordered. Valid + * map key types: String, Integer, byte[] (server will validate in an upcoming release). Maps have + * index (item offset) and rank (sorted index of value component); both support negative indexing. + * Use optional {@link CTX} for nested CDT paths. *

- * Index examples: + * Index (item offset from start; negative = from end): *

    - *
  • Index 0: First item in map.
  • - *
  • Index 4: Fifth item in map.
  • - *
  • Index -1: Last item in map.
  • - *
  • Index -3: Third to last item in map.
  • - *
  • Index 1 Count 2: Second and third items in map.
  • - *
  • Index -3 Count 3: Last three items in map.
  • - *
  • Index -5 Count 4: Range between fifth to last item to second to last item inclusive.
  • + *
  • Index 0: first item; 4: fifth item; -1: last item; -3: third to last.
  • + *
  • Index 1 Count 2: second and third items; Index -3 Count 3: last three items.
  • + *
  • Index -5 Count 4: range from fifth-to-last to second-to-last inclusive.
  • *
- *

- * Rank examples: + * Rank (sorted index of value; negative = from highest): *

    - *
  • Rank 0: Item with lowest value rank in map.
  • - *
  • Rank 4: Fifth lowest ranked item in map.
  • - *
  • Rank -1: Item with highest ranked value in map.
  • - *
  • Rank -3: Item with third highest ranked value in map.
  • - *
  • Rank 1 Count 2: Second and third lowest ranked items in map.
  • - *
  • Rank -3 Count 3: Top three ranked items in map.
  • - *
- *

- * Nested CDT operations are supported by optional CTX context arguments. Examples: - *

    - *
  • bin = {key1={key11=9,key12=4}, key2={key21=3,key22=5}}
  • - *
  • Set map value to 11 for map key "key21" inside of map key "key2".
  • - *
  • MapOperation.put(MapPolicy.Default, "bin", Value.get("key21"), Value.get(11), CTX.mapKey(Value.get("key2")))
  • - *
  • bin result = {key1={key11=9,key12=4},key2={key21=11,key22=5}}
  • - *
  • - *
  • bin = {key1={key11={key111=1},key12={key121=5}}, key2={key21={"key211",7}}}
  • - *
  • Set map value to 11 in map key "key121" for highest ranked map ("key12") inside of map key "key1".
  • - *
  • MapOperation.put(MapPolicy.Default, "bin", Value.get("key121"), Value.get(11), CTX.mapKey(Value.get("key1")), CTX.mapRank(-1))
  • - *
  • bin result = {key1={key11={key111=1},key12={key121=11}}, key2={key21={"key211",7}}}
  • + *
  • Rank 0: lowest ranked value; 4: fifth lowest; -1: highest ranked; -3: third highest.
  • + *
  • Rank 1 Count 2: second and third lowest; Rank -3 Count 3: top three ranked.
  • *
+ *

Put, getByKey, size, putItems; get by index/rank; nested put with CTX.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Key key = new Key("ns", "set", "mapkey");
+ * client.delete(null, key);
+ *
+ * client.operate(null, key,
+ *     MapOperation.put(MapPolicy.Default, "bin", Value.get("name"), Value.get("Alice")),
+ *     MapOperation.put(MapPolicy.Default, "bin", Value.get("score"), Value.get(100)));
+ * Record rec = client.operate(null, key,
+ *     MapOperation.getByKey("bin", Value.get("name"), MapReturnType.VALUE),
+ *     MapOperation.size("bin"));
+ * String name = (String) rec.getList("bin").get(0);
+ * long size = (Long) rec.getList("bin").get(1);
+ *
+ * java.util.Map items = new java.util.HashMap<>();
+ * items.put(Value.get("a"), Value.get(1));
+ * items.put(Value.get("b"), Value.get(2));
+ * client.operate(null, key, MapOperation.putItems(MapPolicy.Default, "bin", items));
+ *
+ * // Index/rank: get by index 0 or -1, by rank 0 or -1
+ * client.operate(null, key, MapOperation.getByIndex("bin", 0, MapReturnType.VALUE));
+ * client.operate(null, key, MapOperation.getByIndex("bin", -1, MapReturnType.VALUE));
+ * client.operate(null, key, MapOperation.getByRank("bin", 0, MapReturnType.VALUE));
+ * client.operate(null, key, MapOperation.getByRank("bin", -1, MapReturnType.VALUE));
+ *
+ * // Nested: put value 11 at key "key21" inside map key "key2"
+ * client.operate(null, key, MapOperation.put(MapPolicy.Default, "bin", Value.get("key21"), Value.get(11), CTX.mapKey(Value.get("key2"))));
+ * // Nested with rank: put 11 at "key121" in highest-ranked map in "key1"
+ * client.operate(null, key, MapOperation.put(MapPolicy.Default, "bin", Value.get("key121"), Value.get(11), CTX.mapKey(Value.get("key1")), CTX.mapRank(-1)));
+ * }
+ * + * @see com.aerospike.client.AerospikeClient#operate + * @see CTX + * @see MapPolicy + * @see MapReturnType */ public class MapOperation { private static final int SET_TYPE = 64; diff --git a/client/src/com/aerospike/client/cdt/MapReturnType.java b/client/src/com/aerospike/client/cdt/MapReturnType.java index 755a5828d..99d3f9a6d 100644 --- a/client/src/com/aerospike/client/cdt/MapReturnType.java +++ b/client/src/com/aerospike/client/cdt/MapReturnType.java @@ -105,9 +105,9 @@ public final class MapReturnType { public static final int ORDERED_MAP = 17; /** - * Invert meaning of map command and return values. For example: + * Invert meaning of map command and return values. + *

With INVERTED, keys outside the specified key range are removed and returned.

*
{@code MapOperation.removeByKeyRange(binName, keyBegin, keyEnd, MapReturnType.KEY | MapReturnType.INVERTED);}
- * With the INVERTED flag enabled, the keys outside of the specified key range will be removed and returned. */ public static final int INVERTED = 0x10000; } diff --git a/client/src/com/aerospike/client/cdt/MapWriteFlags.java b/client/src/com/aerospike/client/cdt/MapWriteFlags.java index 3aea468a8..f0fbaedf7 100644 --- a/client/src/com/aerospike/client/cdt/MapWriteFlags.java +++ b/client/src/com/aerospike/client/cdt/MapWriteFlags.java @@ -17,8 +17,8 @@ package com.aerospike.client.cdt; /** - * Map write bit flags. Use BITWISE OR to combine flags. Example: - * + * Map write bit flags. Use BITWISE OR to combine flags. + *

Combine flags with bitwise OR for map operations.

*
{@code 
  * int flags = MapWriteFlags.UPDATE_ONLY | MapWriteFlags.NO_FAIL | MapWriteFlags.PARTIAL;
  * }
diff --git a/client/src/com/aerospike/client/cluster/Connection.java b/client/src/com/aerospike/client/cluster/Connection.java index 0ed06c28a..ef82781eb 100644 --- a/client/src/com/aerospike/client/cluster/Connection.java +++ b/client/src/com/aerospike/client/cluster/Connection.java @@ -326,14 +326,49 @@ public void close() { } } + /** + * Thrown when a read from the server connection does not complete within the socket timeout. + * + *

Holds the buffer state at the time of timeout for debugging. This is a low-level exception + * typically wrapped or translated by the client; application code usually catches + * {@link com.aerospike.client.AerospikeException.Timeout} instead. + *

Catch {@link com.aerospike.client.AerospikeException.Timeout} in application code; the cause may be ReadTimeout with buffer state for debugging.

+ *
{@code
+	 * try {
+	 *   client.get(null, key);
+	 * } catch (com.aerospike.client.AerospikeException.Timeout e) {
+	 *   if (e.getCause() instanceof Connection.ReadTimeout) {
+	 *     Connection.ReadTimeout rt = (Connection.ReadTimeout) e.getCause();
+	 *     // rt.buffer, rt.offset, rt.length, rt.state for debugging
+	 *   }
+	 * }
+	 * }
+ * + * @see com.aerospike.client.AerospikeException.Timeout + */ public static final class ReadTimeout extends RuntimeException { private static final long serialVersionUID = 1L; + /** Buffer containing partial read data at timeout. */ public final byte[] buffer; + + /** Offset into buffer of the partial read. */ public final int offset; + + /** Length of data read so far. */ public final int length; + + /** Protocol state at timeout. */ public final byte state; + /** + * Constructs a read timeout with the given buffer state. + * + * @param buffer the buffer containing partial read data; may be {@code null} + * @param offset offset into the buffer + * @param length number of bytes read + * @param state protocol state byte + */ public ReadTimeout(byte[] buffer, int offset, int length, byte state) { super("timeout"); this.buffer = buffer; diff --git a/client/src/com/aerospike/client/configuration/ConfigurationProvider.java b/client/src/com/aerospike/client/configuration/ConfigurationProvider.java index 8e14cf013..517a3c02d 100644 --- a/client/src/com/aerospike/client/configuration/ConfigurationProvider.java +++ b/client/src/com/aerospike/client/configuration/ConfigurationProvider.java @@ -19,6 +19,30 @@ import com.aerospike.client.configuration.serializers.Configuration; +/** + * Supplies client configuration (static and dynamic). Used by policies and the client to load + * and fetch configuration. + *

+ * Implementations: {@link YamlConfigProvider} (YAML-based). Application code may implement this + * interface for custom configuration sources. + *

Use YamlConfigProvider from a file path, or implement a custom provider that returns Configuration from another source.

+ *
{@code
+ * // Built-in YAML provider (e.g. from env AEROSPIKE_CLIENT_CONFIG_URL or path)
+ * ConfigurationProvider provider = YamlConfigProvider.getConfigProvider("/path/to/config.yaml");
+ * if (provider != null && provider.loadConfiguration()) {
+ *   Configuration config = provider.fetchConfiguration();
+ * }
+ *
+ * // Custom provider (e.g. from remote or in-memory)
+ * ConfigurationProvider custom = new ConfigurationProvider() {
+ *   public boolean loadConfiguration() { return true; }
+ *   public Configuration fetchConfiguration() { return myConfig; }
+ *   public Configuration fetchDynamicConfiguration() { return myDynamicConfig; }
+ * };
+ * }
+ * + * @see YamlConfigProvider + */ public interface ConfigurationProvider { boolean loadConfiguration(); diff --git a/client/src/com/aerospike/client/exp/CdtExp.java b/client/src/com/aerospike/client/exp/CdtExp.java index b933391e6..f954b00cb 100644 --- a/client/src/com/aerospike/client/exp/CdtExp.java +++ b/client/src/com/aerospike/client/exp/CdtExp.java @@ -47,12 +47,20 @@ enum Type { } /** - * Create a CDT select expression. - * @param returnType - * @param flags - * @param bin - * @param ctx - * @return + * Create a CDT select expression that selects values at the given context path. + * Use with {@link Exp#build} and filter/expression policies or secondary index expressions. + *

Select list element at index 0 from bin "tags" for use in a filter or policy.

+ *
{@code
+     * // Select list element at index 0 from bin "tags"
+     * Exp exp = CdtExp.selectByPath(Exp.Type.LIST, Exp.SELECT_LIST_VALUE, Exp.bin("tags", Exp.Type.LIST), CTX.listIndex(0));
+     * Expression filter = Exp.build(exp);
+     * }
+ * + * @param returnType type of the selected value (e.g. {@link Exp.Type#INT}, {@link Exp.Type#LIST}) + * @param flags select flags (e.g. {@link Exp#SELECT_LIST_VALUE}, {@link Exp#SELECT_MAP_KEY_VALUE}) + * @param bin bin expression (e.g. {@link Exp#bin}); must not be null + * @param ctx context path into nested CDT (e.g. {@link CTX#listIndex}); may be empty for top-level + * @return expression that selects by path */ public static Exp selectByPath(Exp.Type returnType, int flags, Exp bin, CTX... ctx) { byte[] bytes = packCdtSelect(Type.SELECT, flags, ctx); @@ -61,13 +69,21 @@ public static Exp selectByPath(Exp.Type returnType, int flags, Exp bin, CTX... c } /** - * Create a CDT modify expression. - * @param returnType - * @param flags - * @param modifyExp - * @param bin - * @param ctx - * @return + * Create a CDT modify expression that modifies values at the given context path. + * Use with {@link Exp#build} in write/expression policies. + *

Increment integer at map key "count" in bin "stats" with a modify expression.

+ *
{@code
+     * // Increment integer at map key "count" in bin "stats"
+     * Exp modExp = CdtExp.modifyByPath(Exp.Type.INT, CdtExp.MODIFY, Exp.add(Exp.val(1)), Exp.bin("stats", Exp.Type.MAP), CTX.mapKey(com.aerospike.client.Value.get("count")));
+     * Expression exp = Exp.build(modExp);
+     * }
+ * + * @param returnType type of the modified value + * @param modifyFlag modify flag (e.g. {@link #MODIFY}, {@link Exp#MODIFY_APPLY}) + * @param modifyExp expression to apply at the path (e.g. {@link Exp#add}); must not be null + * @param bin bin expression (e.g. {@link Exp#bin}); must not be null + * @param ctx context path into nested CDT; may be empty for top-level + * @return expression that modifies by path */ public static Exp modifyByPath(Exp.Type returnType, int modifyFlag, Exp modifyExp, Exp bin, CTX... ctx) { byte[] bytes = packCdtModify(Type.SELECT, modifyFlag, modifyExp, ctx); diff --git a/client/src/com/aerospike/client/exp/ExpWriteFlags.java b/client/src/com/aerospike/client/exp/ExpWriteFlags.java index 2864a9738..2bd44850e 100644 --- a/client/src/com/aerospike/client/exp/ExpWriteFlags.java +++ b/client/src/com/aerospike/client/exp/ExpWriteFlags.java @@ -17,8 +17,8 @@ package com.aerospike.client.exp; /** - * Expression write bit flags. Use BITWISE OR to combine flags. Example: - * + * Expression write bit flags. Use BITWISE OR to combine flags. + *

Combine flags with bitwise OR for expression write operations.

*
{@code 
  * int flags = ExpWriteFlags.CREATE_ONLY | ExpWriteFlags.POLICY_NO_FAIL;
  * }
diff --git a/client/src/com/aerospike/client/exp/ListExp.java b/client/src/com/aerospike/client/exp/ListExp.java index e6319b4d5..2164b92d2 100644 --- a/client/src/com/aerospike/client/exp/ListExp.java +++ b/client/src/com/aerospike/client/exp/ListExp.java @@ -25,37 +25,49 @@ import com.aerospike.client.util.Packer; /** - * List expression generator. See {@link com.aerospike.client.exp.Exp}. + * List expression generator for filters and operate; see {@link Exp}. *

- * The bin expression argument in these methods can be a reference to a bin or the - * result of another expression. Expressions that modify bin values are only used - * for temporary expression evaluation and are not permanently applied to the bin. + * The bin argument can be a bin reference or an expression that returns a list. List modify + * expressions return the bin's value (a list, or a map when the list is nested in a map). Negative + * indexing is supported; index out of bounds returns a parameter error; a range partially out of + * bounds returns the valid part. Use optional {@link com.aerospike.client.cdt.CTX} for nested + * lists/maps. *

- * List modify expressions return the bin's value. This value will be a list except - * when the list is nested within a map. In that case, a map is returned for the - * list modify expression. - *

- * List expressions support negative indexing. If the index is negative, the - * resolved index starts backwards from end of list. If an index is out of bounds, - * a parameter error will be returned. If a range is partially out of bounds, the - * valid part of the range will be returned. Index/Range examples: + * Index (item offset from start; negative = from end): *

    - *
  • Index 0: First item in list.
  • - *
  • Index 4: Fifth item in list.
  • - *
  • Index -1: Last item in list.
  • - *
  • Index -3: Third to last item in list.
  • - *
  • Index 1 Count 2: Second and third items in list.
  • - *
  • Index -3 Count 3: Last three items in list.
  • - *
  • Index -5 Count 4: Range between fifth to last item to second to last item inclusive.
  • - *
- *

- * Nested expressions are supported by optional CTX context arguments. Example: - *

    - *
  • bin = [[7,9,5],[1,2,3],[6,5,4,1]]
  • - *
  • Get size of last list.
  • - *
  • ListExp.size(Exp.listBin("bin"), CTX.listIndex(-1))
  • - *
  • result = 4
  • + *
  • Index 0: first item; 4: fifth item; -1: last item; -3: third to last.
  • + *
  • Index 1 Count 2: second and third items; Index -3 Count 3: last three items.
  • + *
  • Index -5 Count 4: range from fifth-to-last to second-to-last inclusive.
  • *
+ *

Filter by list size, read by index/range, and nested CTX (e.g. size of last list).

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Key key = new Key("ns", "set", "mykey");
+ *
+ * // Filter by list size (e.g. list at CTX listIndex 4 has size 6)
+ * Policy policy = new Policy();
+ * policy.filterExp = Exp.build(Exp.eq(ListExp.size(Exp.listBin("A"), CTX.listIndex(4)), Exp.val(6)));
+ * Record rec = client.get(policy, key);
+ *
+ * // Index: first (0), last (-1), range second+third (1, count 2), last three (-3, count 3), -5 count 4
+ * Exp byIndex0 = ListExp.getByIndex(ListReturnType.VALUE, Exp.Type.INT, Exp.val(0), Exp.listBin("bin"));
+ * Exp byIndexLast = ListExp.getByIndex(ListReturnType.VALUE, Exp.Type.INT, Exp.val(-1), Exp.listBin("bin"));
+ * Exp byIndexRange = ListExp.getByIndexRange(ListReturnType.VALUE, Exp.val(1), Exp.val(2), Exp.listBin("bin"));
+ * Exp lastThree = ListExp.getByIndexRange(ListReturnType.VALUE, Exp.val(-3), Exp.val(3), Exp.listBin("bin"));
+ * Exp rangeFromFifthToLast = ListExp.getByIndexRange(ListReturnType.VALUE, Exp.val(-5), Exp.val(4), Exp.listBin("bin"));
+ *
+ * // List modify (returns bin value)
+ * Expression exp = Exp.build(ListExp.getByIndex(ListReturnType.VALUE, Exp.Type.INT, Exp.val(0), Exp.listBin("bin")));
+ * Record r = client.operate(null, key, ExpOperation.read("first", exp, ExpReadFlags.DEFAULT));
+ *
+ * // Nested: size of last list (bin = [[7,9,5],[1,2,3],[6,5,4,1]] -> result 4)
+ * Exp sizeOfLastList = ListExp.size(Exp.listBin("bin"), CTX.listIndex(-1));
+ * }
+ * + * @see Exp + * @see MapExp + * @see com.aerospike.client.cdt.CTX + * @see com.aerospike.client.cdt.ListReturnType */ public final class ListExp { private static final int MODULE = 0; diff --git a/client/src/com/aerospike/client/exp/MapExp.java b/client/src/com/aerospike/client/exp/MapExp.java index 367031cd0..3864eb8fb 100644 --- a/client/src/com/aerospike/client/exp/MapExp.java +++ b/client/src/com/aerospike/client/exp/MapExp.java @@ -24,58 +24,67 @@ import com.aerospike.client.util.Packer; /** - * Map expression generator. See {@link com.aerospike.client.exp.Exp}. + * Map expression generator for filters and operate; see {@link Exp}. *

- * The bin expression argument in these methods can be a reference to a bin or the - * result of another expression. Expressions that modify bin values are only used - * for temporary expression evaluation and are not permanently applied to the bin. + * The bin argument can be a bin reference or an expression that returns a map. Map modify + * expressions return the bin's value (a map, or a list when the map is nested in a list). Valid + * map key types: String, Integer, byte[]. Maps support index (item offset) and rank (sorted value + * index), including negative indexing; use optional {@link com.aerospike.client.cdt.CTX} for + * nested maps/lists. For loop variables in filters use {@link Exp#mapLoopVar}, {@link Exp#stringLoopVar} + * with {@link LoopVarPart}. *

- * Map modify expressions return the bin's value. This value will be a map except - * when the map is nested within a list. In that case, a list is returned for the - * map modify expression. - *

- * Valid map key types are: - *

    - *
  • String
  • - *
  • Integer
  • - *
  • byte[]
  • - *
- *

- * The server will validate map key types in an upcoming release. - *

- * All maps maintain an index and a rank. The index is the item offset from the start of the map, - * for both unordered and ordered maps. The rank is the sorted index of the value component. - * Map supports negative indexing for index and rank. - *

- * Index examples: - *

    - *
  • Index 0: First item in map.
  • - *
  • Index 4: Fifth item in map.
  • - *
  • Index -1: Last item in map.
  • - *
  • Index -3: Third to last item in map.
  • - *
  • Index 1 Count 2: Second and third items in map.
  • - *
  • Index -3 Count 3: Last three items in map.
  • - *
  • Index -5 Count 4: Range between fifth to last item to second to last item inclusive.
  • - *
- *

- * Rank examples: + * Index (item offset from start; negative = from end): *

    - *
  • Rank 0: Item with lowest value rank in map.
  • - *
  • Rank 4: Fifth lowest ranked item in map.
  • - *
  • Rank -1: Item with highest ranked value in map.
  • - *
  • Rank -3: Item with third highest ranked value in map.
  • - *
  • Rank 1 Count 2: Second and third lowest ranked items in map.
  • - *
  • Rank -3 Count 3: Top three ranked items in map.
  • + *
  • Index 0: first item; 4: fifth item; -1: last item; -3: third to last.
  • + *
  • Index 1 Count 2: second and third items; Index -3 Count 3: last three items.
  • + *
  • Index -5 Count 4: range from fifth-to-last to second-to-last inclusive.
  • *
- *

- * Nested expressions are supported by optional CTX context arguments. Example: + * Rank (sorted index of value; negative = from highest): *

    - *
  • bin = {key1={key11=9,key12=4}, key2={key21=3,key22=5}}
  • - *
  • Set map value to 11 for map key "key21" inside of map key "key2".
  • - *
  • Get size of map key2.
  • - *
  • MapExp.size(Exp.mapBin("bin"), CTX.mapKey(Value.get("key2"))
  • - *
  • result = 2
  • + *
  • Rank 0: lowest ranked value; 4: fifth lowest; -1: highest ranked; -3: third highest.
  • + *
  • Rank 1 Count 2: second and third lowest; Rank -3 Count 3: top three ranked.
  • *
+ *

Filter by map, read with index/rank and nested CTX, and use a loop variable.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Key key = new Key("ns", "set", "mykey");
+ *
+ * // Filter by map bin (key types: String, Integer, byte[])
+ * java.util.Map myMap = new java.util.HashMap<>();
+ * myMap.put("k", 1);
+ * Policy policy = new Policy();
+ * policy.filterExp = Exp.build(Exp.eq(Exp.mapBin("m"), Exp.val(myMap)));
+ * Record rec = client.get(policy, key);
+ *
+ * // Index: first (0), last (-1), range second+third (1, count 2), last three (-3, count 3)
+ * Exp byIndex0 = MapExp.getByIndex(MapReturnType.VALUE, Exp.Type.INT, Exp.val(0), Exp.mapBin("m"));
+ * Exp byIndexLast = MapExp.getByIndex(MapReturnType.VALUE, Exp.Type.INT, Exp.val(-1), Exp.mapBin("m"));
+ * Exp byIndexRange = MapExp.getByIndexRange(MapReturnType.KEY_VALUE, Exp.val(1), Exp.val(2), Exp.mapBin("m"));
+ * Exp lastThree = MapExp.getByIndexRange(MapReturnType.KEY_VALUE, Exp.val(-3), Exp.val(3), Exp.mapBin("m"));
+ *
+ * // Rank: lowest (0), highest (-1), second+third lowest (1, count 2), top three (-3, count 3)
+ * Exp byRank0 = MapExp.getByRank(MapReturnType.VALUE, Exp.Type.INT, Exp.val(0), Exp.mapBin("m"));
+ * Exp byRankLast = MapExp.getByRank(MapReturnType.VALUE, Exp.Type.INT, Exp.val(-1), Exp.mapBin("m"));
+ * Exp byRankRange = MapExp.getByRankRange(MapReturnType.KEY_VALUE, Exp.val(1), Exp.val(2), Exp.mapBin("m"));
+ * Exp topThree = MapExp.getByRankRange(MapReturnType.KEY_VALUE, Exp.val(-3), Exp.val(3), Exp.mapBin("m"));
+ *
+ * // Map modify (returns bin value)
+ * Expression exp = Exp.build(MapExp.removeByValue(MapReturnType.INVERTED, Exp.val(2), Exp.mapBin("m")));
+ * Record r = client.operate(null, key, ExpOperation.read("m", exp, ExpReadFlags.DEFAULT));
+ * java.util.Map result = r.getMap("m");
+ *
+ * // Nested map: size of map at key "key2" (bin = {key1={...}, key2={key21=3, key22=5}})
+ * Exp sizeExp = MapExp.size(Exp.mapBin("bin"), CTX.mapKey(com.aerospike.client.Value.get("key2")));
+ *
+ * // Loop variable in filter
+ * Exp getPrice = MapExp.getByKey(MapReturnType.VALUE, Exp.Type.FLOAT, Exp.val("price"), Exp.mapLoopVar(LoopVarPart.VALUE));
+ * }
+ * + * @see Exp + * @see ListExp + * @see LoopVarPart + * @see com.aerospike.client.cdt.CTX + * @see com.aerospike.client.cdt.MapReturnType */ public final class MapExp { private static final int MODULE = 0; @@ -114,8 +123,10 @@ public final class MapExp { /** * Create expression that writes key/value item to a map bin. The 'bin' expression should either * reference an existing map bin or be a expression that returns a map. - * + *

Add map entry with ExpOperation.write; combine with getByIndexRange to write from source map.

*
{@code
+	 * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+	 * Key key = new Key("ns", "set", "mykey");
 	 * // Add entry{11,22} to existing map bin.
 	 * Expression e = Exp.build(MapExp.put(MapPolicy.Default, Exp.val(11), Exp.val(22), Exp.mapBin(binName)));
 	 * client.operate(null, key, ExpOperation.write(binName, e, ExpWriteFlags.DEFAULT));
diff --git a/client/src/com/aerospike/client/listener/AbortListener.java b/client/src/com/aerospike/client/listener/AbortListener.java
index 9ccabd7f2..088b585eb 100644
--- a/client/src/com/aerospike/client/listener/AbortListener.java
+++ b/client/src/com/aerospike/client/listener/AbortListener.java
@@ -20,6 +20,17 @@
 
 /**
  * Asynchronous result notifications for transaction aborts.
+ * 

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#abort(com.aerospike.client.async.EventLoop, AbortListener, com.aerospike.client.Txn) abort(EventLoop, AbortListener, ...)}. + *

Implement and pass to async abort to receive AbortStatus on success.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.abort(eventLoop, new AbortListener() {
+ *   public void onSuccess(AbortStatus status) { // done
+ *   }
+ * }, txn);
+ * }
*/ public interface AbortListener { /** diff --git a/client/src/com/aerospike/client/listener/BatchListListener.java b/client/src/com/aerospike/client/listener/BatchListListener.java index a72e6746b..bd5e2bd1b 100644 --- a/client/src/com/aerospike/client/listener/BatchListListener.java +++ b/client/src/com/aerospike/client/listener/BatchListListener.java @@ -24,6 +24,18 @@ /** * Asynchronous result notifications for batch get commands with variable bins per key. * The result is sent in a single list. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#get(com.aerospike.client.async.EventLoop, BatchListListener, com.aerospike.client.policy.BatchPolicy, java.util.List) get(EventLoop, BatchListListener, ...)}. + *

Implement and pass to async batch get (variable bins) to receive list of BatchRead on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.get(eventLoop, new BatchListListener() {
+ *   public void onSuccess(java.util.List records) { // use records
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, batchList);
+ * }
*/ public interface BatchListListener { /** diff --git a/client/src/com/aerospike/client/listener/BatchOperateListListener.java b/client/src/com/aerospike/client/listener/BatchOperateListListener.java index 0edf42005..904cb4622 100644 --- a/client/src/com/aerospike/client/listener/BatchOperateListListener.java +++ b/client/src/com/aerospike/client/listener/BatchOperateListListener.java @@ -23,6 +23,18 @@ /** * Asynchronous result notifications for batch operate commands with variable operations. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#operate(com.aerospike.client.async.EventLoop, BatchOperateListListener, com.aerospike.client.policy.BatchPolicy, java.util.List) operate(EventLoop, BatchOperateListListener, ...)}. + *

Implement and pass to async batch operate (variable ops) to receive list of BatchRecord and status on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.operate(eventLoop, new BatchOperateListListener() {
+ *   public void onSuccess(java.util.List records, boolean status) { // use records
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, batchList);
+ * }
*/ public interface BatchOperateListListener { /** diff --git a/client/src/com/aerospike/client/listener/BatchRecordArrayListener.java b/client/src/com/aerospike/client/listener/BatchRecordArrayListener.java index b13819507..0a9af63fb 100644 --- a/client/src/com/aerospike/client/listener/BatchRecordArrayListener.java +++ b/client/src/com/aerospike/client/listener/BatchRecordArrayListener.java @@ -21,6 +21,18 @@ /** * Asynchronous result notifications for batch operate commands. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#operate(com.aerospike.client.async.EventLoop, BatchRecordArrayListener, com.aerospike.client.policy.BatchPolicy, com.aerospike.client.BatchRecord[]) operate(EventLoop, BatchRecordArrayListener, ...)}. + *

Implement and pass to async batch operate to receive BatchRecord array and status on success or records plus exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.operate(eventLoop, new BatchRecordArrayListener() {
+ *   public void onSuccess(BatchRecord[] records, boolean status) { // use records
+ *   }
+ *   public void onFailure(BatchRecord[] records, AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, batchRecords);
+ * }
*/ public interface BatchRecordArrayListener { /** diff --git a/client/src/com/aerospike/client/listener/BatchRecordSequenceListener.java b/client/src/com/aerospike/client/listener/BatchRecordSequenceListener.java index 44cfb4e43..70bbb8b26 100644 --- a/client/src/com/aerospike/client/listener/BatchRecordSequenceListener.java +++ b/client/src/com/aerospike/client/listener/BatchRecordSequenceListener.java @@ -22,6 +22,19 @@ /** * Asynchronous result notifications for batch operate commands. * The results are sent one record at a time. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#operate(com.aerospike.client.async.EventLoop, BatchRecordSequenceListener, com.aerospike.client.policy.BatchPolicy, com.aerospike.client.BatchRecord[]) operate(EventLoop, BatchRecordSequenceListener, ...)}. + *

Implement and pass to async batch operate to receive each BatchRecord via onRecord, then onSuccess or onFailure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.operate(eventLoop, new BatchRecordSequenceListener() {
+ *   public void onRecord(BatchRecord record, int index) { // use record
+ *   }
+ *   public void onSuccess() { }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, batchRecords);
+ * }
*/ public interface BatchRecordSequenceListener { /** diff --git a/client/src/com/aerospike/client/listener/BatchSequenceListener.java b/client/src/com/aerospike/client/listener/BatchSequenceListener.java index 401b617bc..b3ada06c9 100644 --- a/client/src/com/aerospike/client/listener/BatchSequenceListener.java +++ b/client/src/com/aerospike/client/listener/BatchSequenceListener.java @@ -22,6 +22,19 @@ /** * Asynchronous result notifications for batch get commands with variable bins per key. * The results are sent one batch record at a time. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#get(com.aerospike.client.async.EventLoop, BatchSequenceListener, com.aerospike.client.policy.BatchPolicy, java.util.List) get(EventLoop, BatchSequenceListener, ...)}. + *

Implement and pass to async batch get (variable bins) to receive each BatchRead via onRecord, then onSuccess or onFailure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.get(eventLoop, new BatchSequenceListener() {
+ *   public void onRecord(BatchRead record) { // use record
+ *   }
+ *   public void onSuccess() { }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, batchList);
+ * }
*/ public interface BatchSequenceListener { /** diff --git a/client/src/com/aerospike/client/listener/ClusterStatsListener.java b/client/src/com/aerospike/client/listener/ClusterStatsListener.java index 45356638c..da2d84039 100644 --- a/client/src/com/aerospike/client/listener/ClusterStatsListener.java +++ b/client/src/com/aerospike/client/listener/ClusterStatsListener.java @@ -21,6 +21,18 @@ /** * Asynchronous result notifications for cluster statistics. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#getClusterStats(com.aerospike.client.async.EventLoop, ClusterStatsListener, com.aerospike.client.policy.InfoPolicy) getClusterStats(EventLoop, ClusterStatsListener, ...)}. + *

Implement and pass to async getClusterStats to receive ClusterStats on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.getClusterStats(eventLoop, new ClusterStatsListener() {
+ *   public void onSuccess(com.aerospike.client.cluster.ClusterStats stats) { // use stats
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null);
+ * }
*/ public interface ClusterStatsListener { /** diff --git a/client/src/com/aerospike/client/listener/CommitListener.java b/client/src/com/aerospike/client/listener/CommitListener.java index 358f89cde..02c191211 100644 --- a/client/src/com/aerospike/client/listener/CommitListener.java +++ b/client/src/com/aerospike/client/listener/CommitListener.java @@ -21,6 +21,18 @@ /** * Asynchronous result notifications for transaction commits. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#commit(com.aerospike.client.async.EventLoop, CommitListener, com.aerospike.client.policy.CommitPolicy, com.aerospike.client.Txn) commit(EventLoop, CommitListener, ...)}. + *

Implement and pass to async commit to receive CommitStatus on success or Commit exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.commit(eventLoop, new CommitListener() {
+ *   public void onSuccess(CommitStatus status) { // use status
+ *   }
+ *   public void onFailure(AerospikeException.Commit ae) { ae.printStackTrace(); }
+ * }, null, txn);
+ * }
*/ public interface CommitListener { /** diff --git a/client/src/com/aerospike/client/listener/DeleteListener.java b/client/src/com/aerospike/client/listener/DeleteListener.java index 1f345f94a..f1e9ad777 100644 --- a/client/src/com/aerospike/client/listener/DeleteListener.java +++ b/client/src/com/aerospike/client/listener/DeleteListener.java @@ -21,6 +21,18 @@ /** * Asynchronous result notifications for delete commands. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#delete(com.aerospike.client.async.EventLoop, DeleteListener, com.aerospike.client.policy.WritePolicy, com.aerospike.client.Key) delete(EventLoop, DeleteListener, ...)}. + *

Implement and pass to async delete to receive key and existed flag on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.delete(eventLoop, new DeleteListener() {
+ *   public void onSuccess(Key key, boolean existed) { // done
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, key);
+ * }
*/ public interface DeleteListener { /** diff --git a/client/src/com/aerospike/client/listener/ExecuteListener.java b/client/src/com/aerospike/client/listener/ExecuteListener.java index 6eea971e6..41214bca8 100644 --- a/client/src/com/aerospike/client/listener/ExecuteListener.java +++ b/client/src/com/aerospike/client/listener/ExecuteListener.java @@ -21,6 +21,18 @@ /** * Asynchronous result notifications for execute commands. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#execute(com.aerospike.client.async.EventLoop, ExecuteListener, com.aerospike.client.policy.WritePolicy, com.aerospike.client.Key, java.lang.String, java.lang.String, com.aerospike.client.Value[]) execute(EventLoop, ExecuteListener, ...)}. + *

Implement and pass to async execute to receive key and result object on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.execute(eventLoop, new ExecuteListener() {
+ *   public void onSuccess(Key key, Object obj) { // use obj
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, key, "module", "function", args);
+ * }
*/ public interface ExecuteListener { /** diff --git a/client/src/com/aerospike/client/listener/ExistsArrayListener.java b/client/src/com/aerospike/client/listener/ExistsArrayListener.java index b5b3dc486..1fe66321a 100644 --- a/client/src/com/aerospike/client/listener/ExistsArrayListener.java +++ b/client/src/com/aerospike/client/listener/ExistsArrayListener.java @@ -22,6 +22,18 @@ /** * Asynchronous result notifications for batch exists commands. * The result is sent in a single array. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#exists(com.aerospike.client.async.EventLoop, ExistsArrayListener, com.aerospike.client.policy.BatchPolicy, com.aerospike.client.Key[]) exists(EventLoop, ExistsArrayListener, ...)}. + *

Implement and pass to async batch exists to receive keys and exists array on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.exists(eventLoop, new ExistsArrayListener() {
+ *   public void onSuccess(Key[] keys, boolean[] exists) { // use exists
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, keys);
+ * }
*/ public interface ExistsArrayListener { /** diff --git a/client/src/com/aerospike/client/listener/ExistsListener.java b/client/src/com/aerospike/client/listener/ExistsListener.java index 81354007a..a63b7a086 100644 --- a/client/src/com/aerospike/client/listener/ExistsListener.java +++ b/client/src/com/aerospike/client/listener/ExistsListener.java @@ -21,6 +21,18 @@ /** * Asynchronous result notifications for exists commands. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#exists(com.aerospike.client.async.EventLoop, ExistsListener, com.aerospike.client.policy.Policy, com.aerospike.client.Key) exists(EventLoop, ExistsListener, ...)}. + *

Implement and pass to async exists to receive key and exists flag on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.exists(eventLoop, new ExistsListener() {
+ *   public void onSuccess(Key key, boolean exists) { // use exists
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, key);
+ * }
*/ public interface ExistsListener { /** diff --git a/client/src/com/aerospike/client/listener/ExistsSequenceListener.java b/client/src/com/aerospike/client/listener/ExistsSequenceListener.java index ee54acbbc..11f9a5694 100644 --- a/client/src/com/aerospike/client/listener/ExistsSequenceListener.java +++ b/client/src/com/aerospike/client/listener/ExistsSequenceListener.java @@ -22,6 +22,19 @@ /** * Asynchronous result notifications for batch exists commands. * The results are sent one record at a time. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#exists(com.aerospike.client.async.EventLoop, ExistsSequenceListener, com.aerospike.client.policy.BatchPolicy, com.aerospike.client.Key[]) exists(EventLoop, ExistsSequenceListener, ...)}. + *

Implement and pass to async batch exists to receive each key and exists flag via onExists, then onSuccess or onFailure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.exists(eventLoop, new ExistsSequenceListener() {
+ *   public void onExists(Key key, boolean exists) { // use per key
+ *   }
+ *   public void onSuccess() { }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, keys);
+ * }
*/ public interface ExistsSequenceListener { /** diff --git a/client/src/com/aerospike/client/listener/IndexListener.java b/client/src/com/aerospike/client/listener/IndexListener.java index c15ebb8eb..e42906d2f 100644 --- a/client/src/com/aerospike/client/listener/IndexListener.java +++ b/client/src/com/aerospike/client/listener/IndexListener.java @@ -21,6 +21,19 @@ /** * Asynchronous result notifications for create/drop index commands. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#createIndex(com.aerospike.client.async.EventLoop, IndexListener, com.aerospike.client.policy.InfoPolicy, java.lang.String, java.lang.String, java.lang.String, java.lang.String, com.aerospike.client.query.IndexType, com.aerospike.client.query.IndexCollectionType) createIndex(EventLoop, IndexListener, ...)} + * or dropIndex async methods. + *

Implement and pass to async createIndex/dropIndex to receive AsyncIndexTask on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.createIndex(eventLoop, new IndexListener() {
+ *   public void onSuccess(com.aerospike.client.async.AsyncIndexTask indexTask) { // poll task
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, "ns", "set", "idxName", "bin", IndexType.STRING, IndexCollectionType.DEFAULT);
+ * }
*/ public interface IndexListener { /** diff --git a/client/src/com/aerospike/client/listener/InfoListener.java b/client/src/com/aerospike/client/listener/InfoListener.java index f023b71cb..da9772213 100644 --- a/client/src/com/aerospike/client/listener/InfoListener.java +++ b/client/src/com/aerospike/client/listener/InfoListener.java @@ -22,6 +22,18 @@ /** * Asynchronous info command result notification. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#info(com.aerospike.client.async.EventLoop, InfoListener, com.aerospike.client.policy.InfoPolicy, com.aerospike.client.cluster.Node, java.lang.String...) info(EventLoop, InfoListener, ...)}. + *

Implement and pass to async info to receive map of key-value results on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.info(eventLoop, new InfoListener() {
+ *   public void onSuccess(java.util.Map map) { // use map
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, node, "stat");
+ * }
*/ public interface InfoListener { /** diff --git a/client/src/com/aerospike/client/listener/RecordArrayListener.java b/client/src/com/aerospike/client/listener/RecordArrayListener.java index d3132c854..77d25e0ab 100644 --- a/client/src/com/aerospike/client/listener/RecordArrayListener.java +++ b/client/src/com/aerospike/client/listener/RecordArrayListener.java @@ -23,6 +23,18 @@ /** * Asynchronous result notifications for batch get commands. * The result is sent in a single array. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#get(com.aerospike.client.async.EventLoop, RecordArrayListener, com.aerospike.client.policy.BatchPolicy, com.aerospike.client.Key[]) get(EventLoop, RecordArrayListener, ...)}. + *

Implement and pass to async batch get to receive keys and records array on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.get(eventLoop, new RecordArrayListener() {
+ *   public void onSuccess(Key[] keys, Record[] records) { // use records
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, keys);
+ * }
*/ public interface RecordArrayListener { /** diff --git a/client/src/com/aerospike/client/listener/RecordListener.java b/client/src/com/aerospike/client/listener/RecordListener.java index d75f5904a..a61a75fea 100644 --- a/client/src/com/aerospike/client/listener/RecordListener.java +++ b/client/src/com/aerospike/client/listener/RecordListener.java @@ -22,6 +22,19 @@ /** * Asynchronous result notifications for get or operate commands. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#get(com.aerospike.client.async.EventLoop, RecordListener, com.aerospike.client.policy.Policy, com.aerospike.client.Key) get(EventLoop, RecordListener, ...)} + * or operate async methods. + *

Implement and pass to async get to receive key and record on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.get(eventLoop, new RecordListener() {
+ *   public void onSuccess(Key key, Record record) { // use record
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, key);
+ * }
*/ public interface RecordListener { /** diff --git a/client/src/com/aerospike/client/listener/RecordSequenceListener.java b/client/src/com/aerospike/client/listener/RecordSequenceListener.java index ec56e342c..1e6f56b76 100644 --- a/client/src/com/aerospike/client/listener/RecordSequenceListener.java +++ b/client/src/com/aerospike/client/listener/RecordSequenceListener.java @@ -29,18 +29,38 @@ public interface RecordSequenceListener { * This method is called when an asynchronous record is received from the server. * The receive sequence is not ordered. *

- * If this listener is used in a scan/query command, The user may throw a - * {@link com.aerospike.client.AerospikeException.QueryTerminated AerospikeException.QueryTerminated} - * exception if the command should be aborted. If any exception is thrown, parallel command threads - * to other nodes will also be terminated and the exception will be propagated back through the - * onFailure() call. + * If this listener is used in a scan/query command, the user may throw + * {@link AerospikeException.QueryTerminated} or {@link AerospikeException.ScanTerminated} + * to abort. If any exception is thrown, parallel command threads to other nodes will also + * be terminated and the exception will be propagated back through {@link #onFailure(AerospikeException)}. *

- * If this listener is used in a batch command, an user thrown exception will terminate the batch - * to the current node, but parallel batch command threads to other nodes will continue to run. - * + * If this listener is used in a batch command, a user-thrown exception will terminate the batch + * to the current node, but parallel batch command threads to other nodes will continue to run. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#query(com.aerospike.client.async.EventLoop, RecordSequenceListener, com.aerospike.client.policy.QueryPolicy, com.aerospike.client.query.Statement) query(EventLoop, RecordSequenceListener, ...)} + * or batch get / scan async methods. + *

Implement and pass to async query to receive each record via onRecord, then onSuccess or onFailure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.query(eventLoop, new RecordSequenceListener() {
+ *   public void onRecord(Key key, Record record) throws AerospikeException {
+ *     if (record != null) {
+ *       System.out.println(key + " " + record.getString("name"));
+ *     }
+ *   }
+ *   public void onSuccess() { }
+ *   public void onFailure(AerospikeException e) { e.printStackTrace(); }
+ * }, null, stmt);
+ * }
+ * * @param key unique record identifier - * @param record record instance, will be null if the key is not found - * @throws AerospikeException if error occurs or scan should be terminated. + * @param record record instance; null if the key is not found + * @throws AerospikeException when an error occurs or the scan/query should be terminated (e.g. throw {@link AerospikeException.ScanTerminated} to abort). + * @see #onSuccess() + * @see #onFailure(AerospikeException) + * @see com.aerospike.client.AerospikeClient#query(com.aerospike.client.async.EventLoop, RecordSequenceListener, com.aerospike.client.policy.QueryPolicy, com.aerospike.client.query.Statement) + * @see com.aerospike.client.AerospikeClient#get(com.aerospike.client.async.EventLoop, RecordSequenceListener, com.aerospike.client.policy.BatchPolicy, com.aerospike.client.Key[]) */ public void onRecord(Key key, Record record) throws AerospikeException; diff --git a/client/src/com/aerospike/client/listener/TaskStatusListener.java b/client/src/com/aerospike/client/listener/TaskStatusListener.java index f3aed9ac1..da4e525e8 100644 --- a/client/src/com/aerospike/client/listener/TaskStatusListener.java +++ b/client/src/com/aerospike/client/listener/TaskStatusListener.java @@ -20,6 +20,18 @@ /** * Asynchronous result notifications for index status command. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#indexStatus(com.aerospike.client.async.EventLoop, TaskStatusListener, com.aerospike.client.policy.InfoPolicy, com.aerospike.client.task.Task) indexStatus(EventLoop, TaskStatusListener, ...)}. + *

Implement and pass to async indexStatus to receive status on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.indexStatus(eventLoop, new TaskStatusListener() {
+ *   public void onSuccess(int status) { // use status
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, task);
+ * }
*/ public interface TaskStatusListener { /** diff --git a/client/src/com/aerospike/client/listener/WriteListener.java b/client/src/com/aerospike/client/listener/WriteListener.java index 49b9cd09f..405c4ea83 100644 --- a/client/src/com/aerospike/client/listener/WriteListener.java +++ b/client/src/com/aerospike/client/listener/WriteListener.java @@ -21,6 +21,19 @@ /** * Asynchronous result notifications for put, append, prepend, add, delete and touch commands. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#put(com.aerospike.client.async.EventLoop, WriteListener, com.aerospike.client.policy.WritePolicy, com.aerospike.client.Key, com.aerospike.client.Bin[]) put(EventLoop, WriteListener, ...)} + * or other write async methods. + *

Implement and pass to async put to receive key on success or exception on failure.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.put(eventLoop, new WriteListener() {
+ *   public void onSuccess(Key key) { // done
+ *   }
+ *   public void onFailure(AerospikeException ae) { ae.printStackTrace(); }
+ * }, null, key, bins);
+ * }
*/ public interface WriteListener { /** diff --git a/client/src/com/aerospike/client/operation/BitOperation.java b/client/src/com/aerospike/client/operation/BitOperation.java index 5d1ddc495..e7b48d3f5 100644 --- a/client/src/com/aerospike/client/operation/BitOperation.java +++ b/client/src/com/aerospike/client/operation/BitOperation.java @@ -22,13 +22,21 @@ import com.aerospike.client.util.Packer; /** - * Bit operations. Create bit operations used by client operate command. - * Offset orientation is left-to-right. Negative offsets are supported. - * If the offset is negative, the offset starts backwards from end of the bitmap. - * If an offset is out of bounds, a parameter error will be returned. - *

- * Bit operations on bitmap items nested in lists/maps are not currently + * Bit operations for the client operate command. Create bit operations (resize, insert, set, get, + * count, add, etc.) and pass to {@link com.aerospike.client.AerospikeClient#operate}. Offset is + * left-to-right; negative offset is from end of bitmap. Nested bitmaps in lists/maps are not * supported by the server. + *

Resize a bit bin and perform get/count with BitOperation, then read result from operate.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Key key = new Key("ns", "set", "mykey");
+ * client.operate(null, key,
+ *   BitOperation.resize(BitPolicy.Default, "bits", 4, BitResizeFlags.DEFAULT),
+ *   BitOperation.get("bits", 0, 4),
+ *   BitOperation.count("bits", 0, -1));
+ * Record rec = client.operate(null, key, BitOperation.get("bits", 0, 4));
+ * byte[] bits = (byte[]) rec.getValue("bits");
+ * }
*/ public final class BitOperation { private static final int RESIZE = 0; diff --git a/client/src/com/aerospike/client/operation/BitOverflowAction.java b/client/src/com/aerospike/client/operation/BitOverflowAction.java index 1de69130b..ef844706f 100644 --- a/client/src/com/aerospike/client/operation/BitOverflowAction.java +++ b/client/src/com/aerospike/client/operation/BitOverflowAction.java @@ -17,7 +17,13 @@ package com.aerospike.client.operation; /** - * Action to take when bitwise add/subtract results in overflow/underflow. + * Action to take when bitwise add/subtract results in overflow/underflow. Use with + * {@link BitOperation#add} and + * {@link BitOperation#subtract}. + *

Use FAIL, SATURATE, or WRAP when adding/subtracting integer values in bit bins.

+ *
{@code
+ * client.operate(null, key, BitOperation.add(BitPolicy.Default, "bits", 0, 64, true, BitOverflowAction.SATURATE));
+ * }
*/ public enum BitOverflowAction { /** diff --git a/client/src/com/aerospike/client/operation/BitPolicy.java b/client/src/com/aerospike/client/operation/BitPolicy.java index 13f3d67a4..3a338c985 100644 --- a/client/src/com/aerospike/client/operation/BitPolicy.java +++ b/client/src/com/aerospike/client/operation/BitPolicy.java @@ -17,7 +17,14 @@ package com.aerospike.client.operation; /** - * Bit operation policy. + * Bit operation policy. Use with {@link BitOperation} (resize, insert, set, add, etc.); pass + * {@link #Default} or construct with {@link BitWriteFlags}. + *

Use default policy or custom flags when performing bit operations.

+ *
{@code
+ * BitPolicy policy = BitPolicy.Default;
+ * client.operate(null, key, BitOperation.resize(policy, "bits", 8, BitResizeFlags.DEFAULT));
+ * BitPolicy custom = new BitPolicy(BitWriteFlags.CREATE_ONLY | BitWriteFlags.NO_FAIL);
+ * }
*/ public final class BitPolicy { /** diff --git a/client/src/com/aerospike/client/operation/BitResizeFlags.java b/client/src/com/aerospike/client/operation/BitResizeFlags.java index 3e6231bef..120290d36 100644 --- a/client/src/com/aerospike/client/operation/BitResizeFlags.java +++ b/client/src/com/aerospike/client/operation/BitResizeFlags.java @@ -17,7 +17,13 @@ package com.aerospike.client.operation; /** - * Bitwise operation flags for resize. + * Bitwise operation flags for resize. Use with {@link BitOperation#resize(BitPolicy, String, int, int)}; + * combine with BITWISE OR if needed. + *

Use DEFAULT, FROM_FRONT, GROW_ONLY, or SHRINK_ONLY when resizing bit bins.

+ *
{@code
+ * client.operate(null, key, BitOperation.resize(BitPolicy.Default, "bits", 8, BitResizeFlags.DEFAULT));
+ * client.operate(null, key, BitOperation.resize(BitPolicy.Default, "bits", 16, BitResizeFlags.GROW_ONLY));
+ * }
*/ public final class BitResizeFlags { /** diff --git a/client/src/com/aerospike/client/operation/BitWriteFlags.java b/client/src/com/aerospike/client/operation/BitWriteFlags.java index 6b8e90810..192150e9e 100644 --- a/client/src/com/aerospike/client/operation/BitWriteFlags.java +++ b/client/src/com/aerospike/client/operation/BitWriteFlags.java @@ -17,8 +17,8 @@ package com.aerospike.client.operation; /** - * Bitwise operation policy write bit flags. Use BITWISE OR to combine flags. Example: - * + * Bitwise operation policy write bit flags. Use BITWISE OR to combine flags. + *

Combine flags with bitwise OR for bit operation write semantics.

*
{@code 
  * int flags = BitWriteFlags.NO_FAIL | BitWriteFlags.PARTIAL;
  * }
diff --git a/client/src/com/aerospike/client/operation/HLLOperation.java b/client/src/com/aerospike/client/operation/HLLOperation.java index a9acd2d85..3691d6e07 100644 --- a/client/src/com/aerospike/client/operation/HLLOperation.java +++ b/client/src/com/aerospike/client/operation/HLLOperation.java @@ -24,10 +24,21 @@ import com.aerospike.client.util.Pack; /** - * HyperLogLog (HLL) operations. - *

- * HyperLogLog operations on HLL items nested in lists/maps are not currently - * supported by the server. + * HyperLogLog (HLL) operations for the client operate command. Create HLL operations (init, add, + * setUnion, count, etc.) and pass to {@link com.aerospike.client.AerospikeClient#operate}. HLL + * items nested in lists/maps are not supported by the server. + *

Init HLL bin, add values, then get count with HLLOperation and read result from operate.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Key key = new Key("ns", "set", "mykey");
+ * java.util.List list = java.util.Arrays.asList(Value.get("a"), Value.get("b"), Value.get("c"));
+ * client.operate(null, key,
+ *   HLLOperation.init(HLLPolicy.Default, "hll", 14),
+ *   HLLOperation.add(HLLPolicy.Default, "hll", list),
+ *   HLLOperation.count("hll"));
+ * Record rec = client.operate(null, key, HLLOperation.count("hll"));
+ * long count = (Long) rec.getValue("hll");
+ * }
*/ public final class HLLOperation { private static final int INIT = 0; diff --git a/client/src/com/aerospike/client/operation/HLLPolicy.java b/client/src/com/aerospike/client/operation/HLLPolicy.java index 7100a6c4b..27e036037 100644 --- a/client/src/com/aerospike/client/operation/HLLPolicy.java +++ b/client/src/com/aerospike/client/operation/HLLPolicy.java @@ -17,7 +17,14 @@ package com.aerospike.client.operation; /** - * HyperLogLog operation policy. + * HyperLogLog operation policy. Use with {@link HLLOperation} (init, add, setUnion, count, etc.); + * pass {@link #Default} or construct with {@link HLLWriteFlags}. + *

Use default policy or custom flags when performing HLL operations.

+ *
{@code
+ * HLLPolicy policy = HLLPolicy.Default;
+ * client.operate(null, key, HLLOperation.init(policy, "hll", 14));
+ * HLLPolicy custom = new HLLPolicy(HLLWriteFlags.CREATE_ONLY | HLLWriteFlags.ALLOW_FOLD);
+ * }
*/ public final class HLLPolicy { /** diff --git a/client/src/com/aerospike/client/operation/HLLWriteFlags.java b/client/src/com/aerospike/client/operation/HLLWriteFlags.java index 171148ea7..f5066ab6c 100644 --- a/client/src/com/aerospike/client/operation/HLLWriteFlags.java +++ b/client/src/com/aerospike/client/operation/HLLWriteFlags.java @@ -17,8 +17,8 @@ package com.aerospike.client.operation; /** - * HyperLogLog operation policy write bit flags. Use BITWISE OR to combine flags. Example: - * + * HyperLogLog operation policy write bit flags. Use BITWISE OR to combine flags. + *

Combine flags with bitwise OR for HLL operation write semantics.

*
{@code 
  * int flags = HLLWriteFlags.CREATE_ONLY | HLLWriteFlags.NO_FAIL;
  * }
diff --git a/client/src/com/aerospike/client/policy/AdminPolicy.java b/client/src/com/aerospike/client/policy/AdminPolicy.java index 9d43ed6ca..67d3478ff 100644 --- a/client/src/com/aerospike/client/policy/AdminPolicy.java +++ b/client/src/com/aerospike/client/policy/AdminPolicy.java @@ -17,7 +17,16 @@ package com.aerospike.client.policy; /** - * Policy attributes used for user administration commands. + * Policy attributes used for user administration commands (create user, drop user, grant roles, etc.). + * Pass to {@link com.aerospike.client.AerospikeClient#createUser}, {@link com.aerospike.client.AerospikeClient#dropUser} + * and other admin methods. + *

Set timeout and pass to user administration commands.

+ *
{@code
+ * AdminPolicy policy = new AdminPolicy();
+ * policy.timeout = 5000;
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.createUser(policy, "newuser", "password", java.util.Collections.emptyList());
+ * }
*/ public final class AdminPolicy { /** diff --git a/client/src/com/aerospike/client/policy/BatchDeletePolicy.java b/client/src/com/aerospike/client/policy/BatchDeletePolicy.java index 3953190dc..c7560cd9d 100644 --- a/client/src/com/aerospike/client/policy/BatchDeletePolicy.java +++ b/client/src/com/aerospike/client/policy/BatchDeletePolicy.java @@ -24,7 +24,17 @@ import com.aerospike.client.exp.Expression; /** - * Policy attributes used in batch delete commands. + * Policy attributes used in batch delete commands. Used with {@link BatchPolicy} and + * {@link com.aerospike.client.AerospikeClient#delete(com.aerospike.client.policy.BatchPolicy, java.util.List)}; + * defines filterExp, commitLevel, etc. + *

Set commit level or filterExp and use as batch delete default or per-key policy.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * BatchDeletePolicy policy = new BatchDeletePolicy();
+ * policy.commitLevel = CommitLevel.COMMIT_MASTER;
+ * BatchPolicy batchPolicy = new BatchPolicy();
+ * client.delete(batchPolicy, keys);
+ * }
*/ public final class BatchDeletePolicy { /** diff --git a/client/src/com/aerospike/client/policy/BatchPolicy.java b/client/src/com/aerospike/client/policy/BatchPolicy.java index cf7b168f0..4a7b9f1e3 100644 --- a/client/src/com/aerospike/client/policy/BatchPolicy.java +++ b/client/src/com/aerospike/client/policy/BatchPolicy.java @@ -26,7 +26,27 @@ import java.util.Objects; /** - * Batch parent policy. + * Base policy for batch operations (batch get, batch exists, batch write, batch UDF, etc.). + * + *

Defines concurrency (maxConcurrentThreads), allowInline, and other batch-level options. Subclasses + * and companion policies (e.g. {@link BatchWritePolicy}, {@link BatchDeletePolicy}) add operation-specific options. + * Pass to {@link com.aerospike.client.AerospikeClient#get(Policy, List)} and other batch methods. + * + *

Set maxConcurrentThreads, allowInline and pass to batch get or other batch methods.

+ *
{@code
+ * BatchPolicy policy = new BatchPolicy();
+ * policy.maxConcurrentThreads = 0;   // 0=parallel, 1=sequential (default), >1=cap
+ * policy.allowInline = true;         // inline for in-memory (default)
+ * policy.allowInlineSSD = false;     // no inline for SSD (default)
+ * policy.respondAllKeys = true;      // attempt all keys despite errors (default)
+ * policy.totalTimeout = 5000;       // from Policy: total batch timeout
+ * policy.socketTimeout = 2000;       // from Policy: per-socket timeout
+ * client.get(policy, keys);
+ * }
+ * + * @see Policy + * @see BatchWritePolicy + * @see BatchDeletePolicy */ public class BatchPolicy extends Policy { /** diff --git a/client/src/com/aerospike/client/policy/BatchReadPolicy.java b/client/src/com/aerospike/client/policy/BatchReadPolicy.java index 88cd54e3d..c13958668 100644 --- a/client/src/com/aerospike/client/policy/BatchReadPolicy.java +++ b/client/src/com/aerospike/client/policy/BatchReadPolicy.java @@ -19,7 +19,17 @@ import com.aerospike.client.exp.Expression; /** - * Policy attributes used in batch read commands. + * Policy attributes used in batch read commands. Used with {@link BatchPolicy} and + * {@link com.aerospike.client.AerospikeClient#get(com.aerospike.client.policy.BatchPolicy, java.util.List)} + * when a per-key or default batch read policy is needed (filterExp, readModeAP, readModeSC). + *

Set filterExp or replica read mode and use as batch read default or per-key policy.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * BatchReadPolicy policy = new BatchReadPolicy();
+ * policy.filterExp = Exp.build(Exp.eq(Exp.intBin("a"), Exp.val(1)));
+ * BatchPolicy batchPolicy = BatchPolicy.ReadDefault();
+ * client.get(batchPolicy, keys);
+ * }
*/ public final class BatchReadPolicy { /** diff --git a/client/src/com/aerospike/client/policy/BatchUDFPolicy.java b/client/src/com/aerospike/client/policy/BatchUDFPolicy.java index 525468837..7b25484a2 100644 --- a/client/src/com/aerospike/client/policy/BatchUDFPolicy.java +++ b/client/src/com/aerospike/client/policy/BatchUDFPolicy.java @@ -24,7 +24,16 @@ import com.aerospike.client.exp.Expression; /** - * Policy attributes used in batch UDF execute commands. + * Policy attributes used in batch UDF execute commands. Used with {@link BatchPolicy} and + * {@link com.aerospike.client.AerospikeClient#execute(com.aerospike.client.policy.BatchPolicy, java.util.List)}; + * defines filterExp, commitLevel, etc. + *

Set commit level or filterExp and use as batch UDF default or per-key policy.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * BatchUDFPolicy policy = new BatchUDFPolicy();
+ * BatchPolicy batchPolicy = new BatchPolicy();
+ * client.execute(batchPolicy, batchRecords);
+ * }
*/ public final class BatchUDFPolicy { /** diff --git a/client/src/com/aerospike/client/policy/BatchWritePolicy.java b/client/src/com/aerospike/client/policy/BatchWritePolicy.java index d33c0b9d4..120627940 100644 --- a/client/src/com/aerospike/client/policy/BatchWritePolicy.java +++ b/client/src/com/aerospike/client/policy/BatchWritePolicy.java @@ -24,7 +24,17 @@ import com.aerospike.client.exp.Expression; /** - * Policy attributes used in batch write commands. + * Policy attributes used in batch write commands. Used with {@link BatchPolicy} and + * {@link com.aerospike.client.AerospikeClient#put(com.aerospike.client.policy.BatchPolicy, java.util.List)} + * or batch operate; defines recordExistsAction, generationPolicy, etc. per batch or per key. + *

Set record-exists action and use as batch write default or per-key policy.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * BatchWritePolicy policy = new BatchWritePolicy();
+ * policy.recordExistsAction = RecordExistsAction.REPLACE;
+ * BatchPolicy batchPolicy = BatchPolicy.WriteDefault();
+ * client.put(batchPolicy, batchRecords);
+ * }
*/ public final class BatchWritePolicy { /** diff --git a/client/src/com/aerospike/client/policy/ClientPolicy.java b/client/src/com/aerospike/client/policy/ClientPolicy.java index 06ff36f20..d9c943fca 100644 --- a/client/src/com/aerospike/client/policy/ClientPolicy.java +++ b/client/src/com/aerospike/client/policy/ClientPolicy.java @@ -33,7 +33,69 @@ import com.aerospike.client.util.Util; /** - * Container object for client policy Command. + * Configuration for cluster connection and default policies used by {@link com.aerospike.client.AerospikeClient}. + * + *

This policy controls connection pool sizes, timeouts, authentication, TLS, thread pool, + * and default read/write/query/batch policies. Pass an instance to + * {@link com.aerospike.client.AerospikeClient} when creating the client. + * + *

Configure auth, timeouts, connection pool and default policies, then pass to AerospikeClient constructor.

+ *
{@code
+ * ClientPolicy policy = new ClientPolicy();
+ * policy.user = "admin";                    // auth user
+ * policy.password = "secret";               // auth password
+ * policy.clusterName = "mycluster";         // expected cluster name
+ * policy.authMode = AuthMode.INTERNAL;      // INTERNAL/EXTERNAL/PKI. Client must use same auth method as server to log in
+ * policy.timeout = 1000;                    // Tend and first-connection timeout (ms); limits wait so client does not block on unreachable nodes
+ * policy.loginTimeout = 5000;               // Login handshake timeout (ms); limits wait when authenticating to each node
+ * policy.closeTimeout = 0;                  // wait for async on close (0=indefinite)
+ * policy.minConnsPerNode = 0;               // min sync connections per node
+ * policy.maxConnsPerNode = 100;             // max sync connections per node
+ * policy.asyncMinConnsPerNode = 0;          // min async connections per node
+ * policy.asyncMaxConnsPerNode = -1;         // max async (-1 = use maxConnsPerNode)
+ * policy.connPoolsPerNode = 1;              // sync connection pools per node
+ * policy.maxSocketIdle = 0;                 // max socket idle seconds (0=no reap)
+ * policy.maxErrorRate = 100;                // max errors per errorRateWindow
+ * policy.errorRateWindow = 1;               // error rate window seconds
+ * policy.tendInterval = 1000;               // cluster tend interval ms
+ * policy.failIfNotConnected = true;          // fail if no connection at init
+ * policy.validateClusterName = true;         // validate cluster name on tend
+ * policy.readPolicyDefault = new Policy();
+ * policy.writePolicyDefault = new WritePolicy();
+ * policy.scanPolicyDefault = new ScanPolicy();
+ * policy.queryPolicyDefault = new QueryPolicy();
+ * policy.batchPolicyDefault = BatchPolicy.ReadDefault();
+ * policy.batchParentPolicyWriteDefault = BatchPolicy.WriteDefault();
+ * policy.batchWritePolicyDefault = new BatchWritePolicy();
+ * policy.batchDeletePolicyDefault = new BatchDeletePolicy();
+ * policy.batchUDFPolicyDefault = new BatchUDFPolicy();
+ * policy.txnVerifyPolicyDefault = new TxnVerifyPolicy();
+ * policy.txnRollPolicyDefault = new TxnRollPolicy();
+ * policy.infoPolicyDefault = new InfoPolicy();
+ * policy.tlsPolicy = null;                  // TLS config (null = plain sockets)
+ * policy.keepAlive = null;                  // TCP keep-alive (null = off)
+ * policy.ipMap = null;                      // IP translation map
+ * policy.threadPool = null;                 // null = default cached pool
+ * policy.sharedThreadPool = false;          // do not shutdown pool on close
+ * policy.useServicesAlternate = false;      // use alt service info commands
+ * policy.forceSingleNode = false;           // single-node mode (testing)
+ * policy.rackAware = false;                 // use rack affinity
+ * policy.rackId = 0;                        // client rack id
+ * policy.rackIds = null;                    // preferred rack list
+ * policy.appId = null;                      // app id for metrics
+ * policy.eventLoops = null;                 // null = async disabled
+ * IAerospikeClient client = new AerospikeClient(policy, "localhost", 3000);
+ * }
+ * + *

Related default policies: {@link com.aerospike.client.policy.Policy} (read), + * {@link com.aerospike.client.policy.WritePolicy}, {@link com.aerospike.client.policy.ScanPolicy}, + * {@link com.aerospike.client.policy.QueryPolicy}, {@link com.aerospike.client.policy.BatchPolicy} (batch read/write parent), + * {@link com.aerospike.client.policy.BatchWritePolicy}, {@link com.aerospike.client.policy.BatchDeletePolicy}, + * {@link com.aerospike.client.policy.BatchUDFPolicy}, {@link com.aerospike.client.policy.TxnVerifyPolicy}, + * {@link com.aerospike.client.policy.TxnRollPolicy}, {@link com.aerospike.client.policy.InfoPolicy}, + * {@link com.aerospike.client.policy.TlsPolicy}. + * + * @see com.aerospike.client.AerospikeClient */ public class ClientPolicy { /** @@ -355,16 +417,16 @@ public class ClientPolicy { * Underlying thread pool used in synchronous batch, scan, and query commands. These commands * are often sent to multiple server nodes in parallel threads. A thread pool improves * performance because threads do not have to be created/destroyed for each command. - * The default, null, indicates that the following daemon thread pool will be used: - *

+	 * 

When null, a default cached daemon thread pool is used as shown below.

+ *
{@code
 	 * threadPool = Executors.newCachedThreadPool(new ThreadFactory() {
 	 *     public final Thread newThread(Runnable runnable) {
-	 *			Thread thread = new Thread(runnable);
-	 *			thread.setDaemon(true);
-	 *			return thread;
-	 *		}
-	 *	});
-	 * 
+ * Thread thread = new Thread(runnable); + * thread.setDaemon(true); + * return thread; + * } + * }); + * }
* Daemon threads automatically terminate when the program terminates. *

* Default: null (use Executors.newCachedThreadPool) @@ -454,8 +516,12 @@ public class ClientPolicy { public String appId; /** - * Copy client policy from another client policy AND override certain policy attributes if they exist in the - * configProvider. Any policy overrides will not get logged. + * Copies a client policy from another and overrides attributes that exist in the configuration provider. + * + *

Overrides from the config provider are applied but not logged. + * + * @param other the policy to copy from; must not be {@code null} + * @param configProvider the provider of overrides; may be {@code null} (no overrides applied) */ public ClientPolicy(ClientPolicy other, ConfigurationProvider configProvider) { this(other); @@ -463,8 +529,13 @@ public ClientPolicy(ClientPolicy other, ConfigurationProvider configProvider) { } /** - * Copy client policy from another client policy AND override certain policy attributes if they exist in the - * configProvider. Any default policy overrides will get logged. + * Copies a client policy from another and overrides attributes that exist in the configuration provider. + * + *

When {@code isDefaultPolicy} is {@code true}, default policy overrides are logged. + * + * @param other the policy to copy from; must not be {@code null} + * @param configProvider the provider of overrides; may be {@code null} (no overrides applied) + * @param isDefaultPolicy {@code true} to log default policy overrides, {@code false} otherwise */ public ClientPolicy(ClientPolicy other, ConfigurationProvider configProvider, boolean isDefaultPolicy) { this(other); @@ -472,7 +543,9 @@ public ClientPolicy(ClientPolicy other, ConfigurationProvider configProvider, bo } /** - * Copy client policy from another client policy. + * Copies all fields from another client policy. + * + * @param other the policy to copy from; must not be {@code null} */ public ClientPolicy(ClientPolicy other) { this.eventLoops = other.eventLoops; @@ -520,7 +593,7 @@ public ClientPolicy(ClientPolicy other) { } /** - * Default constructor. + * Constructs a client policy with default values for all fields. */ public ClientPolicy() { } diff --git a/client/src/com/aerospike/client/policy/InfoPolicy.java b/client/src/com/aerospike/client/policy/InfoPolicy.java index 88dd409f3..30b4724aa 100644 --- a/client/src/com/aerospike/client/policy/InfoPolicy.java +++ b/client/src/com/aerospike/client/policy/InfoPolicy.java @@ -17,7 +17,15 @@ package com.aerospike.client.policy; /** - * Policy attributes used for info commands. + * Policy attributes used for info commands. Pass to {@link com.aerospike.client.AerospikeClient#info} + * and other info-based methods to control socket timeout. + *

Set timeout and pass to info command.

+ *
{@code
+ * InfoPolicy policy = new InfoPolicy();
+ * policy.timeout = 2000;
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * java.util.Map map = client.info(policy, client.getNodes()[0], "stat");
+ * }
*/ public final class InfoPolicy { /** diff --git a/client/src/com/aerospike/client/policy/Policy.java b/client/src/com/aerospike/client/policy/Policy.java index 98b23bfad..a96c47b01 100644 --- a/client/src/com/aerospike/client/policy/Policy.java +++ b/client/src/com/aerospike/client/policy/Policy.java @@ -27,7 +27,38 @@ import com.aerospike.client.exp.Expression; /** - * Command policy attributes used in all database commands. + * Base policy for read and read-like database commands (get, exists, operate read, query, scan, etc.). + * + *

Defines timeouts, retries, replica selection, optional expression filter, and transaction attachment. + * Subclasses (e.g. {@link com.aerospike.client.policy.WritePolicy}, {@link com.aerospike.client.policy.QueryPolicy}) + * add command-specific options. + * + *

Set timeouts, replica, filterExp and pass to get or other read commands.

+ *
{@code
+ * Policy policy = new Policy();
+ * policy.txn = null;                         // Attach command to multi-record transaction; null = no txn
+ * policy.readModeAP = ReadModeAP.ONE;        // AP namespace: which replica to read (ONE, ALL, etc.)
+ * policy.readModeSC = ReadModeSC.SESSION;    // SC namespace: session/linearize/allow_unavailable
+ * policy.replica = Replica.SEQUENCE;         // Which partition replica (SEQUENCE, MASTER, PREFER_RACK, etc.)
+ * policy.filterExp = null;                   // Expression filter; if false, command skipped (e.g. Exp.build(...))
+ * policy.connectTimeout = 0;                 // Ms for new connection; 0 = use socket/total timeout (intent: bound TLS/connect cost)
+ * policy.socketTimeout = 30000;              // Ms socket idle during command; intent: detect stuck connections
+ * policy.totalTimeout = 1000;                // Ms total command time; intent: fail fast, avoid indefinite wait
+ * policy.timeoutDelay = 0;                   // Ms to drain socket on timeout before close; intent: avoid RST on cloud
+ * policy.maxRetries = 2;                     // Retries after initial attempt; 0 for non-idempotent writes (intent: tolerate transient failures)
+ * policy.sleepBetweenRetries = 0;            // Ms sleep between retries; intent: give cluster time to reform
+ * policy.sleepMultiplier = 1.0;              // Exponential backoff factor for retries (> 1.0)
+ * policy.readTouchTtlPercent = 0;            // 0=server default, -1=no touch, 1-100=read refreshes TTL (intent: read-based LRU)
+ * policy.sendKey = false;                    // Send user key with request; intent: store/validate key on server
+ * policy.compress = false;                   // Zlib compress buffers; intent: reduce network size (EE server)
+ * policy.failOnFilteredOut = false;          // Throw if filterExp skips command; intent: surface filtered-out as error
+ * client.get(policy, key);
+ * }
+ * + * @see com.aerospike.client.policy.WritePolicy + * @see com.aerospike.client.policy.QueryPolicy + * @see com.aerospike.client.policy.ScanPolicy + * @see com.aerospike.client.policy.BatchPolicy */ public class Policy { /** @@ -61,16 +92,16 @@ public class Policy { public Replica replica = Replica.SEQUENCE; /** - * Optional expression filter. If filterExp exists and evaluates to false, the - * command is ignored. - *

- * Default: null - *

- *

Example:{@code
-	 * Policy p = new Policy();
-	 * p.filterExp = Exp.build(Exp.eq(Exp.intBin("a"), Exp.val(11)));
-	 * }
- */ + * Optional expression filter; if set and the expression evaluates to false, the command is skipped. + *

+ * Default: null + *

+ *

Set filterExp to skip records that do not match the expression.

+ *
{@code
+ * Policy p = new Policy();
+ * p.filterExp = Exp.build(Exp.eq(Exp.intBin("a"), Exp.val(11)));
+ * }
+ */ public Expression filterExp; /** diff --git a/client/src/com/aerospike/client/policy/QueryPolicy.java b/client/src/com/aerospike/client/policy/QueryPolicy.java index e8ac33625..b9db3662d 100644 --- a/client/src/com/aerospike/client/policy/QueryPolicy.java +++ b/client/src/com/aerospike/client/policy/QueryPolicy.java @@ -23,10 +23,30 @@ import com.aerospike.client.configuration.serializers.dynamicconfig.DynamicQueryConfig; /** - * Container object for policy attributes used in query operations. - *

- * Inherited Policy fields {@link Policy#txn} and {@link Policy#failOnFilteredOut} are ignored - * in query commands. + * Policy for query operations (secondary index and aggregation queries). + * + *

Extends {@link com.aerospike.client.policy.Policy} with query-specific options (expected duration, + * record queue size, includeBinData, etc.). Inherited fields {@link com.aerospike.client.policy.Policy#txn} + * and {@link com.aerospike.client.policy.Policy#failOnFilteredOut} are ignored for query commands. + * Pass to {@link com.aerospike.client.AerospikeClient#query} and + * {@link com.aerospike.client.AerospikeClient#queryAggregate}. + * + *

Set expectedDuration, recordQueueSize, includeBinData and pass to query.

+ *
{@code
+ * QueryPolicy policy = new QueryPolicy();
+ * policy.expectedDuration = QueryDuration.LONG;  // LONG/SHORT; server optimizes (SHORT = small result set). Ignored for agg/background and server version before 6.0
+ * policy.maxRecords = 0;                         // Deprecated: use Statement.setMaxRecords(long) instead. Approx record limit (0 = no limit)
+ * policy.maxConcurrentNodes = 0;                 // Max nodes queried in parallel; 0 = all in parallel (intent: throttle concurrency)
+ * policy.recordQueueSize = 5000;                // Records buffered before blocking producer (intent: balance memory vs throughput)
+ * policy.infoTimeout = 1000;                     // Timeout (ms) for cluster-stable info call; used only when failOnClusterChange is true on server before 6.0
+ * policy.includeBinData = true;                 // true = return bins; false = return only digests and keys (use false to reduce payload when bins not needed)
+ * policy.failOnClusterChange = false;           // Abort if cluster migrating; ignored on server 6.0+
+ * policy.shortQuery = false;                     // Deprecated: use expectedDuration (e.g. QueryDuration.SHORT) instead. true = server optimizes for under 100 records per node
+ * client.query(policy, stmt);
+ * }
+ * + * @see com.aerospike.client.policy.Policy + * @see com.aerospike.client.query.Statement */ public class QueryPolicy extends Policy { /** @@ -113,8 +133,10 @@ public class QueryPolicy extends Policy { public boolean shortQuery; /** - * Copy query policy from another query policy AND override certain policy attributes if they exist in the - * configProvider. Any policy overrides will not get logged. + * Copies a query policy from another and applies overrides from the configuration provider (overrides not logged). + * + * @param other the policy to copy from; must not be {@code null} + * @param configProvider the provider of overrides; may be {@code null} */ public QueryPolicy(QueryPolicy other, ConfigurationProvider configProvider) { this(other); @@ -122,8 +144,11 @@ public QueryPolicy(QueryPolicy other, ConfigurationProvider configProvider) { } /** - * Copy query policy from another query policy AND override certain policy attributes if they exist in the - * configProvider. Any default policy overrides will get logged. + * Copies a query policy from another and applies overrides from the configuration provider. + * + * @param other the policy to copy from; must not be {@code null} + * @param configProvider the provider of overrides; may be {@code null} + * @param isDefaultPolicy {@code true} to log default policy overrides */ public QueryPolicy(QueryPolicy other, ConfigurationProvider configProvider, boolean isDefaultPolicy) { this(other); @@ -131,7 +156,9 @@ public QueryPolicy(QueryPolicy other, ConfigurationProvider configProvider, bool } /** - * Copy query policy from another query policy. + * Copies all fields from another query policy. + * + * @param other the policy to copy from; must not be {@code null} */ public QueryPolicy(QueryPolicy other) { super(other); @@ -146,24 +173,19 @@ public QueryPolicy(QueryPolicy other) { } /** - * Copy query policy from another policy. + * Copies base policy fields from another policy; query-specific fields use defaults. + * + * @param other the policy to copy from; must not be {@code null} */ public QueryPolicy(Policy other) { super(other); } /** - * Default constructor. Disable totalTimeout and set maxRetries. - *

- * The latest servers support retries on individual data partitions. - * This feature is useful when a cluster is migrating and partition(s) - * are missed or incomplete on the first query attempt. - *

- * If the first query attempt misses 2 of 4096 partitions, then only - * those 2 partitions are retried in the next query attempt from the - * last key digest received for each respective partition. A higher - * default maxRetries is used because it's wasteful to invalidate - * all query results because a single partition was missed. + * Constructs a query policy with totalTimeout disabled and maxRetries set to 5. + * + *

Servers support retries on individual partitions; a higher maxRetries allows retrying only + * missed partitions without invalidating the entire query result. */ public QueryPolicy() { super.totalTimeout = 0; diff --git a/client/src/com/aerospike/client/policy/ScanPolicy.java b/client/src/com/aerospike/client/policy/ScanPolicy.java index 4e2ec0f7f..b2fd2439a 100644 --- a/client/src/com/aerospike/client/policy/ScanPolicy.java +++ b/client/src/com/aerospike/client/policy/ScanPolicy.java @@ -23,15 +23,26 @@ import com.aerospike.client.configuration.serializers.dynamicconfig.DynamicScanConfig; /** - * Container object for optional parameters used in scan operations. - *

- * Inherited Policy fields {@link Policy#txn} and {@link Policy#failOnFilteredOut} are ignored in - * scan commands. + * Policy for legacy scan operations; prefer {@link com.aerospike.client.policy.QueryPolicy} with a + * {@link com.aerospike.client.query.Statement} that has no filter (primary index query). * - * @deprecated Use {@link com.aerospike.client.policy.QueryPolicy} with - * {@link com.aerospike.client.AerospikeClient#query(com.aerospike.client.policy.QueryPolicy, com.aerospike.client.query.Statement)} - * (or related query methods) and a {@link com.aerospike.client.query.Statement} with no filter set (primary index query) instead. - * It will eventually be removed. + *

Inherited fields {@link com.aerospike.client.policy.Policy#txn} and + * {@link com.aerospike.client.policy.Policy#failOnFilteredOut} are ignored in scan commands. + * + *

Set maxRecords, recordsPerSecond, concurrentNodes and pass to scanAll.

+ *
{@code
+ * ScanPolicy policy = new ScanPolicy();
+ * policy.maxRecords = 0;                         // Approx record limit; divided across nodes (0 = no limit). Intent: cap scan size
+ * policy.recordsPerSecond = 0;                   // RPS limit per server (0 = no limit). Intent: throttle scan to reduce load
+ * policy.maxConcurrentNodes = 0;                // Max nodes scanned in parallel; 0 = all. Only when concurrentNodes true. Intent: throttle concurrency
+ * policy.concurrentNodes = true;              // Issue scan requests to nodes in parallel (true) or sequentially (false)
+ * policy.includeBinData = true;                 // true = return bins; false = return only digests and keys. Intent: reduce payload when bins not needed
+ * client.scanAll(policy, namespace, setName, callback);
+ * }
+ * + * @see com.aerospike.client.policy.Policy + * @see com.aerospike.client.policy.QueryPolicy + * @deprecated Use {@link com.aerospike.client.policy.QueryPolicy} with {@link com.aerospike.client.AerospikeClient#query} and a {@link com.aerospike.client.query.Statement} with no filter instead */ @Deprecated public final class ScanPolicy extends Policy { diff --git a/client/src/com/aerospike/client/policy/TCPKeepAlive.java b/client/src/com/aerospike/client/policy/TCPKeepAlive.java index c282d58f8..43e4b508e 100644 --- a/client/src/com/aerospike/client/policy/TCPKeepAlive.java +++ b/client/src/com/aerospike/client/policy/TCPKeepAlive.java @@ -17,7 +17,14 @@ package com.aerospike.client.policy; /** - * TCP keep-alive policy. This configuration only referenced when using native Netty epoll library. + * TCP keep-alive policy. Referenced when using native Netty epoll library; set on + * {@link ClientPolicy#keepAlive} to enable TCP keep-alive on connections. + *

Set idle, interval and probes then assign to ClientPolicy.keepAlive for Netty epoll.

+ *
{@code
+ * ClientPolicy policy = new ClientPolicy();
+ * policy.keepAlive = new TCPKeepAlive(59, 59, 2);
+ * IAerospikeClient client = new AerospikeClient(policy, "localhost", 3000);
+ * }
*/ public final class TCPKeepAlive { /** diff --git a/client/src/com/aerospike/client/policy/TlsPolicy.java b/client/src/com/aerospike/client/policy/TlsPolicy.java index ff4448d1d..28aa79663 100644 --- a/client/src/com/aerospike/client/policy/TlsPolicy.java +++ b/client/src/com/aerospike/client/policy/TlsPolicy.java @@ -39,7 +39,7 @@ public final class TlsPolicy { * instance needs to be shared between multiple AerospikeClient instances. If this field * is null, the AerospikeClient constructor will create a new NettyTlsContext when netty * eventloops are used with TLS. - * + *

Share NettyTlsContext across multiple AerospikeClient instances when using Netty with TLS.

*
{@code
 	 * // Share NettyTlsContext across AerospikeClient instances.
 	 * TlsPolicy tp = new TlsPolicy();
@@ -49,8 +49,8 @@ public final class TlsPolicy {
 	 * ClientPolicy cp = new ClientPolicy();
 	 * cp.tlsPolicy = tp;
 	 *
-	 * AerospikeClient cluster1 = new AerospikeClient(cp, "host1", 3000);
-	 * AerospikeClient cluster2 = new AerospikeClient(cp, "host2", 3000);
+	 * IAerospikeClient cluster1 = new AerospikeClient(cp, "host1", 3000);
+	 * IAerospikeClient cluster2 = new AerospikeClient(cp, "host2", 3000);
 	 * }
* * Default: null (create NettyTlsContext for each AerospikeClient instance when netty is used). @@ -60,13 +60,12 @@ public final class TlsPolicy { /** * Allowable TLS protocols that the client can use for secure connections. * Available cipher names can be obtained by {@link javax.net.ssl.SSLSocket#getSupportedProtocols()} - * Multiple protocols can be specified. Example: - *
-	 * {@code
+	 * Multiple protocols can be specified.
+	 * 

Set allowed TLS protocols (e.g. TLSv1.2).

+ *
{@code
 	 * TlsPolicy policy = new TlsPolicy();
 	 * policy.protocols = new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"};
-	 * }
-	 * 
+ * }
* Default: TLSv1.2 (Only allow TLSv1.2 protocol) */ public String[] protocols = new String[] {"TLSv1.2"}; diff --git a/client/src/com/aerospike/client/policy/TxnRollPolicy.java b/client/src/com/aerospike/client/policy/TxnRollPolicy.java index 9601e3d83..11982d8c9 100644 --- a/client/src/com/aerospike/client/policy/TxnRollPolicy.java +++ b/client/src/com/aerospike/client/policy/TxnRollPolicy.java @@ -24,7 +24,12 @@ /** * Transaction policy fields used to batch roll forward/backward records on - * commit or abort. Used a placeholder for now as there are no additional fields beyond BatchPolicy. + * commit or abort. Extends {@link BatchPolicy}; pass to transaction commit/abort batch operations. + *

Use as default or per-request policy for transaction roll (commit/abort) batch operations.

+ *
{@code
+ * TxnRollPolicy policy = new TxnRollPolicy();
+ * client.commit(commitPolicy, txn);
+ * }
*/ public class TxnRollPolicy extends BatchPolicy { /** diff --git a/client/src/com/aerospike/client/policy/TxnVerifyPolicy.java b/client/src/com/aerospike/client/policy/TxnVerifyPolicy.java index cafda0fdd..b14fe43c2 100644 --- a/client/src/com/aerospike/client/policy/TxnVerifyPolicy.java +++ b/client/src/com/aerospike/client/policy/TxnVerifyPolicy.java @@ -24,7 +24,12 @@ /** * Transaction policy fields used to batch verify record versions on commit. - * Used a placeholder for now as there are no additional fields beyond BatchPolicy. + * Extends {@link BatchPolicy}; pass to transaction verify batch operations. + *

Use as default or per-request policy for transaction verify (version check) batch operations.

+ *
{@code
+ * TxnVerifyPolicy policy = new TxnVerifyPolicy();
+ * client.commit(commitPolicy, txn);
+ * }
*/ public class TxnVerifyPolicy extends BatchPolicy { /** diff --git a/client/src/com/aerospike/client/policy/WritePolicy.java b/client/src/com/aerospike/client/policy/WritePolicy.java index cbc1d460d..2ddd450ef 100644 --- a/client/src/com/aerospike/client/policy/WritePolicy.java +++ b/client/src/com/aerospike/client/policy/WritePolicy.java @@ -25,8 +25,31 @@ import com.aerospike.client.configuration.serializers.dynamicconfig.DynamicWriteConfig; /** - * Container object for policy attributes used in write operations. - * This object is passed into methods where database writes can occur. + * Policy for write operations (put, delete, operate write, UDF execute, etc.). + * + *

Extends {@link com.aerospike.client.policy.Policy} with record-exists action, generation policy, + * expiration (TTL), commit level, and optional send-key/durable-delete options. Pass to + * {@link com.aerospike.client.AerospikeClient#put}, {@link com.aerospike.client.AerospikeClient#operate}, + * and other write methods. + * + *

Set record-exists action, generation policy, commit level, TTL and pass to put or operate write.

+ *
{@code
+ * WritePolicy policy = new WritePolicy();
+ * policy.recordExistsAction = RecordExistsAction.UPDATE;  // UPDATE/REPLACE/CREATE_ONLY/REPLACE_ONLY. What to do when record exists
+ * policy.generationPolicy = GenerationPolicy.NONE;         // NONE/EXPECT_GEN_EQUAL/EXPECT_GEN_GT. Intent: optimistic concurrency
+ * policy.commitLevel = CommitLevel.COMMIT_ALL;            // COMMIT_ALL/COMMIT_MASTER. When server returns success (all replicas vs master only)
+ * policy.generation = 0;                                 // Expected gen; used when generationPolicy not NONE (0 for create). Intent: detect concurrent updates
+ * policy.expiration = 0;                                  // TTL seconds: -2=no change, -1=never, 0=server default, >0=ttl. Intent: record lifetime
+ * policy.respondAllOps = false;                           // Operate: return result for every op (true helps with result offsets). Intent: easier operate result indexing
+ * policy.durableDelete = false;                           // Leave tombstone on delete (EE 3.10+). Intent: prevent deleted record from reappearing after node failure
+ * policy.onLockingOnly = false;                           // Execute write only if record not locked by this txn. Intent: safe retry of non-idempotent writes
+ * policy.xdr = false;                                     // Set XDR bit in wire protocol (for XDR emulation). Intent: external connector compatibility
+ * client.put(policy, key, bins);
+ * }
+ * + * @see com.aerospike.client.policy.Policy + * @see com.aerospike.client.policy.RecordExistsAction + * @see com.aerospike.client.policy.GenerationPolicy */ public final class WritePolicy extends Policy { /** diff --git a/client/src/com/aerospike/client/query/Filter.java b/client/src/com/aerospike/client/query/Filter.java index 77e7da056..d697da77d 100644 --- a/client/src/com/aerospike/client/query/Filter.java +++ b/client/src/com/aerospike/client/query/Filter.java @@ -26,18 +26,32 @@ import com.aerospike.client.util.Pack; /** - * Query filter definition. + * Defines a filter for secondary index queries; only one filter is allowed per {@link Statement} and must reference a bin which has a secondary index defined. * - * Currently, only one filter is allowed in a Statement, and must be on bin which has a secondary index defined. + *

Use the static factory methods ({@link #equal}, {@link #range}, {@link #contains}, {@link #geoWithinRegion}, etc.) + * to create filters by bin name, by index name, or by expression. Pass the result to {@link Statement#setFilter(Filter)}. + * + *

Create an equality filter on an indexed bin and set it on a Statement for query.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Statement stmt = new Statement();
+ * stmt.setNamespace("test");
+ * stmt.setSetName("users");
+ * stmt.setFilter(Filter.equal("status", "active"));
+ * RecordSet rs = client.query(queryPolicy, stmt);
+ * }
+ * + * @see Statement#setFilter(Filter) + * @see IndexCollectionType */ public final class Filter { /** - * Create long equality filter for query. + * Creates a long equality filter for a secondary index query on the given bin. * - * @param name bin name - * @param value filter value - * @param ctx optional context for elements within a CDT - * @return filter instance + * @param name bin name that has a secondary index defined; must not be {@code null} + * @param value value to match (equality) + * @param ctx optional context for elements within a CDT; may be empty + * @return a filter instance for use with {@link Statement#setFilter(Filter)} */ public static Filter equal(String name, long value, CTX... ctx) { Value val = Value.get(value); @@ -69,12 +83,12 @@ public static Filter equalByIndex(String indexName, long value) { } /** - * Create string equality filter for query. + * Creates a string equality filter for a secondary index query on the given bin. * - * @param name bin name - * @param value filter value - * @param ctx optional context for elements within a CDT - * @return filter instance + * @param name bin name that has a secondary index defined; must not be {@code null} + * @param value string value to match (equality); may be {@code null} + * @param ctx optional context for elements within a CDT; may be empty + * @return a filter instance for use with {@link Statement#setFilter(Filter)} */ public static Filter equal(String name, String value, CTX... ctx) { Value val = Value.get(value); @@ -270,15 +284,15 @@ public static Filter containsByIndex(String indexName, IndexCollectionType type, } /** - * Create range filter for query. - * Range arguments must be longs or integers which can be cast to longs. - * String ranges are not supported. + * Creates a numeric range filter (inclusive begin and end) for a secondary index query on the given bin. * - * @param name bin name - * @param begin filter begin value inclusive - * @param end filter end value inclusive - * @param ctx optional context for elements within a CDT - * @return filter instance + *

Range arguments must be numeric (long or castable to long); string ranges are not supported. + * + * @param name bin name that has a secondary index defined; must not be {@code null} + * @param begin inclusive start of range + * @param end inclusive end of range + * @param ctx optional context for elements within a CDT; may be empty + * @return a filter instance for use with {@link Statement#setFilter(Filter)} */ public static Filter range(String name, long begin, long end, CTX... ctx) { return new Filter(name, IndexCollectionType.DEFAULT, ParticleType.INTEGER, Value.get(begin), Value.get(end), ctx); diff --git a/client/src/com/aerospike/client/query/IndexCollectionType.java b/client/src/com/aerospike/client/query/IndexCollectionType.java index c5fee4fbc..1bd81759e 100644 --- a/client/src/com/aerospike/client/query/IndexCollectionType.java +++ b/client/src/com/aerospike/client/query/IndexCollectionType.java @@ -17,7 +17,13 @@ package com.aerospike.client.query; /** - * Secondary index collection type. + * Secondary index collection type. Use when creating an index or building {@link Filter} + * (DEFAULT for scalar bin, LIST/MAPKEYS/MAPVALUES for CDT). + *

Specify collection type when creating a secondary index on list or map bins.

+ *
{@code
+ * client.createIndex(null, "ns", "set", "idx_tags", "tags", IndexType.STRING, IndexCollectionType.LIST);
+ * Filter f = Filter.contains("tags", IndexCollectionType.LIST, "v");
+ * }
*/ public enum IndexCollectionType { /** diff --git a/client/src/com/aerospike/client/query/IndexType.java b/client/src/com/aerospike/client/query/IndexType.java index 5cfb445c4..f2aa361a6 100644 --- a/client/src/com/aerospike/client/query/IndexType.java +++ b/client/src/com/aerospike/client/query/IndexType.java @@ -17,7 +17,13 @@ package com.aerospike.client.query; /** - * Underlying data type of secondary index. + * Underlying data type of secondary index. Use when creating an index via + * {@link com.aerospike.client.IAerospikeClient#createIndex} or in {@link Filter} expressions. + *

Specify index type (NUMERIC, STRING, GEO2DSPHERE, etc.) when creating a secondary index.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * client.createIndex(null, "ns", "set", "idx_status", "status", IndexType.STRING, IndexCollectionType.DEFAULT);
+ * }
*/ public enum IndexType { /** diff --git a/client/src/com/aerospike/client/query/KeyRecord.java b/client/src/com/aerospike/client/query/KeyRecord.java index e1d401b37..d5f8f0182 100644 --- a/client/src/com/aerospike/client/query/KeyRecord.java +++ b/client/src/com/aerospike/client/query/KeyRecord.java @@ -22,21 +22,55 @@ import java.util.Objects; /** - * Container object for key identifier and record data. + * Pairs a record key with its record data (bins, generation, expiration), as returned by query and scan. + * + *

Used by {@link com.aerospike.client.query.RecordSet} and query/scan listeners. The key may be {@code null} + * for aggregation results that do not return keys; the record may be {@code null} when only digests are requested. + * + *

Iterate query/scan RecordSet and read key and record from each KeyRecord.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * RecordSet rs = client.query(policy, stmt);
+ * try {
+ *     for (KeyRecord kr : rs) {
+ *         Key key = kr.key;
+ *         Record rec = kr.record;
+ *         if (rec != null) {
+ *             Object val = rec.getValue("mybin");
+ *         }
+ *     }
+ * } finally {
+ *     rs.close();
+ * }
+ * }
+ * + *

Construct a KeyRecord pair from a key and record (e.g. for testing or custom iteration).

+ *
{@code
+ * Key key = new Key("ns", "set", "id");
+ * Record record = client.get(null, key).record;
+ * KeyRecord kr = new KeyRecord(key, record);
+ * }
+ * + * @see com.aerospike.client.query.RecordSet + * @see com.aerospike.client.Key + * @see com.aerospike.client.Record */ public final class KeyRecord { /** - * Unique identifier for record. + * The record key; may be {@code null} in some aggregation or digest-only results. */ public final Key key; /** - * Record header and bin data. + * The record (bins, generation, expiration); may be {@code null} if only digests were requested. */ public final Record record; /** - * Initialize key and record. + * Constructs a key-record pair. + * + * @param key the record key; may be {@code null} + * @param record the record data; may be {@code null} */ public KeyRecord(Key key, Record record) { this.key = key; @@ -44,7 +78,9 @@ public KeyRecord(Key key, Record record) { } /** - * Hash lookup uses key and record. + * Returns a hash code based on key and record. + * + * @return the hash code */ @Override public int hashCode() { @@ -52,7 +88,10 @@ public int hashCode() { } /** - * Equality uses key and record. + * Compares this key-record pair to the specified object for equality. + * + * @param obj the object to compare to + * @return {@code true} if equal, {@code false} otherwise */ @Override public boolean equals(Object obj) @@ -69,7 +108,9 @@ public boolean equals(Object obj) } /** - * Convert key and record to string. + * Returns a string representation of this key-record pair. + * + * @return string representation */ @Override public String toString() { diff --git a/client/src/com/aerospike/client/query/PartitionFilter.java b/client/src/com/aerospike/client/query/PartitionFilter.java index aebff5b0f..191e36c24 100644 --- a/client/src/com/aerospike/client/query/PartitionFilter.java +++ b/client/src/com/aerospike/client/query/PartitionFilter.java @@ -22,13 +22,26 @@ import com.aerospike.client.cluster.Partition; /** - * Partition filter used in scan/query. This filter is also used as a cursor. + * Partition filter used in scan/query. This filter is also used as a cursor. Pass to + * {@link com.aerospike.client.AerospikeClient#query(com.aerospike.client.policy.QueryPolicy, Statement, PartitionFilter)} + * or overloads with PartitionFilter to limit partitions or resume from a digest. *

* If a previous scan/query returned all records specified by a PartitionFilter instance, a * future scan/query using the same PartitionFilter instance will only return new records added * after the last record read (in digest order) in each partition in the previous scan/query. * To reset the cursor of an existing PartitionFilter instance, call * {@link #setPartitions(PartitionStatus[])} with a null argument. + *

Query all partitions, or a partition range, or records after a key for resumable scan.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Statement stmt = new Statement();
+ * stmt.setNamespace("test");
+ * stmt.setSetName("users");
+ * PartitionFilter pf = PartitionFilter.all();
+ * client.query(queryPolicy, stmt, pf, queryListener);
+ * PartitionFilter range = PartitionFilter.range(0, 100);
+ * client.query(queryPolicy, stmt, range, queryListener);
+ * }
*/ public final class PartitionFilter implements Serializable { private static final long serialVersionUID = 4L; diff --git a/client/src/com/aerospike/client/query/QueryListener.java b/client/src/com/aerospike/client/query/QueryListener.java index b8db35b72..12546ebe6 100644 --- a/client/src/com/aerospike/client/query/QueryListener.java +++ b/client/src/com/aerospike/client/query/QueryListener.java @@ -21,8 +21,32 @@ import com.aerospike.client.Record; /** - * Result notification for sync query command. - * The results are sent one record at a time. + * Callback invoked for each record returned by a synchronous secondary-index query. + * Use this listener when you want to process records one at a time instead of buffering + * a full {@link RecordSet}; results are streamed and the receive order is not guaranteed. + *

+ * No built-in implementations; implement this interface in application code and pass to + * {@link com.aerospike.client.IAerospikeClient#query(com.aerospike.client.policy.QueryPolicy, Statement, QueryListener)} + * or the overload with {@link PartitionFilter}. To abort from inside the callback, throw + * {@link AerospikeException.QueryTerminated}. + *

Implement onRecord and pass to query to process each record as it arrives; close resources in caller when done.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Statement stmt = new Statement();
+ * stmt.setNamespace("test");
+ * stmt.setSetName("users");
+ * client.query(queryPolicy, stmt, new QueryListener() {
+ *   public void onRecord(Key key, Record record) {
+ *     // process key, record
+ *   }
+ * });
+ * }
+ * + * @see com.aerospike.client.AerospikeClient#query(com.aerospike.client.policy.QueryPolicy, Statement, QueryListener) + * @see com.aerospike.client.AerospikeClient#query(com.aerospike.client.policy.QueryPolicy, Statement, PartitionFilter, QueryListener) + * @see Statement + * @see QueryListenerExecutor + * @see QueryListenerCommand */ public interface QueryListener { /** @@ -36,7 +60,7 @@ public interface QueryListener { * * @param key unique record identifier * @param record record instance - * @throws AerospikeException if error occurs or query should be terminated. + * @throws AerospikeException when an error occurs or the query should be terminated (e.g. throw {@link AerospikeException.QueryTerminated} to terminate). */ public void onRecord(Key key, Record record); } diff --git a/client/src/com/aerospike/client/query/RecordSet.java b/client/src/com/aerospike/client/query/RecordSet.java index 11cc6a568..4642e6947 100644 --- a/client/src/com/aerospike/client/query/RecordSet.java +++ b/client/src/com/aerospike/client/query/RecordSet.java @@ -26,11 +26,33 @@ import com.aerospike.client.Record; /** - * This class manages record retrieval from queries. - * Multiple threads will retrieve records from the server nodes and put these records on the queue. - * The single user thread consumes these records from the queue. + * Iterable stream of {@link KeyRecord} results from a secondary index query. + * + *

Producer threads fill an internal queue with records from the server; the single user thread calls + * {@link #next()} to block until the next record is available, then {@link #getRecord()} to access it. + * Call {@link #close()} when done to release resources and optionally terminate the query early. + * + *

Call query with Statement then iterate with next() and getRecord(); close the RecordSet when done.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * RecordSet rs = client.query(queryPolicy, stmt);
+ * try {
+ *     while (rs.next()) {
+ *         KeyRecord kr = rs.getRecord();
+ *         Key key = kr.key;
+ *         Record rec = kr.record;
+ *         // process key, rec
+ *     }
+ * } finally {
+ *     rs.close();
+ * }
+ * }
+ * + * @see com.aerospike.client.AerospikeClient#query(com.aerospike.client.policy.QueryPolicy, Statement) + * @see KeyRecord */ public class RecordSet implements Iterable, Closeable { + /** Sentinel value placed on the queue when no more records are available. */ public static final KeyRecord END = new KeyRecord(null, null); private final IQueryExecutor executor; @@ -59,10 +81,10 @@ protected RecordSet() { //------------------------------------------------------- /** - * Retrieve next record. This method will block until a record is retrieved - * or the query is cancelled. + * Advances to the next record, blocking until one is available or the query ends. * - * @return whether record exists - if false, no more records are available + * @return {@code true} if a record is available (use {@link #getRecord()}), {@code false} if no more records or query was closed + * @throws AerospikeException when the query failed on the server (e.g. timeout, connection error, or invalid statement). */ public boolean next() throws AerospikeException { if (! valid) { @@ -93,7 +115,9 @@ record = queue.take(); } /** - * Close query. + * Closes this record set and releases resources; may signal the server to stop the query. + * + *

Call in a {@code finally} block to ensure resources are released. After close, {@link #next()} returns {@code false}. */ public void close() { valid = false; @@ -106,7 +130,9 @@ public void close() { } /** - * Provide Iterator for RecordSet. + * Returns an iterator over the records in this set. + * + * @return an iterator over {@link KeyRecord} elements */ @Override public Iterator iterator() { @@ -118,21 +144,27 @@ public Iterator iterator() { //------------------------------------------------------- /** - * Get record's unique identifier. + * Returns the key of the current record (valid after {@link #next()} returns {@code true}). + * + * @return the key of the current record */ public Key getKey() { return record.key; } /** - * Get record's header and bin data. + * Returns the record (bins, generation, expiration) of the current record (valid after {@link #next()} returns {@code true}). + * + * @return the record data for the current record */ public Record getRecord() { return record.record; } /** - * Get key and record. + * Returns the current {@link KeyRecord} (key and record together). + * + * @return the key and record for the current record */ public KeyRecord getKeyRecord() { return record; diff --git a/client/src/com/aerospike/client/query/RegexFlag.java b/client/src/com/aerospike/client/query/RegexFlag.java index 0c5e4c714..bbeccb8db 100644 --- a/client/src/com/aerospike/client/query/RegexFlag.java +++ b/client/src/com/aerospike/client/query/RegexFlag.java @@ -17,8 +17,8 @@ package com.aerospike.client.query; /** - * Regex bit flags. Use BITWISE OR to combine flags. Example: - * + * Regex bit flags. Use BITWISE OR to combine flags. + *

Combine flags with bitwise OR for regex matching (e.g. in Filter.regex).

*
{@code 
  * int flags = RegexFlag.ICASE | RegexFlag.NEWLINE;
  * }
diff --git a/client/src/com/aerospike/client/query/ResultSet.java b/client/src/com/aerospike/client/query/ResultSet.java index f63d5c2c0..dc7f19d5d 100644 --- a/client/src/com/aerospike/client/query/ResultSet.java +++ b/client/src/com/aerospike/client/query/ResultSet.java @@ -25,11 +25,30 @@ import com.aerospike.client.Log; /** - * This class manages result retrieval from queries. - * Multiple threads will retrieve results from the server nodes and put these results on the queue. - * The single user thread consumes these results from the queue. + * Iterable stream of aggregation results from a query that uses an aggregation UDF. + * + *

Producer threads fill an internal queue with results from the server; the consumer thread calls + * {@link #next()} to block until the next result is available, then {@link #getObject()} to access it. + * Call {@link #close()} when done to release resources and optionally terminate the query early. + * + *

Call queryAggregate then iterate with next() and getObject(); close the ResultSet when done.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * ResultSet rs = client.queryAggregate(queryPolicy, stmt);
+ * try {
+ *     while (rs.next()) {
+ *         Object result = rs.getObject();
+ *         // process aggregation result
+ *     }
+ * } finally {
+ *     rs.close();
+ * }
+ * }
+ * + * @see RecordSet for query results that return full records */ public class ResultSet implements Iterable, Closeable { + /** Sentinel value placed on the queue when no more results are available. */ public static final Object END = new Object(); private final QueryAggregateExecutor executor; @@ -58,10 +77,10 @@ protected ResultSet() { //------------------------------------------------------- /** - * Retrieve next result. This method will block until a result is retrieved - * or the query is cancelled. + * Advances to the next result, blocking until one is available or the query ends. * - * @return whether result exists - if false, no more results are available + * @return {@code true} if a result is available (use {@link #getObject()}), {@code false} if no more results or query was closed + * @throws AerospikeException when the query failed on the server (e.g. timeout, connection error, or invalid statement). */ public boolean next() throws AerospikeException { if (!valid) { @@ -90,7 +109,9 @@ public boolean next() throws AerospikeException { } /** - * Close query. + * Closes this result set and releases resources; may signal the server to stop the query. + * + *

Call in a {@code finally} block to ensure resources are released. After close, {@link #next()} returns {@code false}. */ public void close() { valid = false; @@ -103,7 +124,9 @@ public void close() { } /** - * Provide Iterator for RecordSet. + * Returns an iterator over the results in this set. + * + * @return an iterator over the aggregation result objects */ @Override public Iterator iterator() { @@ -115,7 +138,9 @@ public Iterator iterator() { //------------------------------------------------------- /** - * Get result. + * Returns the current aggregation result (valid after {@link #next()} returns {@code true}). + * + * @return the current result object (type depends on the UDF) */ public Object getObject() { return row; diff --git a/client/src/com/aerospike/client/query/Statement.java b/client/src/com/aerospike/client/query/Statement.java index f1f3e7cc3..389c4c708 100644 --- a/client/src/com/aerospike/client/query/Statement.java +++ b/client/src/com/aerospike/client/query/Statement.java @@ -21,7 +21,53 @@ import com.aerospike.client.util.RandomShift; /** - * Query statement parameters. + * Holds parameters for secondary index queries and scans executed via + * {@link com.aerospike.client.AerospikeClient#query} (RecordSet or listener overload). + * + *

Use this class to specify namespace, set, optional filter (on an indexed bin), bin names to return, + * optional aggregation function, and limits such as {@link #setMaxRecords(long)} and + * {@link #setRecordsPerSecond(int)}. + * + *

Run a secondary index query with filter and iterate RecordSet; use IAerospikeClient and close RecordSet when done.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Statement stmt = new Statement();
+ * stmt.setNamespace("test");
+ * stmt.setSetName("users");
+ * stmt.setFilter(Filter.equal("status", "active"));
+ * stmt.setBinNames("name", "email");
+ * stmt.setMaxRecords(1000);
+ * RecordSet rs = client.query(queryPolicy, stmt);
+ * try {
+ *     for (KeyRecord kr : rs) {
+ *         // process kr.record
+ *     }
+ * } finally {
+ *     rs.close();
+ * }
+ * }
+ * + *

Run a full namespace/set scan with no filter and optional recordsPerSecond limit.

+ *
{@code
+ * Statement stmt = new Statement();
+ * stmt.setNamespace("test");
+ * stmt.setSetName("orders");
+ * stmt.setRecordsPerSecond(500);
+ * RecordSet rs = client.query(queryPolicy, stmt);
+ * }
+ * + *

Run an aggregation query with filter and UDF; result type depends on the UDF.

+ *
{@code
+ * Statement stmt = new Statement();
+ * stmt.setNamespace("test");
+ * stmt.setSetName("events");
+ * stmt.setFilter(Filter.range("age", 18, 65));
+ * stmt.setAggregateFunction("myudfs", "countGroup", Value.get("state"));
+ * Object result = client.queryAggregate(queryPolicy, stmt);
+ * }
+ * + * @see com.aerospike.client.AerospikeClient#query + * @see Filter */ public final class Statement { String namespace; @@ -41,136 +87,186 @@ public final class Statement { boolean returnData; /** - * Set query namespace. + * Sets the namespace to query or scan. + * + * @param namespace the namespace name; must not be {@code null} */ public void setNamespace(String namespace) { this.namespace = namespace; } /** - * Get query namespace. + * Returns the namespace set for this statement. + * + * @return the namespace name, or {@code null} if not set */ public String getNamespace() { return namespace; } /** - * Set optional query setname. + * Sets the optional set name to restrict the query or scan to a single set. + * + * @param setName the set name, or {@code null} to query/scan all sets in the namespace */ public void setSetName(String setName) { this.setName = setName; } /** - * Get optional query setname. + * Returns the optional set name for this statement. + * + * @return the set name, or {@code null} if not set (all sets in namespace) */ public String getSetName() { return setName; } /** - * Set optional query index name. If not set, the server - * will determine the index from the filter's bin name. - * Note, the call is only applicable to pre-6.0 server versions, - * and is ignored by server versions 6.0 and later. + * Sets the optional secondary index name to use for the query. + * + *

If not set, the server determines the index from the filter's bin name. This method + * is only applicable to server versions before 6.0; server versions 6.0 and later ignore it. + * + * @param indexName the index name, or {@code null} to let the server choose from the filter bin */ public void setIndexName(String indexName) { this.indexName = indexName; } /** - * Get optional query index name. + * Returns the optional index name set for this statement. + * + * @return the index name, or {@code null} if not set */ public String getIndexName() { return indexName; } /** - * Set query bin names. + * Sets which bins to return for each record; empty or {@code null} means all bins. + * + * @param binNames the bin names to return, or {@code null} / empty for all bins */ public void setBinNames(String... binNames) { this.binNames = binNames; } /** - * Get query bin names. + * Returns the bin names to return for each record. + * + * @return the bin names, or {@code null} if not set (all bins) */ public String[] getBinNames() { return binNames; } /** - * Set optional query index filter. This filter is applied to the secondary index on query. - * Query index filters must reference a bin which has a secondary index defined. + * Sets the optional filter applied to the secondary index for the query. + * + *

The filter must reference a bin that has a secondary index defined. If {@code null}, + * the statement represents a full namespace/set scan (see {@link #isScan()}). + * + * @param filter the index filter, or {@code null} for a full scan + * @see Filter + * @see #isScan() */ public void setFilter(Filter filter) { this.filter = filter; } /** - * Return query index filter. + * Returns the index filter for this statement. + * + * @return the filter, or {@code null} if not set (full scan) */ public Filter getFilter() { return filter; } /** - * Set optional task id. + * Sets the optional task ID for background query/scan execution. + * + * @param taskId the task ID; use 0 to let the client generate one via {@link #prepareTaskId()} */ public void setTaskId(long taskId) { this.taskId = taskId; } /** - * Return optional task id. + * Returns the task ID set for this statement. + * + * @return the task ID, or 0 if not set */ public long getTaskId() { return taskId; } /** - * Set maximum number of records returned (for foreground query) or processed - * (for background execute query). This number is divided by the number of nodes - * involved in the query. The actual number of records returned may be less than - * maxRecords if node record counts are small and unbalanced across nodes. + * Sets the maximum number of records returned (foreground query) or processed (background + * execute query). + * + *

The limit is divided across the nodes involved in the query. The actual number of + * records returned may be less than {@code maxRecords} if node record counts are small or + * unbalanced. + * + * @param maxRecords maximum number of records; 0 means no limit */ public void setMaxRecords(long maxRecords) { this.maxRecords = maxRecords; } /** - * Return maximum number of records. + * Returns the maximum number of records set for this statement. + * + * @return the maximum record count, or 0 if not set (no limit) */ public long getMaxRecords() { return maxRecords; } /** - * Limit returned records per second (rps) rate for each server. - * Do not apply rps limit if recordsPerSecond is zero (default). - *

- * recordsPerSecond is supported in all primary and secondary index - * queries in server versions 6.0+. For background queries, recordsPerSecond - * is bounded by the server config background-query-max-rps. + * Limits the number of records returned or processed per second (rps) per server. + * + *

If {@code recordsPerSecond} is zero (default), no rps limit is applied. This option + * is supported for primary and secondary index queries on server versions 6.0 and later. + * For background queries, the effective rps is also bounded by the server config + * {@code background-query-max-rps}. + * + * @param recordsPerSecond maximum records per second per server; 0 for no limit */ public void setRecordsPerSecond(int recordsPerSecond) { this.recordsPerSecond = recordsPerSecond; } /** - * Return records per second. + * Returns the records-per-second limit set for this statement. + * + * @return the rps limit, or 0 if not set (no limit) */ public int getRecordsPerSecond() { return recordsPerSecond; } /** - * Set Lua aggregation function parameters for a Lua package located on the filesystem. - * This function will be called on both the server and client for each selected item. + * Sets the Lua aggregation function for a package located on the server filesystem. + * + *

The function is invoked on the server and optionally on the client for each selected + * record. Use the other overload {@link #setAggregateFunction(ClassLoader, String, String, String, Value...)} + * when the Lua module is loaded from the classpath (e.g. a resource). + * + *

Example: + *

{@code
+	 * Statement stmt = new Statement();
+	 * stmt.setNamespace("test");
+	 * stmt.setSetName("demo");
+	 * stmt.setAggregateFunction("myudfs", "myAggregate", Value.get("arg1"));
+	 * }
* - * @param packageName server package where user defined function resides - * @param functionName aggregation function name - * @param functionArgs arguments to pass to function name, if any + * @param packageName server package (module) where the UDF resides; must not be {@code null} + * @param functionName name of the aggregation function; must not be {@code null} + * @param functionArgs optional arguments to pass to the function; may be empty + * @see #setAggregateFunction(ClassLoader, String, String, String, Value...) */ public void setAggregateFunction(String packageName, String functionName, Value... functionArgs) { this.packageName = packageName; @@ -179,14 +275,25 @@ public void setAggregateFunction(String packageName, String functionName, Value. } /** - * Set Lua aggregation function parameters for a Lua package located in a resource file. - * This function will be called on both the server and client for each selected item. - * - * @param resourceLoader class loader where resource is located. Example: MyClass.class.getClassLoader() or Thread.currentThread().getContextClassLoader() for webapps - * @param resourcePath class path where Lua resource is located - * @param packageName server package where user defined function resides - * @param functionName aggregation function name - * @param functionArgs arguments to pass to function name, if any + * Sets the Lua aggregation function for a package loaded from a classpath resource. + * + *

The function is invoked on the server and optionally on the client for each selected + * record. Use this overload when the Lua module is bundled as a resource (e.g. in a JAR). + * + *

Example: + *

{@code
+	 * Statement stmt = new Statement();
+	 * stmt.setNamespace("test");
+	 * stmt.setSetName("demo");
+	 * stmt.setAggregateFunction(MyClass.class.getClassLoader(), "udf/myagg.lua", "myagg", "reduce", Value.get(0));
+	 * }
+ * + * @param resourceLoader class loader that can load the resource; e.g. {@code MyClass.class.getClassLoader()} or {@code Thread.currentThread().getContextClassLoader()} for web apps + * @param resourcePath classpath path to the Lua resource file; must not be {@code null} + * @param packageName server package (module) name where the UDF resides; must not be {@code null} + * @param functionName name of the aggregation function; must not be {@code null} + * @param functionArgs optional arguments to pass to the function; may be empty + * @see #setAggregateFunction(String, String, Value...) */ public void setAggregateFunction(ClassLoader resourceLoader, String resourcePath, String packageName, String functionName, Value... functionArgs) { this.resourceLoader = resourceLoader; @@ -197,58 +304,77 @@ public void setAggregateFunction(ClassLoader resourceLoader, String resourcePath } /** - * Return resource class loader. + * Returns the class loader used to load the aggregation Lua resource. + * + * @return the resource class loader, or {@code null} if aggregation uses filesystem package */ public ClassLoader getResourceLoader() { return resourceLoader; } /** - * Return resource path. + * Returns the classpath path to the aggregation Lua resource. + * + * @return the resource path, or {@code null} if aggregation uses filesystem package */ public String getResourcePath() { return resourcePath; } /** - * Return aggregation file name. + * Returns the server package (module) name for the aggregation function. + * + * @return the package name, or {@code null} if no aggregation was set */ public String getPackageName() { return packageName; } /** - * Return aggregation function name. + * Returns the aggregation function name. + * + * @return the function name, or {@code null} if no aggregation was set */ public String getFunctionName() { return functionName; } /** - * Return aggregation function arguments. + * Returns the arguments passed to the aggregation function. + * + * @return the function arguments, or {@code null} if no aggregation was set */ public Value[] getFunctionArgs() { return functionArgs; } /** - * Set operations to be performed on a background query - * {@link com.aerospike.client.AerospikeClient#execute(com.aerospike.client.policy.WritePolicy, Statement, Operation...)} - * A foreground query that returns records to the client will silently ignore these operations. + * Sets the operations to run on the server for each record in a background query. + * + *

Used with {@link com.aerospike.client.AerospikeClient#execute(com.aerospike.client.policy.WritePolicy, Statement, Operation...)}. + * Foreground queries that return records to the client ignore these operations. + * + * @param operations the operations to apply per record; may be {@code null} + * @see com.aerospike.client.AerospikeClient#execute(com.aerospike.client.policy.WritePolicy, Statement, Operation...) */ public void setOperations(Operation[] operations) { this.operations = operations; } /** - * Return operations to be performed on a background query. + * Returns the operations to be performed on each record in a background query. + * + * @return the operations, or {@code null} if not set */ public Operation[] getOperations() { return this.operations; } /** - * Not used anymore. + * No longer used; retained for backward compatibility only. + * + * @param returnData ignored + * @deprecated This method has no effect */ @Deprecated public void setReturnData(boolean returnData) { @@ -256,7 +382,10 @@ public void setReturnData(boolean returnData) { } /** - * Not used anymore. + * No longer used; retained for backward compatibility only. + * + * @return the stored value (has no effect on behavior) + * @deprecated This method has no effect */ @Deprecated public boolean returnData() { @@ -264,14 +393,19 @@ public boolean returnData() { } /** - * Return taskId if set by user. Otherwise return a new taskId. + * Returns the task ID for this statement, or a newly generated one if none was set. + * + * @return the user-set task ID if non-zero, otherwise a new unique task ID */ public long prepareTaskId() { return (taskId != 0)? taskId : RandomShift.instance().nextLong(); } /** - * Return if full namespace/set scan is specified. + * Indicates whether this statement represents a full namespace/set scan (no index filter). + * + * @return {@code true} if no filter is set (full scan), {@code false} if an index filter is set + * @see #getFilter() */ public boolean isScan() { return filter == null; diff --git a/client/src/com/aerospike/client/task/ExecuteTask.java b/client/src/com/aerospike/client/task/ExecuteTask.java index b5a60be54..614bd66be 100644 --- a/client/src/com/aerospike/client/task/ExecuteTask.java +++ b/client/src/com/aerospike/client/task/ExecuteTask.java @@ -25,21 +25,60 @@ import com.aerospike.client.util.Version; /** - * Task used to poll for long-running server execute job completion. + * Task that polls for completion of a background query or scan execute job started by + * {@link com.aerospike.client.AerospikeClient#execute} (UDF or Operation overload). + * + *

Use {@link #waitTillComplete()} to block until the job finishes on all nodes, or + * {@link #queryStatus()} / {@link com.aerospike.client.task.Task#isDone()} to poll. + * + *

Example (background execute with Operations, wait for completion): + *

{@code
+ * Statement stmt = new Statement();
+ * stmt.setNamespace("test");
+ * stmt.setSetName("users");
+ * stmt.setFilter(Filter.equal("status", "pending"));
+ * ExecuteTask task = client.execute(writePolicy, stmt, Operation.put(new Bin("processed", true)));
+ * task.waitTillComplete();  // blocks until job finishes on all nodes
+ * }
+ * + *

Example (background execute with UDF, poll status): + *

{@code
+ * Statement stmt = new Statement();
+ * stmt.setNamespace("test");
+ * stmt.setSetName("events");
+ * ExecuteTask task = client.execute(writePolicy, stmt, "myudfs", "processRecord", Value.get("arg"));
+ * while (!task.isDone()) {
+ *     int status = task.queryStatus();  // NOT_FOUND, IN_PROGRESS, or COMPLETE
+ *     Thread.sleep(500);
+ * }
+ * }
+ * + * @see com.aerospike.client.task.Task + * @see com.aerospike.client.AerospikeClient#execute */ public class ExecuteTask extends Task { private final long taskId; private final boolean scan; /** - * Initialize task with fields needed to query server nodes. + * Constructs an execute task for the given statement and task ID (from the execute call). + * + * @param cluster the cluster; must not be {@code null} + * @param policy policy for polling (timeout, etc.); must not be {@code null} + * @param statement the statement that was executed + * @param taskId the task ID returned by the execute call */ public ExecuteTask(Cluster cluster, Policy policy, Statement statement, long taskId) { this(cluster, policy, taskId, statement.isScan()); } /** - * Initialize task with fields needed to query server nodes. + * Constructs an execute task with the given task ID and scan flag. + * + * @param cluster the cluster; must not be {@code null} + * @param policy policy for polling; must not be {@code null} + * @param taskId the task ID from the execute call + * @param isScan {@code true} for scan execute, {@code false} for query execute */ public ExecuteTask(Cluster cluster, Policy policy, long taskId, boolean isScan) { super(cluster, policy); @@ -57,14 +96,19 @@ protected ExecuteTask(long taskId, boolean isScan) { } /** - * Return task id. + * Returns the task ID for this execute job. + * + * @return the task ID */ public long getTaskId() { return taskId; } /** - * Query all nodes for task completion status. + * Queries the cluster for this execute task's completion status. + * + * @return {@link Task#NOT_FOUND}, {@link Task#IN_PROGRESS}, or {@link Task#COMPLETE} + * @throws AerospikeException when a node request fails (e.g. timeout or connection error). */ @Override public int queryStatus() throws AerospikeException { diff --git a/client/src/com/aerospike/client/task/IndexTask.java b/client/src/com/aerospike/client/task/IndexTask.java index 91095085d..4e52a93fd 100644 --- a/client/src/com/aerospike/client/task/IndexTask.java +++ b/client/src/com/aerospike/client/task/IndexTask.java @@ -25,7 +25,37 @@ import com.aerospike.client.util.Version; /** - * Task used to poll for long running create index completion. + * Task that polls for completion of a secondary index create or drop started by + * {@link com.aerospike.client.AerospikeClient#createIndex} or + * {@link com.aerospike.client.AerospikeClient#dropIndex}. + * + *

Use {@link #waitTillComplete()} to block until the index operation finishes on all nodes, or + * {@link #queryStatus()} / {@link com.aerospike.client.task.Task#isDone()} to poll. + * + *

Example (create index, wait for completion): + *

{@code
+ * IndexTask task = client.createIndex(null, "test", "users", "idx_status", "status", IndexType.STRING);
+ * task.waitTillComplete();  // blocks until index is built on all nodes
+ * }
+ * + *

Example (create index with collection type, poll status): + *

{@code
+ * IndexTask task = client.createIndex(null, "test", "events", "idx_tags", "tags", IndexType.STRING, IndexCollectionType.LIST);
+ * while (!task.isDone()) {
+ *     int status = task.queryStatus();  // NOT_FOUND, IN_PROGRESS, or COMPLETE
+ *     Thread.sleep(500);
+ * }
+ * }
+ * + *

Example (drop index): + *

{@code
+ * IndexTask task = client.dropIndex(null, "test", "users", "idx_status");
+ * task.waitTillComplete();
+ * }
+ * + * @see com.aerospike.client.task.Task + * @see com.aerospike.client.AerospikeClient#createIndex + * @see com.aerospike.client.AerospikeClient#dropIndex */ public final class IndexTask extends Task { private final String namespace; @@ -35,7 +65,13 @@ public final class IndexTask extends Task { private String existsCommand; /** - * Initialize task with fields needed to query server nodes. + * Constructs an index task for the given namespace and index name. + * + * @param cluster the cluster; must not be {@code null} + * @param policy policy for polling (timeout, etc.); must not be {@code null} + * @param namespace the namespace of the index + * @param indexName the name of the index + * @param isCreate {@code true} for create, {@code false} for drop */ public IndexTask(Cluster cluster, Policy policy, String namespace, String indexName, boolean isCreate) { super(cluster, policy); @@ -45,7 +81,9 @@ public IndexTask(Cluster cluster, Policy policy, String namespace, String indexN } /** - * Query all nodes for task completion status. + * Queries the cluster for this index task's completion status. + * + * @return {@link Task#NOT_FOUND}, {@link Task#IN_PROGRESS}, or {@link Task#COMPLETE} */ @Override public int queryStatus() { diff --git a/client/src/com/aerospike/client/task/RegisterTask.java b/client/src/com/aerospike/client/task/RegisterTask.java index b1803ee67..f9666be13 100644 --- a/client/src/com/aerospike/client/task/RegisterTask.java +++ b/client/src/com/aerospike/client/task/RegisterTask.java @@ -23,13 +23,40 @@ import com.aerospike.client.policy.Policy; /** - * Task used to poll for UDF registration completion. + * Task that polls for completion of UDF module registration started by + * {@link com.aerospike.client.AerospikeClient#register} or + * {@link com.aerospike.client.AerospikeClient#registerUdfString}. + * + *

Use {@link #waitTillComplete()} to block until the package is registered on all nodes, or + * {@link #queryStatus()} / {@link com.aerospike.client.task.Task#isDone()} to poll. + * + *

Example (register UDF from file, wait for completion): + *

{@code
+ * RegisterTask task = client.register(null, "udf/myudfs.lua", "myudfs.lua", Language.LUA);
+ * task.waitTillComplete();  // blocks until package is registered on all nodes
+ * }
+ * + *

Example (register from classpath resource, poll status): + *

{@code
+ * RegisterTask task = client.register(null, MyClass.class.getClassLoader(), "udf/myagg.lua", "myagg.lua", Language.LUA);
+ * while (!task.isDone()) {
+ *     int status = task.queryStatus();  // IN_PROGRESS or COMPLETE
+ *     Thread.sleep(500);
+ * }
+ * }
+ * + * @see com.aerospike.client.task.Task + * @see com.aerospike.client.AerospikeClient#register */ public final class RegisterTask extends Task { private final String packageName; /** - * Initialize task with fields needed to query server nodes. + * Constructs a register task for the given UDF package name. + * + * @param cluster the cluster; must not be {@code null} + * @param policy policy for polling (timeout, etc.); must not be {@code null} + * @param packageName the UDF package name (e.g. "myudfs") */ public RegisterTask(Cluster cluster, Policy policy, String packageName) { super(cluster, policy); @@ -37,7 +64,10 @@ public RegisterTask(Cluster cluster, Policy policy, String packageName) { } /** - * Query all nodes for task completion status. + * Queries the cluster for this registration task's completion status. + * + * @return {@link Task#IN_PROGRESS} or {@link Task#COMPLETE} + * @throws AerospikeException when a node request fails (e.g. timeout or connection error). */ public int queryStatus() throws AerospikeException { // All nodes must respond with package to be considered done. diff --git a/client/src/com/aerospike/client/task/Task.java b/client/src/com/aerospike/client/task/Task.java index f596229fb..8f693e80c 100644 --- a/client/src/com/aerospike/client/task/Task.java +++ b/client/src/com/aerospike/client/task/Task.java @@ -25,11 +25,46 @@ import com.aerospike.client.util.Util; /** - * Task used to poll for server task completion. + * Base type for server tasks (index creation, UDF registration, background query/scan execution) that complete asynchronously. + * + *

Use {@link #waitTillComplete()} or {@link #waitTillComplete(int)} to block until the task finishes, or + * {@link #isDone()} to poll. Status is one of {@link #NOT_FOUND}, {@link #IN_PROGRESS}, or {@link #COMPLETE}. + * + *

Index creation task: create a secondary index and block until the server reports completion.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * IndexTask task = client.createIndex(null, "test", "users", "idx_status", "status", IndexType.STRING);
+ * task.waitTillComplete();
+ * }
+ * + *

UDF registration task: register a UDF package and poll with isDone() or waitTillComplete.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * RegisterTask task = client.register(null, "udf/myudfs.lua", "myudfs.lua", Language.LUA);
+ * if (!task.isDone()) {
+ *   task.waitTillComplete(10);
+ * }
+ * }
+ * + *

Background query/scan execute task: run a background query or scan and wait for completion.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * ExecuteTask task = client.execute(writePolicy, stmt, Operation.put(new Bin("processed", true)));
+ * task.waitTillComplete();
+ * }
+ * + * @see com.aerospike.client.task.IndexTask + * @see com.aerospike.client.task.RegisterTask + * @see com.aerospike.client.task.ExecuteTask */ public abstract class Task { + /** Task status: task not found (may mean not started or already removed by server). */ public static final int NOT_FOUND = 0; + + /** Task status: task is still running. */ public static final int IN_PROGRESS = 1; + + /** Task status: task completed successfully. */ public static final int COMPLETE = 2; protected final Cluster cluster; @@ -37,7 +72,10 @@ public abstract class Task { private boolean done; /** - * Initialize task with fields needed to query server nodes. + * Constructs a task that will poll the given cluster for completion using the given policy (timeout, etc.). + * + * @param cluster the cluster to query for task status; must not be {@code null} + * @param policy policy for info commands used to poll (timeout, etc.); must not be {@code null} */ public Task(Cluster cluster, Policy policy) { this.cluster = cluster; @@ -46,7 +84,7 @@ public Task(Cluster cluster, Policy policy) { } /** - * Initialize task that has already completed. + * Constructs a task that is already considered complete (e.g. for testing or no-op). */ public Task() { this.cluster = null; @@ -55,27 +93,32 @@ public Task() { } /** - * Wait for asynchronous task to complete using default sleep interval (1 second). - * The timeout is passed from the original task policy. If task is not complete by timeout, - * an exception is thrown. Do not timeout if timeout set to zero. + * Blocks until the task completes or the policy timeout is reached (sleep interval 1 second). + * + *

Uses the timeout from the policy passed to the task constructor. If policy timeout is 0, waits indefinitely. + * + * @throws AerospikeException.Timeout when the task does not complete before the policy timeout. */ public final void waitTillComplete() { taskWait(1000); } /** - * Wait for asynchronous task to complete using given sleep interval in milliseconds. - * The timeout is passed from the original task policy. If task is not complete by timeout, - * an exception is thrown. Do not timeout if policy timeout set to zero. + * Blocks until the task completes or the policy timeout is reached. + * + * @param sleepInterval milliseconds to sleep between status polls + * @throws AerospikeException.Timeout when the task does not complete before the policy timeout. */ public final void waitTillComplete(int sleepInterval) { taskWait(sleepInterval); } /** - * Wait for asynchronous task to complete using given sleep interval and timeout in milliseconds. - * If task is not complete by timeout, an exception is thrown. Do not timeout if timeout set to - * zero. + * Blocks until the task completes or the given timeout is reached. + * + * @param sleepInterval milliseconds to sleep between status polls + * @param timeout maximum time to wait in milliseconds; 0 to wait indefinitely + * @throws AerospikeException.Timeout when the task does not complete before the timeout. */ public final void waitTillComplete(int sleepInterval, int timeout) { policy = new InfoPolicy(); @@ -134,7 +177,9 @@ private final void taskWait(int sleepInterval) { } /** - * Has task completed. + * Returns whether the task has completed (or is considered complete, e.g. NOT_FOUND after polling). + * + * @return {@code true} if the task is done, {@code false} if still in progress */ public final boolean isDone() { if (done) { @@ -157,7 +202,9 @@ public final boolean isDone() { } /** - * Query all nodes for task completion status. + * Queries the cluster for this task's completion status. + * + * @return {@link #NOT_FOUND}, {@link #IN_PROGRESS}, or {@link #COMPLETE} */ public abstract int queryStatus(); } diff --git a/client/src/com/aerospike/client/util/Utf8.java b/client/src/com/aerospike/client/util/Utf8.java index c7fc0ce24..57b6a9d0d 100644 --- a/client/src/com/aerospike/client/util/Utf8.java +++ b/client/src/com/aerospike/client/util/Utf8.java @@ -39,7 +39,7 @@ public final class Utf8 { * method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in both * time and space. * - * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired + * @throws IllegalArgumentException when {@code sequence} contains ill-formed UTF-16 (unpaired * surrogates) */ public static int encodedLength(CharSequence sequence) { diff --git a/client/src/com/aerospike/client/util/Version.java b/client/src/com/aerospike/client/util/Version.java index 8aa967790..1b0d0b034 100644 --- a/client/src/com/aerospike/client/util/Version.java +++ b/client/src/com/aerospike/client/util/Version.java @@ -18,12 +18,26 @@ import java.net.InetSocketAddress; +import com.aerospike.client.AerospikeClient; import com.aerospike.client.AerospikeException; import com.aerospike.client.IAerospikeClient; import com.aerospike.client.Info; import com.aerospike.client.cluster.Node; import com.aerospike.client.policy.InfoPolicy; +/** + * Server or client version representation; supports comparison and constants for feature checks. + * Use {@link #getServerVersion(IAerospikeClient, InfoPolicy)} or + * {@link #getServerVersion(InfoPolicy, Node)} to obtain server version. + *

Obtain server version from a connected client and compare to version constants.

+ *
{@code
+ * IAerospikeClient client = new AerospikeClient("localhost", 3000);
+ * Version serverVer = Version.getServerVersion(client, new InfoPolicy());
+ * if (serverVer.isGreaterOrEqual(Version.SERVER_VERSION_8_1)) {
+ *   // use 8.1+ feature
+ * }
+ * }
+ */ public final class Version implements Comparable { public static final Version SERVER_VERSION_8_1 = new Version(8, 1, 0, 0); public static final Version SERVER_VERSION_PSCAN = new Version(4, 9, 0, 3);