package com.sleepycat.je.tree; import java.util.Comparator; import com.sleepycat.je.DatabaseEntry; import de.ovgu.cide.jakutil.*; /** * Key represents a JE B-Tree Key. Keys are immutable. Within JE, keys are * usually represented as byte arrays rather than as Key instances in order to * reduce the in-memory footprint. The static methods of this class are used to * operate on the byte arrays. * One exception is when keys are held within a collection. In that case, Key * objects are instantiated so that keys are hashed and compared by value. */ public final class Key implements Comparable { public static boolean DUMP_BINARY=true; public static boolean DUMP_INT_BINDING=false; public static final byte[] EMPTY_KEY=new byte[0]; private byte[] key; /** * Construct a new key from a byte array. */ public Key( byte[] key){ if (key == null) { this.key=null; } else { this.key=new byte[key.length]; System.arraycopy(key,0,this.key,0,key.length); } } public static byte[] makeKey( DatabaseEntry dbt){ byte[] entryKey=dbt.getData(); if (entryKey == null) { return EMPTY_KEY; } else { byte[] newKey=new byte[dbt.getSize()]; System.arraycopy(entryKey,dbt.getOffset(),newKey,0,dbt.getSize()); return newKey; } } /** * Get the byte array for the key. */ public byte[] getKey(){ return key; } /** * Compare two keys. Standard compareTo function and returns. * Note that any configured user comparison function is not used, and * therefore this method should not be used for comparison of keys during * Btree operations. */ public int compareTo( Object o){ if (o == null) { throw new NullPointerException(); } Key argKey=(Key)o; return compareUnsignedBytes(this.key,argKey.key); } /** * Support Set of Key in BINReference. */ public boolean equals( Object o){ return (o instanceof Key) && (compareTo(o) == 0); } /** * Support HashSet of Key in BINReference. */ public int hashCode(){ int code=0; for (int i=0; i < key.length; i+=1) { code+=key[i]; } return code; } /** * Compare keys with an optional comparator. */ public static int compareKeys( byte[] key1, byte[] key2, Comparator comparator){ if (comparator != null) { return comparator.compare(key1,key2); } else { return compareUnsignedBytes(key1,key2); } } /** * Compare using a default unsigned byte comparison. */ private static int compareUnsignedBytes( byte[] key1, byte[] key2){ int a1Len=key1.length; int a2Len=key2.length; int limit=Math.min(a1Len,a2Len); for (int i=0; i < limit; i++) { byte b1=key1[i]; byte b2=key2[i]; if (b1 == b2) { continue; } else { return (b1 & 0xff) - (b2 & 0xff); } } return (a1Len - a2Len); } public static String dumpString( byte[] key, int nspaces){ StringBuffer sb=new StringBuffer(); sb.append(TreeUtils.indent(nspaces)); sb.append("<key v=\""); if (DUMP_BINARY) { if (key == null) { sb.append("<null>"); } else { sb.append(TreeUtils.dumpByteArray(key)); } } else if (DUMP_INT_BINDING) { if (key == null) { sb.append("<null>"); } else { DatabaseEntry e=new DatabaseEntry(key); } } else { sb.append(key == null ? "" : new String(key)); } sb.append("\"/>"); return sb.toString(); } /** * Print the string w/out XML format. */ public static String getNoFormatString( byte[] key){ return "key=" + dumpString(key,0); } }