Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.storemate.shared;
  
  import java.util.Arrays;
  
  
  public class StorableKey
     implements Comparable<StorableKey>
 {
     protected final byte[] _buffer;
     protected final int _offset_length;

    
Hash code is calculated on-demand
 
     protected int _hashCode;
     
     public StorableKey(byte[] buf) {
          = buf;
          = 0;
          = buf.length;
     }
 
     public StorableKey(byte[] bufint offsetint len)
     {
          = buf;
          = offset;
          = len;
         if (offset < 0) {
             throw new IllegalArgumentException("Illegal offset: "+offset);
         }
         if (len < 0) {
             throw new IllegalArgumentException("Illegal length: "+len);
         }
         if ((offset + len) > buf.length) {
             throw new IllegalArgumentException("Illegal offset/length ("+offset+"/"+len
                     +") combination: array length = "+buf.length);
         }
     }
 
     /*
     /**********************************************************************
     /* Simple accessories
     /**********************************************************************
      */
 
     public final int length() { return ; }

    

Since:
0.9.23
 
     public final int byteAt(int index) {
         if (index < 0 || index >= ) {
             throw new IllegalArgumentException("Invalid index "+index+": key length="+);
         }
         return [ + index];
     }
    
    
Method that can be called to see whether this key has specified key as a prefix, including possible case that keys are identical
 
     public final boolean hasPrefix(StorableKey other)
     {
         if (other == thisreturn true;
         if (other == null) { // since meaning here would be ambiguous, let's fail instead
             throw new IllegalArgumentException("Can't pass null key");
         }
         final int prefixLen = other.length();
         if (prefixLen > ) {
             return false;
         }
         // Optimization for common case of no offsets
         if ( == 0 && other._offset == 0) {
             return _equals(other._bufferprefixLen);
         }
         // otherwise offline
         return _equals(other._bufferother._offset,
                  + prefixLen);
     }
    
    
Method for checking whether raw contents of this key equal contents of given byte sequence.
 
     public final boolean equals(byte[] bufferint offsetint length)
     {
         if (length != ) {
             return false;
         }
         if (offset == 0 &&  == 0) {
             return _equals(bufferlength);
         }
         return _equals(bufferoffsetlength);
     }
 
     private final boolean _equals(byte[] b1byte[] b2int len)
    {
        int ptr = 0;
        while (ptr < len) {
            if (b1[ptr] != b2[ptr]) {
                return false;
            }
            ++ptr;
        }
        return true;
    }
    
    private final boolean _equals(byte[] b1int ptr1byte[] b2int ptr2int end)
    {
        while (ptr1 < end) {
            if (b1[ptr1] != b2[ptr2]) {
                return false;
            }
            ++ptr1;
            ++ptr2;
        }
        return true;
    }
    /*
    /**********************************************************************
    /* Find methods
    /**********************************************************************
     */
    public final int indexOf(byte toMatch) {
        return indexOf(toMatch, 0);
    }
    public final int indexOf(byte toMatchint atOrAfter)
    {
        final byte[] b  = ;
        for (int i = +atOrAfterend =  + i < end; ++i) {
            if (b[i] == toMatch) {
                return i;
            }
        }
        return -1;
    }
    public final int lastIndexOf(byte toMatch) {
        return lastIndexOf(toMatch, 0);
    }
    public final int lastIndexOf(byte toMatchint atOrAfter)
    {
        final byte[] b  = ;
        final int first =  + atOrAfter;
        for (int i =  + ; --i >= first; ) {
            if (b[i] == toMatch) {
                return i;
            }
        }
        return -1;
    }
    
    /*
    /**********************************************************************
    /* Mutant factories
    /**********************************************************************
     */
    
    public final byte[] asBytes() {
        if ( == 0) {
            if ( == .) {
                return ;
            }
            return Arrays.copyOf();
        }
        return Arrays.copyOfRange(+);
    }
    public final StorableKey range(int offsetint length) {
        if (offset < 0 || length < 0 || (offset+length) > ) {
            throw new IllegalArgumentException("Invalid range (offset "+offset+", length "+length
                    +"), for key with length of "++" bytes");
        }
        if (offset == 0 && length == ) {
            return this;
        }
        int from = +offset;
        return new StorableKey(fromlength);
    }
    
    public final byte[] rangeAsBytes(int offsetint length)
    {
        if (offset < 0 || length < 0 || (offset+length) > ) {
            throw new IllegalArgumentException("Invalid range (offset "+offset+", length "+length
                    +"), for key with length of "++" bytes");
        }
        int from = +offset;
        return Arrays.copyOfRange(fromfrom + );
    }
    
    public final <T> T with(WithBytesCallback<T> cb) {
        return cb.withBytes();
    }
    public final <T> T withRange(WithBytesCallback<T> cbint offsetint length) {
        if (offset < 0 || length < 0 || (offset+length) > ) {
            throw new IllegalArgumentException("Invalid range (offset "+offset+", length "+length
                    +"), for key with length of "++" bytes");
        }
        return cb.withBytes(+offsetlength);
    }
    /*
    /**********************************************************************
    /* Hash code calculation
    /**********************************************************************
     */
    
    public int hashCode(BlockHasher32 hasher) {
        return hasher.hash(.);
    }
    
    public int hashCode(BlockHasher32 hasherint offsetint length) {
        if (offset < 0 || length < 0 || (offset+length) > ) {
            throw new IllegalArgumentException("Invalid range (offset "+offset+", length "+length
                    +"), for key with length of "++" bytes");
        }
        return hasher.hash(.+offsetlength);
    }
    
    /*
    /**********************************************************************
    /* Std method overrides
    /**********************************************************************
     */
    
    @Override public int hashCode() {
        int h = ;
        if (h == 0) {
            h = ..hash(0, );
            if (h == 0) { // need to mask 0 not to mean "not calculated"
                h = 1;
            }
             = h;
        }
        return h;
    }
    @Override
    public boolean equals(Object o)
    {
        if (o == thisreturn true;
        if (o == nullreturn false;
        if (o.getClass() != getClass()) return false;
        StorableKey other = (StorableKeyo;
        if (other._length != return false;
        final int end =  + ;
        final byte[] thisB = ;
        final byte[] thatB = other._buffer;
        for (int i1 = i2 = other._offseti1 < end; ) {
            if (thisB[i1++] != thatB[i2++]) {
                return false;
            }
        }
        return true;
    }
    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder("[Key(");
        sb.append();
        sb.append("), hash 0x");
        sb.append(Integer.toHexString(hashCode()));
        // TODO: add head/tail of key?
        sb.append(']');
        return sb.toString();
    }
    @Override
    public int compareTo(StorableKey other)
    {
        if (other == nullreturn 1;
        final byte[] b1  = ;
        final byte[] b2  = other._buffer;
        if (( + other._offset) > 0) {
            return _compareWithOffsets(b1b2other._offsetother._length);
        }
        final int end = Math.min(other._length);
        for (int i = 0; i < end; ++i) {
            if (b1[i] != b2[i]) {
                return _unsignedDiff(b1[i], b2[i]);
            }
        }
        return  - other._length;
    }
    
    private final static int _compareWithOffsets(byte[] b1byte[] b2int off1int off2,
            int len1int len2)
    {
        final int end = off1 + Math.min(len1len2);
        for (int i1 = off1i2 = off2i1 < end; ++i1, ++i2) {
            if (b1[i1] != b2[i2]) {
                return _unsignedDiff(b1[i1], b2[i2]);
            }
        }
        // longer should be sorted after shorter so:
        return len1 - len2;
    }
    private final static int _unsignedDiff(byte b1byte b2)
    {
        int i1 = b1 & 0xFF;
        int i2 = b2 & 0xFF;
        
        return i1 - i2;
    }
    /*
    /**********************************************************************
    /* Converter interfaces
    /**********************************************************************
     */
    
    
Interface used by objects that can provide a StorableKey, either by returning aggregated key, or converting an alternate representation it has.
    public interface Convertible {
        public StorableKey asStorableKey();
    }
    public interface Provider {
        public StorableKey getStorableKey();
    }
New to GrepCode? Check out our FAQ X