Package com.aerospike.client

Source Code of com.aerospike.client.Key

/*
* Aerospike Client - Java Library
*
* Copyright 2012 by Aerospike, Inc. All rights reserved.
*
* Availability of this source code to partners and customers includes
* redistribution rights covered by individual contract. Please check your
* contract for exact rights and responsibilities.
*/
package com.aerospike.client;

import gnu.crypto.hash.RipeMD160;

import java.util.Arrays;

import com.aerospike.client.command.Buffer;
import com.aerospike.client.command.ParticleType;
import com.aerospike.client.util.ThreadLocalData1;

/**
* 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.  If the user key needs
   * to persist on the server, the key should be explicitly stored in a bin.
   */
  public final Object 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 server handles record identifiers by digest only.
   *
   * @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 = key;
    digest = computeDigest(setName, new Value.StringValue(key));
  }

  /**
   * 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 server handles record identifiers by digest only.
   * If the user key needs to be stored on the server, the key should be stored 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, byte[] key) throws AerospikeException {
    this.namespace = namespace;
    this.setName = setName;
    this.userKey = key;
    digest = computeDigest(setName, new Value.BytesValue(key));
  }

  /**
   * 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 server handles record identifiers by digest only.
   * If the user key needs to be stored on the server, the key should be stored 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.
   * @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;
    Value value = new Value.ByteSegmentValue(key, offset, length);
    this.userKey = value;
    digest = computeDigest(setName, value);
  }

  /**
   * 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 server handles record identifiers by digest only.
   * If the user key needs to be stored on the server, the key should be stored 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 = key;
    digest = computeDigest(setName, new Value.LongValue(key));
  }

  /**
   * 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 server handles record identifiers by digest only.
   * If the user key needs to be stored on the server, the key should be stored 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 = key;
    digest = computeDigest(setName, new Value.LongValue(key));
  }

  /**
   * 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 server handles record identifiers by digest only.
   * If the user key needs to be stored on the server, the key should be stored 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;
    digest = 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 and optional set name.
   *
   * @param namespace        namespace
   * @param digest        unique server hash value
   * @param setName        optional set name, enter null when set does not exist
   */
  public Key(String namespace, byte[] digest, String setName) {
    this.namespace = namespace;
    this.digest = digest;
    this.setName = setName;
    this.userKey = null;
  }
 
  /**
   * Initialize key from namespace and digest.
   * This constructor exists for the legacy CitrusleafClient compatibility layer only.
   * Do not use.
   *
   * @param namespace        namespace
   * @param digest        unique server hash value
   */
  public Key(String namespace, byte[] digest) {
    this.namespace = namespace;
    this.digest = digest;
    this.setName = null;
    this.userKey = null;
  }

  /**
   * 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) {
    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 {
    int keyType = key.getType();
   
    if (keyType == ParticleType.NULL) {
      throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key: null");
    }
   
    // This method runs 14% faster using thread local byte array
    // versus creating the buffer each time.
    byte[] buffer = ThreadLocalData1.getBuffer();
    int setLength = Buffer.stringToUtf8(setName, buffer, 0);

    buffer[setLength] = (byte)keyType;   
    int keyLength = key.write(buffer, setLength + 1);

    // Run additional 16% faster using direct class versus
    // HashFactory.getInstance("RIPEMD-160").
    RipeMD160 hash = new RipeMD160();
    hash.update(buffer, 0, setLength);
    hash.update(buffer, setLength, keyLength + 1);
    return hash.digest();
  }
}
TOP

Related Classes of com.aerospike.client.Key

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.