Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 59 additions & 31 deletions client/src/com/aerospike/client/AerospikeClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4693,6 +4693,30 @@ public final ResultSet queryAggregateNode(QueryPolicy policy, Statement statemen
// Secondary Index functions
//--------------------------------------------------------

/**
* Create a set index for the given namespace and set.
* A set index is a secondary index specialized for record presence per set;
* no bin, type, context, or expression parameters are used.
* This asynchronous server call will return before command is complete.
* The user can optionally wait for command completion by using the returned
* IndexTask instance.
* Requires server version 8.1.2+.
*
* @param policy generic configuration parameters, pass in null for defaults
* @param namespace namespace - equivalent to database name
* @param setName set name (required for set indexes)
* @param indexName name of set index
* @throws AerospikeException if index create fails
*/
public final IndexTask createIndex(
Policy policy,
String namespace,
String setName,
String indexName
) throws AerospikeException {
return createIndex(policy, namespace, setName, indexName, null, null, IndexCollectionType.SET);
}

/**
* Create scalar secondary index.
* This asynchronous server call will return before command is complete.
Expand Down Expand Up @@ -5366,47 +5390,51 @@ private String buildCreateIndexInfoCommand(
sb.append(";indexname=");
sb.append(indexName);

if (exp != null && exp.size() > 0) {
String base64 = exp.getBase64();

sb.append(";exp=");
sb.append(base64);

if (indexCollectionType != IndexCollectionType.DEFAULT) {
sb.append(";indextype=");
sb.append(indexCollectionType);
}

sb.append(";type=");
sb.append(indexType);
} else {
if (ctx != null && ctx.length > 0) {
byte[] bytes = Pack.pack(ctx);
String base64 = Crypto.encodeBase64(bytes);
if (indexCollectionType == IndexCollectionType.SET) {
sb.append(";indextype=set");
}
else {
if (exp != null && exp.size() > 0) {
String base64 = exp.getBase64();

sb.append(";context=");
sb.append(";exp=");
sb.append(base64);
}

if (indexCollectionType != IndexCollectionType.DEFAULT) {
sb.append(";indextype=");
sb.append(indexCollectionType);
}
if (indexCollectionType != IndexCollectionType.DEFAULT) {
sb.append(";indextype=");
sb.append(indexCollectionType);
}

if (node.serverVersion.isGreaterOrEqual(Version.SERVER_VERSION_8_1)) {
sb.append(";bin=");
sb.append(binName);
sb.append(";type=");
sb.append(indexType);
} else {
sb.append(";indexdata=");
sb.append(binName);
sb.append(',');
sb.append(indexType);
if (ctx != null && ctx.length > 0) {
byte[] bytes = Pack.pack(ctx);
String base64 = Crypto.encodeBase64(bytes);

sb.append(";context=");
sb.append(base64);
}

if (indexCollectionType != IndexCollectionType.DEFAULT) {
sb.append(";indextype=");
sb.append(indexCollectionType);
}

if (node.serverVersion.isGreaterOrEqual(Version.SERVER_VERSION_8_1)) {
sb.append(";bin=");
sb.append(binName);
sb.append(";type=");
sb.append(indexType);
} else {
sb.append(";indexdata=");
sb.append(binName);
sb.append(',');
sb.append(indexType);
}
}
}


return sb.toString();
}

Expand Down
22 changes: 22 additions & 0 deletions client/src/com/aerospike/client/IAerospikeClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -1917,6 +1917,28 @@ public ResultSet queryAggregateNode(QueryPolicy policy, Statement statement, Nod
// Secondary Index functions
//--------------------------------------------------------

/**
* Create a set index for the given namespace and set.
* A set index is a secondary index specialized for record presence per set;
* no bin, type, context, or expression parameters are used.
* This asynchronous server call will return before command is complete.
* The user can optionally wait for command completion by using the returned
* IndexTask instance.
* Requires server version 8.1.2+.
*
* @param policy generic configuration parameters, pass in null for defaults
* @param namespace namespace - equivalent to database name
* @param setName set name (required for set indexes)
* @param indexName name of set index
* @throws AerospikeException if index create fails
*/
public IndexTask createIndex(
Policy policy,
String namespace,
String setName,
String indexName
) throws AerospikeException;

/**
* Create scalar secondary index.
* This asynchronous server call will return before command is complete.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,12 @@ public enum IndexCollectionType {
/**
* Index map values.
*/
MAPVALUES;
MAPVALUES,

/**
* Set index.
* No bin, type, context, or expression parameters are used.
* Requires server version 8.1.2+.
*/
SET;
}
5 changes: 5 additions & 0 deletions client/src/com/aerospike/client/task/IndexTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ public static int parseStatusResponse(String command, String response, boolean i

int begin = index + find.length();
int end = response.indexOf(';', begin);

if (end < 0) {
end = response.length();
}

String str = response.substring(begin, end);
int pct = Integer.parseInt(str);

Expand Down
1 change: 1 addition & 0 deletions client/src/com/aerospike/client/util/Version.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

public final class Version implements Comparable<Version> {
public static final Version SERVER_VERSION_8_1 = new Version(8, 1, 0, 0);
public static final Version SERVER_VERSION_8_1_2 = new Version(8, 1, 2, 0);
public static final Version SERVER_VERSION_PSCAN = new Version(4, 9, 0, 3);
public static final Version SERVER_VERSION_QUERY_SHOW = new Version(5, 7, 0, 0);
public static final Version SERVER_VERSION_PQUERY_BATCH_ANY = new Version(6, 0, 0, 0);
Expand Down
46 changes: 46 additions & 0 deletions test/src/com/aerospike/test/sync/query/TestIndex.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import static org.junit.Assert.assertEquals;

import org.junit.Assume;
import org.junit.Test;

import com.aerospike.client.AerospikeException;
Expand All @@ -31,11 +32,13 @@
import com.aerospike.client.exp.LoopVarPart;
import com.aerospike.client.query.IndexType;
import com.aerospike.client.task.IndexTask;
import com.aerospike.client.util.Version;
import com.aerospike.test.sync.TestSync;

public class TestIndex extends TestSync {
private static final String indexName = "testindex";
private static final String binName = "testbin";
private static final String setIndexName = "testsetindex";

@Test
public void createDrop() {
Expand Down Expand Up @@ -70,6 +73,49 @@ public void createDrop() {
}
}

@Test
public void setIndexCreateDrop() {
Version serverVersion = client.getCluster().getRandomNode().getServerVersion();
Assume.assumeTrue("Set index tests require server version 8.1.2 or later",
serverVersion.isGreaterOrEqual(Version.SERVER_VERSION_8_1_2));

IndexTask task;

// Drop set index if it already exists.
try {
task = client.dropIndex(args.indexPolicy, args.namespace, args.set, setIndexName);
task.waitTillComplete();
}
catch (AerospikeException ae) {
if (ae.getResultCode() != ResultCode.INDEX_NOTFOUND) {
throw ae;
}
}

task = client.createIndex(args.indexPolicy, args.namespace, args.set, setIndexName);
task.waitTillComplete();

// Verify the set index exists on all nodes.
Node[] nodes = client.getNodes();

for (Node node : nodes) {
String cmd = IndexTask.buildExistsCommand(args.namespace, setIndexName, node.serverVersion);
String response = Info.request(node, cmd);
assertEquals("true", response);
}

task = client.dropIndex(args.indexPolicy, args.namespace, args.set, setIndexName);
task.waitTillComplete();

// Ensure all nodes have dropped the set index.
for (Node node : nodes) {
String cmd = IndexTask.buildStatusCommand(args.namespace, setIndexName, node.serverVersion);
String response = Info.request(node, cmd);
int code = Info.parseResultCode(response);
assertEquals(201, code);
}
}

@Test
public void ctxRestore() {
CTX[] ctx1 = new CTX[] {
Expand Down
Loading