All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aerospike.client.Key Maven / Gradle / Ivy

Go to download

Aerospike Java client interface to Aerospike database server. Uses Bouncy Castle crypto library for RIPEMD-160 hashing.

There is a newer version: 9.0.0
Show newest version
/*
 * Copyright 2012-2021 Aerospike, Inc.
 *
 * Portions may be licensed to Aerospike, Inc. under one or more contributor
 * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.aerospike.client;

import java.util.Arrays;

import com.aerospike.client.command.Buffer;
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.
 */
public final class Key {
	/**
	 * Namespace. Equivalent to database name.
	 */
	public final String namespace;

	/**
	 * Optional set name. Equivalent to database table.
	 */
	public final String setName;

	/**
	 * Unique server hash value generated from set name and user key.
	 */
	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.
  • *
*/ 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);}
    	 * 
    *
  • *
* * @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 */ public Key(String namespace, String setName, String key) throws AerospikeException { this.namespace = namespace; this.setName = setName; this.userKey = new Value.StringValue(key); digest = Crypto.computeDigest(setName, this.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'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);}
    	 * 
    *
  • *
* * @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 */ public Key(String namespace, String setName, byte[] key) throws AerospikeException { this.namespace = namespace; this.setName = setName; this.userKey = new Value.BytesValue(key); digest = Crypto.computeDigest(setName, this.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'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);}
    	 * 
    *
  • *
* * @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 */ public Key(String namespace, String setName, byte[] key, int offset, int length) throws AerospikeException { this.namespace = namespace; this.setName = setName; this.userKey = new Value.ByteSegmentValue(key, offset, length); digest = Crypto.computeDigest(setName, this.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.
  • *
* * @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 */ public Key(String namespace, String setName, int key) throws AerospikeException { this.namespace = namespace; this.setName = setName; this.userKey = new Value.LongValue(key); digest = Crypto.computeDigest(setName, this.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.
  • *
* * @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 */ public Key(String namespace, String setName, long key) throws AerospikeException { this.namespace = namespace; this.setName = setName; this.userKey = new Value.LongValue(key); digest = Crypto.computeDigest(setName, this.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.
  • *
* * @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 */ public Key(String namespace, String setName, Value key) throws AerospikeException { this.namespace = namespace; this.setName = setName; this.userKey = key; // Some value types can't be used as keys (jblob, list, map, null). Verify key type. key.validateKeyType(); digest = Crypto.computeDigest(setName, key); } /* * Removed Object constructor because the type must be determined using multiple "instanceof" * checks. If the type is not known, java serialization (slow) is used for byte conversion. * These two performance penalties make this constructor unsuitable in all cases from * a performance perspective. * * The preferred method when using compound java key objects is to explicitly convert the * object to a byte[], String (or other known type) and call the associated Key constructor. * public Key(String namespace, String setName, Object key) throws AerospikeException { this.namespace = namespace; this.setName = setName; this.userKey = key; digest = computeDigest(setName, Value.get(key)); } */ /** * Initialize key from namespace, digest, optional set name and optional userKey. * * @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). */ public Key(String namespace, byte[] digest, String setName, Value userKey) { this.namespace = namespace; this.digest = digest; this.setName = setName; // Do not try to validate userKey type because it is most likely null. this.userKey = userKey; } /** * Hash lookup uses namespace and digest. */ @Override public int hashCode() { final int prime = 31; int result = prime + Arrays.hashCode(digest); return prime * result + namespace.hashCode(); } /** * Equality uses namespace and digest. */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } Key other = (Key) obj; if (! Arrays.equals(digest, other.digest)) return false; return namespace.equals(other.namespace); } /** * Generate unique server hash value from set name, key type and user defined key. * The hash function is RIPEMD-160 (a 160 bit hash). * * @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 */ public static byte[] computeDigest(String setName, Value key) throws AerospikeException { return Crypto.computeDigest(setName, key); } @Override public String toString() { return this.namespace + ":" + this.setName + ":" + this.userKey + ":" + Buffer.bytesToHexString(this.digest); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy