001/**
002 * Copyright The Apache Software Foundation
003 *
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *     http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020package org.apache.hadoop.hbase;
021
022import static org.apache.hadoop.hbase.util.Bytes.len;
023
024import java.io.DataInput;
025import java.io.DataOutput;
026import java.io.IOException;
027import java.io.OutputStream;
028import java.nio.ByteBuffer;
029import java.util.ArrayList;
030import java.util.Arrays;
031import java.util.HashMap;
032import java.util.Iterator;
033import java.util.List;
034import java.util.Map;
035import org.apache.hadoop.hbase.util.ByteBufferUtils;
036import org.apache.hadoop.hbase.util.Bytes;
037import org.apache.hadoop.hbase.util.ClassSize;
038import org.apache.hadoop.io.RawComparator;
039import org.apache.yetus.audience.InterfaceAudience;
040import org.slf4j.Logger;
041import org.slf4j.LoggerFactory;
042
043import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
044
045/**
046 * An HBase Key/Value. This is the fundamental HBase Type.
047 * <p>
048 * HBase applications and users should use the Cell interface and avoid directly using KeyValue and
049 * member functions not defined in Cell.
050 * <p>
051 * If being used client-side, the primary methods to access individual fields are
052 * {@link #getRowArray()}, {@link #getFamilyArray()}, {@link #getQualifierArray()},
053 * {@link #getTimestamp()}, and {@link #getValueArray()}. These methods allocate new byte arrays
054 * and return copies. Avoid their use server-side.
055 * <p>
056 * Instances of this class are immutable. They do not implement Comparable but Comparators are
057 * provided. Comparators change with context, whether user table or a catalog table comparison. Its
058 * critical you use the appropriate comparator. There are Comparators for normal HFiles, Meta's
059 * Hfiles, and bloom filter keys.
060 * <p>
061 * KeyValue wraps a byte array and takes offsets and lengths into passed array at where to start
062 * interpreting the content as KeyValue. The KeyValue format inside a byte array is:
063 * <code>&lt;keylength&gt; &lt;valuelength&gt; &lt;key&gt; &lt;value&gt;</code> Key is further
064 * decomposed as: <code>&lt;rowlength&gt; &lt;row&gt; &lt;columnfamilylength&gt;
065 * &lt;columnfamily&gt; &lt;columnqualifier&gt;
066 * &lt;timestamp&gt; &lt;keytype&gt;</code> The <code>rowlength</code> maximum is
067 * <code>Short.MAX_SIZE</code>, column family length maximum is <code>Byte.MAX_SIZE</code>, and
068 * column qualifier + key length must be &lt; <code>Integer.MAX_SIZE</code>. The column does not
069 * contain the family/qualifier delimiter, {@link #COLUMN_FAMILY_DELIMITER}<br>
070 * KeyValue can optionally contain Tags. When it contains tags, it is added in the byte array after
071 * the value part. The format for this part is: <code>&lt;tagslength&gt;&lt;tagsbytes&gt;</code>.
072 * <code>tagslength</code> maximum is <code>Short.MAX_SIZE</code>. The <code>tagsbytes</code>
073 * contain one or more tags where as each tag is of the form
074 * <code>&lt;taglength&gt;&lt;tagtype&gt;&lt;tagbytes&gt;</code>. <code>tagtype</code> is one byte
075 * and <code>taglength</code> maximum is <code>Short.MAX_SIZE</code> and it includes 1 byte type
076 * length and actual tag bytes length.
077 */
078@InterfaceAudience.Private
079public class KeyValue implements ExtendedCell, Cloneable {
080  private static final ArrayList<Tag> EMPTY_ARRAY_LIST = new ArrayList<>();
081
082  private static final Logger LOG = LoggerFactory.getLogger(KeyValue.class);
083
084  public static final int FIXED_OVERHEAD = ClassSize.OBJECT + // the KeyValue object itself
085      ClassSize.REFERENCE + // pointer to "bytes"
086      2 * Bytes.SIZEOF_INT + // offset, length
087      Bytes.SIZEOF_LONG;// memstoreTS
088
089  /**
090   * Colon character in UTF-8
091   */
092  public static final char COLUMN_FAMILY_DELIMITER = ':';
093
094  public static final byte[] COLUMN_FAMILY_DELIM_ARRAY =
095    new byte[]{COLUMN_FAMILY_DELIMITER};
096
097  /**
098   * Comparator for plain key/values; i.e. non-catalog table key/values. Works on Key portion
099   * of KeyValue only.
100   * @deprecated Use {@link CellComparator#getInstance()} instead. Deprecated for hbase 2.0, remove for hbase 3.0.
101   */
102  @Deprecated
103  public static final KVComparator COMPARATOR = new KVComparator();
104  /**
105   * A {@link KVComparator} for <code>hbase:meta</code> catalog table
106   * {@link KeyValue}s.
107   * @deprecated Use {@link CellComparatorImpl#META_COMPARATOR} instead. Deprecated for hbase 2.0, remove for hbase 3.0.
108   */
109  @Deprecated
110  public static final KVComparator META_COMPARATOR = new MetaComparator();
111
112  /** Size of the key length field in bytes*/
113  public static final int KEY_LENGTH_SIZE = Bytes.SIZEOF_INT;
114
115  /** Size of the key type field in bytes */
116  public static final int TYPE_SIZE = Bytes.SIZEOF_BYTE;
117
118  /** Size of the row length field in bytes */
119  public static final int ROW_LENGTH_SIZE = Bytes.SIZEOF_SHORT;
120
121  /** Size of the family length field in bytes */
122  public static final int FAMILY_LENGTH_SIZE = Bytes.SIZEOF_BYTE;
123
124  /** Size of the timestamp field in bytes */
125  public static final int TIMESTAMP_SIZE = Bytes.SIZEOF_LONG;
126
127  // Size of the timestamp and type byte on end of a key -- a long + a byte.
128  public static final int TIMESTAMP_TYPE_SIZE = TIMESTAMP_SIZE + TYPE_SIZE;
129
130  // Size of the length shorts and bytes in key.
131  public static final int KEY_INFRASTRUCTURE_SIZE = ROW_LENGTH_SIZE
132      + FAMILY_LENGTH_SIZE + TIMESTAMP_TYPE_SIZE;
133
134  // How far into the key the row starts at. First thing to read is the short
135  // that says how long the row is.
136  public static final int ROW_OFFSET =
137    Bytes.SIZEOF_INT /*keylength*/ +
138    Bytes.SIZEOF_INT /*valuelength*/;
139
140  public static final int ROW_KEY_OFFSET = ROW_OFFSET + ROW_LENGTH_SIZE;
141
142  // Size of the length ints in a KeyValue datastructure.
143  public static final int KEYVALUE_INFRASTRUCTURE_SIZE = ROW_OFFSET;
144
145  /** Size of the tags length field in bytes */
146  public static final int TAGS_LENGTH_SIZE = Bytes.SIZEOF_SHORT;
147
148  public static final int KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE = ROW_OFFSET + TAGS_LENGTH_SIZE;
149
150  /**
151   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided
152   * characteristics would take up for its underlying data structure.
153   *
154   * @param rlength row length
155   * @param flength family length
156   * @param qlength qualifier length
157   * @param vlength value length
158   *
159   * @return the <code>KeyValue</code> data structure length
160   */
161  public static long getKeyValueDataStructureSize(int rlength,
162      int flength, int qlength, int vlength) {
163    return KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE
164        + getKeyDataStructureSize(rlength, flength, qlength) + vlength;
165  }
166
167  /**
168   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided
169   * characteristics would take up for its underlying data structure.
170   *
171   * @param rlength row length
172   * @param flength family length
173   * @param qlength qualifier length
174   * @param vlength value length
175   * @param tagsLength total length of the tags
176   *
177   * @return the <code>KeyValue</code> data structure length
178   */
179  public static long getKeyValueDataStructureSize(int rlength, int flength, int qlength,
180      int vlength, int tagsLength) {
181    if (tagsLength == 0) {
182      return getKeyValueDataStructureSize(rlength, flength, qlength, vlength);
183    }
184    return KeyValue.KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE
185        + getKeyDataStructureSize(rlength, flength, qlength) + vlength + tagsLength;
186  }
187
188  /**
189   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided
190   * characteristics would take up for its underlying data structure.
191   *
192   * @param klength key length
193   * @param vlength value length
194   * @param tagsLength total length of the tags
195   *
196   * @return the <code>KeyValue</code> data structure length
197   */
198  public static long getKeyValueDataStructureSize(int klength, int vlength, int tagsLength) {
199    if (tagsLength == 0) {
200      return (long) KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE + klength + vlength;
201    }
202    return (long) KeyValue.KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE + klength + vlength + tagsLength;
203  }
204
205  /**
206   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided
207   * characteristics would take up in its underlying data structure for the key.
208   *
209   * @param rlength row length
210   * @param flength family length
211   * @param qlength qualifier length
212   *
213   * @return the key data structure length
214   */
215  public static long getKeyDataStructureSize(int rlength, int flength, int qlength) {
216    return (long) KeyValue.KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
217  }
218
219  /**
220   * Key type.
221   * Has space for other key types to be added later.  Cannot rely on
222   * enum ordinals . They change if item is removed or moved.  Do our own codes.
223   */
224  public static enum Type {
225    Minimum((byte)0),
226    Put((byte)4),
227
228    Delete((byte)8),
229    DeleteFamilyVersion((byte)10),
230    DeleteColumn((byte)12),
231    DeleteFamily((byte)14),
232
233    // Maximum is used when searching; you look from maximum on down.
234    Maximum((byte)255);
235
236    private final byte code;
237
238    Type(final byte c) {
239      this.code = c;
240    }
241
242    public byte getCode() {
243      return this.code;
244    }
245
246    private static Type[] codeArray = new Type[256];
247
248    static {
249      for (Type t : Type.values()) {
250        codeArray[t.code & 0xff] = t;
251      }
252    }
253
254    /**
255     * Cannot rely on enum ordinals . They change if item is removed or moved.
256     * Do our own codes.
257     * @param b
258     * @return Type associated with passed code.
259     */
260    public static Type codeToType(final byte b) {
261      Type t = codeArray[b & 0xff];
262      if (t != null) {
263        return t;
264      }
265      throw new RuntimeException("Unknown code " + b);
266    }
267  }
268
269  /**
270   * Lowest possible key.
271   * Makes a Key with highest possible Timestamp, empty row and column.  No
272   * key can be equal or lower than this one in memstore or in store file.
273   */
274  public static final KeyValue LOWESTKEY =
275    new KeyValue(HConstants.EMPTY_BYTE_ARRAY, HConstants.LATEST_TIMESTAMP);
276
277  ////
278  // KeyValue core instance fields.
279  protected byte [] bytes = null;  // an immutable byte array that contains the KV
280  protected int offset = 0;  // offset into bytes buffer KV starts at
281  protected int length = 0;  // length of the KV starting from offset.
282
283  /** Here be dragons **/
284
285  /**
286   * used to achieve atomic operations in the memstore.
287   */
288  @Override
289  public long getSequenceId() {
290    return seqId;
291  }
292
293  @Override
294  public void setSequenceId(long seqId) {
295    this.seqId = seqId;
296  }
297
298  // multi-version concurrency control version.  default value is 0, aka do not care.
299  private long seqId = 0;
300
301  /** Dragon time over, return to normal business */
302
303
304  /** Writable Constructor -- DO NOT USE */
305  public KeyValue() {}
306
307  /**
308   * Creates a KeyValue from the start of the specified byte array.
309   * Presumes <code>bytes</code> content is formatted as a KeyValue blob.
310   * @param bytes byte array
311   */
312  public KeyValue(final byte [] bytes) {
313    this(bytes, 0);
314  }
315
316  /**
317   * Creates a KeyValue from the specified byte array and offset.
318   * Presumes <code>bytes</code> content starting at <code>offset</code> is
319   * formatted as a KeyValue blob.
320   * @param bytes byte array
321   * @param offset offset to start of KeyValue
322   */
323  public KeyValue(final byte [] bytes, final int offset) {
324    this(bytes, offset, getLength(bytes, offset));
325  }
326
327  /**
328   * Creates a KeyValue from the specified byte array, starting at offset, and
329   * for length <code>length</code>.
330   * @param bytes byte array
331   * @param offset offset to start of the KeyValue
332   * @param length length of the KeyValue
333   */
334  public KeyValue(final byte [] bytes, final int offset, final int length) {
335    this.bytes = bytes;
336    this.offset = offset;
337    this.length = length;
338  }
339
340  /**
341   * Creates a KeyValue from the specified byte array, starting at offset, and
342   * for length <code>length</code>.
343   *
344   * @param bytes  byte array
345   * @param offset offset to start of the KeyValue
346   * @param length length of the KeyValue
347   * @param ts
348   */
349  public KeyValue(final byte[] bytes, final int offset, final int length, long ts) {
350    this(bytes, offset, length, null, 0, 0, null, 0, 0, ts, Type.Maximum, null, 0, 0, null);
351  }
352
353  /** Constructors that build a new backing byte array from fields */
354
355  /**
356   * Constructs KeyValue structure filled with null value.
357   * Sets type to {@link KeyValue.Type#Maximum}
358   * @param row - row key (arbitrary byte array)
359   * @param timestamp
360   */
361  public KeyValue(final byte [] row, final long timestamp) {
362    this(row, null, null, timestamp, Type.Maximum, null);
363  }
364
365  /**
366   * Constructs KeyValue structure filled with null value.
367   * @param row - row key (arbitrary byte array)
368   * @param timestamp
369   */
370  public KeyValue(final byte [] row, final long timestamp, Type type) {
371    this(row, null, null, timestamp, type, null);
372  }
373
374  /**
375   * Constructs KeyValue structure filled with null value.
376   * Sets type to {@link KeyValue.Type#Maximum}
377   * @param row - row key (arbitrary byte array)
378   * @param family family name
379   * @param qualifier column qualifier
380   */
381  public KeyValue(final byte [] row, final byte [] family,
382      final byte [] qualifier) {
383    this(row, family, qualifier, HConstants.LATEST_TIMESTAMP, Type.Maximum);
384  }
385
386  /**
387   * Constructs KeyValue structure as a put filled with specified values and
388   * LATEST_TIMESTAMP.
389   * @param row - row key (arbitrary byte array)
390   * @param family family name
391   * @param qualifier column qualifier
392   */
393  public KeyValue(final byte [] row, final byte [] family,
394      final byte [] qualifier, final byte [] value) {
395    this(row, family, qualifier, HConstants.LATEST_TIMESTAMP, Type.Put, value);
396  }
397
398  /**
399   * Constructs KeyValue structure filled with specified values.
400   * @param row row key
401   * @param family family name
402   * @param qualifier column qualifier
403   * @param timestamp version timestamp
404   * @param type key type
405   * @throws IllegalArgumentException
406   */
407  public KeyValue(final byte[] row, final byte[] family,
408      final byte[] qualifier, final long timestamp, Type type) {
409    this(row, family, qualifier, timestamp, type, null);
410  }
411
412  /**
413   * Constructs KeyValue structure filled with specified values.
414   * @param row row key
415   * @param family family name
416   * @param qualifier column qualifier
417   * @param timestamp version timestamp
418   * @param value column value
419   * @throws IllegalArgumentException
420   */
421  public KeyValue(final byte[] row, final byte[] family,
422      final byte[] qualifier, final long timestamp, final byte[] value) {
423    this(row, family, qualifier, timestamp, Type.Put, value);
424  }
425
426  /**
427   * Constructs KeyValue structure filled with specified values.
428   * @param row row key
429   * @param family family name
430   * @param qualifier column qualifier
431   * @param timestamp version timestamp
432   * @param value column value
433   * @param tags tags
434   * @throws IllegalArgumentException
435   */
436  public KeyValue(final byte[] row, final byte[] family,
437      final byte[] qualifier, final long timestamp, final byte[] value,
438      final Tag[] tags) {
439    this(row, family, qualifier, timestamp, value, tags != null ? Arrays.asList(tags) : null);
440  }
441
442  /**
443   * Constructs KeyValue structure filled with specified values.
444   * @param row row key
445   * @param family family name
446   * @param qualifier column qualifier
447   * @param timestamp version timestamp
448   * @param value column value
449   * @param tags tags non-empty list of tags or null
450   * @throws IllegalArgumentException
451   */
452  public KeyValue(final byte[] row, final byte[] family,
453      final byte[] qualifier, final long timestamp, final byte[] value,
454      final List<Tag> tags) {
455    this(row, 0, row==null ? 0 : row.length,
456      family, 0, family==null ? 0 : family.length,
457      qualifier, 0, qualifier==null ? 0 : qualifier.length,
458      timestamp, Type.Put,
459      value, 0, value==null ? 0 : value.length, tags);
460  }
461
462  /**
463   * Constructs KeyValue structure filled with specified values.
464   * @param row row key
465   * @param family family name
466   * @param qualifier column qualifier
467   * @param timestamp version timestamp
468   * @param type key type
469   * @param value column value
470   * @throws IllegalArgumentException
471   */
472  public KeyValue(final byte[] row, final byte[] family,
473      final byte[] qualifier, final long timestamp, Type type,
474      final byte[] value) {
475    this(row, 0, len(row),   family, 0, len(family),   qualifier, 0, len(qualifier),
476        timestamp, type,   value, 0, len(value));
477  }
478
479  /**
480   * Constructs KeyValue structure filled with specified values.
481   * <p>
482   * Column is split into two fields, family and qualifier.
483   * @param row row key
484   * @param family family name
485   * @param qualifier column qualifier
486   * @param timestamp version timestamp
487   * @param type key type
488   * @param value column value
489   * @throws IllegalArgumentException
490   */
491  public KeyValue(final byte[] row, final byte[] family,
492      final byte[] qualifier, final long timestamp, Type type,
493      final byte[] value, final List<Tag> tags) {
494    this(row, family, qualifier, 0, qualifier==null ? 0 : qualifier.length,
495        timestamp, type, value, 0, value==null ? 0 : value.length, tags);
496  }
497
498  /**
499   * Constructs KeyValue structure filled with specified values.
500   * @param row row key
501   * @param family family name
502   * @param qualifier column qualifier
503   * @param timestamp version timestamp
504   * @param type key type
505   * @param value column value
506   * @throws IllegalArgumentException
507   */
508  public KeyValue(final byte[] row, final byte[] family,
509      final byte[] qualifier, final long timestamp, Type type,
510      final byte[] value, final byte[] tags) {
511    this(row, family, qualifier, 0, qualifier==null ? 0 : qualifier.length,
512        timestamp, type, value, 0, value==null ? 0 : value.length, tags);
513  }
514
515  /**
516   * Constructs KeyValue structure filled with specified values.
517   * @param row row key
518   * @param family family name
519   * @param qualifier column qualifier
520   * @param qoffset qualifier offset
521   * @param qlength qualifier length
522   * @param timestamp version timestamp
523   * @param type key type
524   * @param value column value
525   * @param voffset value offset
526   * @param vlength value length
527   * @throws IllegalArgumentException
528   */
529  public KeyValue(byte [] row, byte [] family,
530      byte [] qualifier, int qoffset, int qlength, long timestamp, Type type,
531      byte [] value, int voffset, int vlength, List<Tag> tags) {
532    this(row, 0, row==null ? 0 : row.length,
533        family, 0, family==null ? 0 : family.length,
534        qualifier, qoffset, qlength, timestamp, type,
535        value, voffset, vlength, tags);
536  }
537
538  /**
539   * @param row
540   * @param family
541   * @param qualifier
542   * @param qoffset
543   * @param qlength
544   * @param timestamp
545   * @param type
546   * @param value
547   * @param voffset
548   * @param vlength
549   * @param tags
550   */
551  public KeyValue(byte [] row, byte [] family,
552      byte [] qualifier, int qoffset, int qlength, long timestamp, Type type,
553      byte [] value, int voffset, int vlength, byte[] tags) {
554    this(row, 0, row==null ? 0 : row.length,
555        family, 0, family==null ? 0 : family.length,
556        qualifier, qoffset, qlength, timestamp, type,
557        value, voffset, vlength, tags, 0, tags==null ? 0 : tags.length);
558  }
559
560  /**
561   * Constructs KeyValue structure filled with specified values.
562   * <p>
563   * Column is split into two fields, family and qualifier.
564   * @param row row key
565   * @throws IllegalArgumentException
566   */
567  public KeyValue(final byte [] row, final int roffset, final int rlength,
568      final byte [] family, final int foffset, final int flength,
569      final byte [] qualifier, final int qoffset, final int qlength,
570      final long timestamp, final Type type,
571      final byte [] value, final int voffset, final int vlength) {
572    this(row, roffset, rlength, family, foffset, flength, qualifier, qoffset,
573      qlength, timestamp, type, value, voffset, vlength, null);
574  }
575
576  /**
577   * Constructs KeyValue structure filled with specified values. Uses the provided buffer as the
578   * data buffer.
579   * <p>
580   * Column is split into two fields, family and qualifier.
581   *
582   * @param buffer the bytes buffer to use
583   * @param boffset buffer offset
584   * @param row row key
585   * @param roffset row offset
586   * @param rlength row length
587   * @param family family name
588   * @param foffset family offset
589   * @param flength family length
590   * @param qualifier column qualifier
591   * @param qoffset qualifier offset
592   * @param qlength qualifier length
593   * @param timestamp version timestamp
594   * @param type key type
595   * @param value column value
596   * @param voffset value offset
597   * @param vlength value length
598   * @param tags non-empty list of tags or null
599   * @throws IllegalArgumentException an illegal value was passed or there is insufficient space
600   * remaining in the buffer
601   */
602  public KeyValue(byte [] buffer, final int boffset,
603      final byte [] row, final int roffset, final int rlength,
604      final byte [] family, final int foffset, final int flength,
605      final byte [] qualifier, final int qoffset, final int qlength,
606      final long timestamp, final Type type,
607      final byte [] value, final int voffset, final int vlength,
608      final Tag[] tags) {
609     this.bytes  = buffer;
610     this.length = writeByteArray(buffer, boffset,
611         row, roffset, rlength,
612         family, foffset, flength, qualifier, qoffset, qlength,
613        timestamp, type, value, voffset, vlength, tags);
614     this.offset = boffset;
615   }
616
617  /**
618   * Constructs KeyValue structure filled with specified values.
619   * <p>
620   * Column is split into two fields, family and qualifier.
621   * @param row row key
622   * @param roffset row offset
623   * @param rlength row length
624   * @param family family name
625   * @param foffset family offset
626   * @param flength family length
627   * @param qualifier column qualifier
628   * @param qoffset qualifier offset
629   * @param qlength qualifier length
630   * @param timestamp version timestamp
631   * @param type key type
632   * @param value column value
633   * @param voffset value offset
634   * @param vlength value length
635   * @param tags tags
636   * @throws IllegalArgumentException
637   */
638  public KeyValue(final byte [] row, final int roffset, final int rlength,
639      final byte [] family, final int foffset, final int flength,
640      final byte [] qualifier, final int qoffset, final int qlength,
641      final long timestamp, final Type type,
642      final byte [] value, final int voffset, final int vlength,
643      final List<Tag> tags) {
644    this.bytes = createByteArray(row, roffset, rlength,
645        family, foffset, flength, qualifier, qoffset, qlength,
646        timestamp, type, value, voffset, vlength, tags);
647    this.length = bytes.length;
648    this.offset = 0;
649  }
650
651  /**
652   * @param row
653   * @param roffset
654   * @param rlength
655   * @param family
656   * @param foffset
657   * @param flength
658   * @param qualifier
659   * @param qoffset
660   * @param qlength
661   * @param timestamp
662   * @param type
663   * @param value
664   * @param voffset
665   * @param vlength
666   * @param tags
667   */
668  public KeyValue(final byte [] row, final int roffset, final int rlength,
669      final byte [] family, final int foffset, final int flength,
670      final byte [] qualifier, final int qoffset, final int qlength,
671      final long timestamp, final Type type,
672      final byte [] value, final int voffset, final int vlength,
673      final byte[] tags, final int tagsOffset, final int tagsLength) {
674    this.bytes = createByteArray(row, roffset, rlength,
675        family, foffset, flength, qualifier, qoffset, qlength,
676        timestamp, type, value, voffset, vlength, tags, tagsOffset, tagsLength);
677    this.length = bytes.length;
678    this.offset = 0;
679  }
680
681  /**
682   * Constructs an empty KeyValue structure, with specified sizes.
683   * This can be used to partially fill up KeyValues.
684   * <p>
685   * Column is split into two fields, family and qualifier.
686   * @param rlength row length
687   * @param flength family length
688   * @param qlength qualifier length
689   * @param timestamp version timestamp
690   * @param type key type
691   * @param vlength value length
692   * @throws IllegalArgumentException
693   */
694  public KeyValue(final int rlength,
695      final int flength,
696      final int qlength,
697      final long timestamp, final Type type,
698      final int vlength) {
699    this(rlength, flength, qlength, timestamp, type, vlength, 0);
700  }
701
702  /**
703   * Constructs an empty KeyValue structure, with specified sizes.
704   * This can be used to partially fill up KeyValues.
705   * <p>
706   * Column is split into two fields, family and qualifier.
707   * @param rlength row length
708   * @param flength family length
709   * @param qlength qualifier length
710   * @param timestamp version timestamp
711   * @param type key type
712   * @param vlength value length
713   * @param tagsLength
714   * @throws IllegalArgumentException
715   */
716  public KeyValue(final int rlength,
717      final int flength,
718      final int qlength,
719      final long timestamp, final Type type,
720      final int vlength, final int tagsLength) {
721    this.bytes = createEmptyByteArray(rlength, flength, qlength, timestamp, type, vlength,
722        tagsLength);
723    this.length = bytes.length;
724    this.offset = 0;
725  }
726
727
728  public KeyValue(byte[] row, int roffset, int rlength,
729                  byte[] family, int foffset, int flength,
730                  ByteBuffer qualifier, long ts, Type type, ByteBuffer value, List<Tag> tags) {
731    this.bytes = createByteArray(row, roffset, rlength, family, foffset, flength,
732        qualifier, 0, qualifier == null ? 0 : qualifier.remaining(), ts, type,
733        value, 0, value == null ? 0 : value.remaining(), tags);
734    this.length = bytes.length;
735    this.offset = 0;
736  }
737
738  public KeyValue(Cell c) {
739    this(c.getRowArray(), c.getRowOffset(), c.getRowLength(),
740        c.getFamilyArray(), c.getFamilyOffset(), c.getFamilyLength(),
741        c.getQualifierArray(), c.getQualifierOffset(), c.getQualifierLength(),
742        c.getTimestamp(), Type.codeToType(c.getTypeByte()), c.getValueArray(), c.getValueOffset(),
743        c.getValueLength(), c.getTagsArray(), c.getTagsOffset(), c.getTagsLength());
744    this.seqId = c.getSequenceId();
745  }
746
747  /**
748   * Create an empty byte[] representing a KeyValue
749   * All lengths are preset and can be filled in later.
750   * @param rlength
751   * @param flength
752   * @param qlength
753   * @param timestamp
754   * @param type
755   * @param vlength
756   * @return The newly created byte array.
757   */
758  private static byte[] createEmptyByteArray(final int rlength, int flength,
759      int qlength, final long timestamp, final Type type, int vlength, int tagsLength) {
760    if (rlength > Short.MAX_VALUE) {
761      throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
762    }
763    if (flength > Byte.MAX_VALUE) {
764      throw new IllegalArgumentException("Family > " + Byte.MAX_VALUE);
765    }
766    // Qualifier length
767    if (qlength > Integer.MAX_VALUE - rlength - flength) {
768      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
769    }
770    RawCell.checkForTagsLength(tagsLength);
771    // Key length
772    long longkeylength = getKeyDataStructureSize(rlength, flength, qlength);
773    if (longkeylength > Integer.MAX_VALUE) {
774      throw new IllegalArgumentException("keylength " + longkeylength + " > " +
775        Integer.MAX_VALUE);
776    }
777    int keylength = (int)longkeylength;
778    // Value length
779    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
780      throw new IllegalArgumentException("Valuer > " +
781          HConstants.MAXIMUM_VALUE_LENGTH);
782    }
783
784    // Allocate right-sized byte array.
785    byte[] bytes= new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength,
786        tagsLength)];
787    // Write the correct size markers
788    int pos = 0;
789    pos = Bytes.putInt(bytes, pos, keylength);
790    pos = Bytes.putInt(bytes, pos, vlength);
791    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
792    pos += rlength;
793    pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
794    pos += flength + qlength;
795    pos = Bytes.putLong(bytes, pos, timestamp);
796    pos = Bytes.putByte(bytes, pos, type.getCode());
797    pos += vlength;
798    if (tagsLength > 0) {
799      pos = Bytes.putAsShort(bytes, pos, tagsLength);
800    }
801    return bytes;
802  }
803
804  /**
805   * Checks the parameters passed to a constructor.
806   *
807   * @param row row key
808   * @param rlength row length
809   * @param family family name
810   * @param flength family length
811   * @param qlength qualifier length
812   * @param vlength value length
813   *
814   * @throws IllegalArgumentException an illegal value was passed
815   */
816  static void checkParameters(final byte [] row, final int rlength,
817      final byte [] family, int flength, int qlength, int vlength)
818          throws IllegalArgumentException {
819    if (rlength > Short.MAX_VALUE) {
820      throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
821    }
822    if (row == null) {
823      throw new IllegalArgumentException("Row is null");
824    }
825    // Family length
826    flength = family == null ? 0 : flength;
827    if (flength > Byte.MAX_VALUE) {
828      throw new IllegalArgumentException("Family > " + Byte.MAX_VALUE);
829    }
830    // Qualifier length
831    if (qlength > Integer.MAX_VALUE - rlength - flength) {
832      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
833    }
834    // Key length
835    long longKeyLength = getKeyDataStructureSize(rlength, flength, qlength);
836    if (longKeyLength > Integer.MAX_VALUE) {
837      throw new IllegalArgumentException("keylength " + longKeyLength + " > " +
838          Integer.MAX_VALUE);
839    }
840    // Value length
841    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
842      throw new IllegalArgumentException("Value length " + vlength + " > " +
843          HConstants.MAXIMUM_VALUE_LENGTH);
844    }
845  }
846
847  /**
848   * Write KeyValue format into the provided byte array.
849   *
850   * @param buffer the bytes buffer to use
851   * @param boffset buffer offset
852   * @param row row key
853   * @param roffset row offset
854   * @param rlength row length
855   * @param family family name
856   * @param foffset family offset
857   * @param flength family length
858   * @param qualifier column qualifier
859   * @param qoffset qualifier offset
860   * @param qlength qualifier length
861   * @param timestamp version timestamp
862   * @param type key type
863   * @param value column value
864   * @param voffset value offset
865   * @param vlength value length
866   *
867   * @return The number of useful bytes in the buffer.
868   *
869   * @throws IllegalArgumentException an illegal value was passed or there is insufficient space
870   * remaining in the buffer
871   */
872  public static int writeByteArray(byte [] buffer, final int boffset,
873      final byte [] row, final int roffset, final int rlength,
874      final byte [] family, final int foffset, int flength,
875      final byte [] qualifier, final int qoffset, int qlength,
876      final long timestamp, final Type type,
877      final byte [] value, final int voffset, int vlength, Tag[] tags) {
878
879    checkParameters(row, rlength, family, flength, qlength, vlength);
880
881    // Calculate length of tags area
882    int tagsLength = 0;
883    if (tags != null && tags.length > 0) {
884      for (Tag t: tags) {
885        tagsLength += t.getValueLength() + Tag.INFRASTRUCTURE_SIZE;
886      }
887    }
888    RawCell.checkForTagsLength(tagsLength);
889    int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
890    int keyValueLength = (int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength,
891        tagsLength);
892    if (keyValueLength > buffer.length - boffset) {
893      throw new IllegalArgumentException("Buffer size " + (buffer.length - boffset) + " < " +
894          keyValueLength);
895    }
896
897    // Write key, value and key row length.
898    int pos = boffset;
899    pos = Bytes.putInt(buffer, pos, keyLength);
900    pos = Bytes.putInt(buffer, pos, vlength);
901    pos = Bytes.putShort(buffer, pos, (short)(rlength & 0x0000ffff));
902    pos = Bytes.putBytes(buffer, pos, row, roffset, rlength);
903    pos = Bytes.putByte(buffer, pos, (byte) (flength & 0x0000ff));
904    if (flength != 0) {
905      pos = Bytes.putBytes(buffer, pos, family, foffset, flength);
906    }
907    if (qlength != 0) {
908      pos = Bytes.putBytes(buffer, pos, qualifier, qoffset, qlength);
909    }
910    pos = Bytes.putLong(buffer, pos, timestamp);
911    pos = Bytes.putByte(buffer, pos, type.getCode());
912    if (value != null && value.length > 0) {
913      pos = Bytes.putBytes(buffer, pos, value, voffset, vlength);
914    }
915    // Write the number of tags. If it is 0 then it means there are no tags.
916    if (tagsLength > 0) {
917      pos = Bytes.putAsShort(buffer, pos, tagsLength);
918      for (Tag t : tags) {
919        int tlen = t.getValueLength();
920        pos = Bytes.putAsShort(buffer, pos, tlen + Tag.TYPE_LENGTH_SIZE);
921        pos = Bytes.putByte(buffer, pos, t.getType());
922        Tag.copyValueTo(t, buffer, pos);
923        pos += tlen;
924      }
925    }
926    return keyValueLength;
927  }
928
929  /**
930   * Write KeyValue format into a byte array.
931   * @param row row key
932   * @param roffset row offset
933   * @param rlength row length
934   * @param family family name
935   * @param foffset family offset
936   * @param flength family length
937   * @param qualifier column qualifier
938   * @param qoffset qualifier offset
939   * @param qlength qualifier length
940   * @param timestamp version timestamp
941   * @param type key type
942   * @param value column value
943   * @param voffset value offset
944   * @param vlength value length
945   * @return The newly created byte array.
946   */
947  private static byte [] createByteArray(final byte [] row, final int roffset,
948      final int rlength, final byte [] family, final int foffset, int flength,
949      final byte [] qualifier, final int qoffset, int qlength,
950      final long timestamp, final Type type,
951      final byte [] value, final int voffset,
952      int vlength, byte[] tags, int tagsOffset, int tagsLength) {
953
954    checkParameters(row, rlength, family, flength, qlength, vlength);
955    RawCell.checkForTagsLength(tagsLength);
956    // Allocate right-sized byte array.
957    int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
958    byte[] bytes = new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength,
959      tagsLength)];
960    // Write key, value and key row length.
961    int pos = 0;
962    pos = Bytes.putInt(bytes, pos, keyLength);
963    pos = Bytes.putInt(bytes, pos, vlength);
964    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
965    pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
966    pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
967    if(flength != 0) {
968      pos = Bytes.putBytes(bytes, pos, family, foffset, flength);
969    }
970    if(qlength != 0) {
971      pos = Bytes.putBytes(bytes, pos, qualifier, qoffset, qlength);
972    }
973    pos = Bytes.putLong(bytes, pos, timestamp);
974    pos = Bytes.putByte(bytes, pos, type.getCode());
975    if (value != null && value.length > 0) {
976      pos = Bytes.putBytes(bytes, pos, value, voffset, vlength);
977    }
978    // Add the tags after the value part
979    if (tagsLength > 0) {
980      pos = Bytes.putAsShort(bytes, pos, tagsLength);
981      pos = Bytes.putBytes(bytes, pos, tags, tagsOffset, tagsLength);
982    }
983    return bytes;
984  }
985
986  /**
987   * @param qualifier can be a ByteBuffer or a byte[], or null.
988   * @param value can be a ByteBuffer or a byte[], or null.
989   */
990  private static byte [] createByteArray(final byte [] row, final int roffset,
991      final int rlength, final byte [] family, final int foffset, int flength,
992      final Object qualifier, final int qoffset, int qlength,
993      final long timestamp, final Type type,
994      final Object value, final int voffset, int vlength, List<Tag> tags) {
995
996    checkParameters(row, rlength, family, flength, qlength, vlength);
997
998    // Calculate length of tags area
999    int tagsLength = 0;
1000    if (tags != null && !tags.isEmpty()) {
1001      for (Tag t : tags) {
1002        tagsLength += t.getValueLength() + Tag.INFRASTRUCTURE_SIZE;
1003      }
1004    }
1005    RawCell.checkForTagsLength(tagsLength);
1006    // Allocate right-sized byte array.
1007    int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
1008    byte[] bytes = new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength,
1009        tagsLength)];
1010
1011    // Write key, value and key row length.
1012    int pos = 0;
1013    pos = Bytes.putInt(bytes, pos, keyLength);
1014
1015    pos = Bytes.putInt(bytes, pos, vlength);
1016    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
1017    pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
1018    pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
1019    if(flength != 0) {
1020      pos = Bytes.putBytes(bytes, pos, family, foffset, flength);
1021    }
1022    if (qlength > 0) {
1023      if (qualifier instanceof ByteBuffer) {
1024        pos = Bytes.putByteBuffer(bytes, pos, (ByteBuffer) qualifier);
1025      } else {
1026        pos = Bytes.putBytes(bytes, pos, (byte[]) qualifier, qoffset, qlength);
1027      }
1028    }
1029    pos = Bytes.putLong(bytes, pos, timestamp);
1030    pos = Bytes.putByte(bytes, pos, type.getCode());
1031    if (vlength > 0) {
1032      if (value instanceof ByteBuffer) {
1033        pos = Bytes.putByteBuffer(bytes, pos, (ByteBuffer) value);
1034      } else {
1035        pos = Bytes.putBytes(bytes, pos, (byte[]) value, voffset, vlength);
1036      }
1037    }
1038    // Add the tags after the value part
1039    if (tagsLength > 0) {
1040      pos = Bytes.putAsShort(bytes, pos, tagsLength);
1041      for (Tag t : tags) {
1042        int tlen = t.getValueLength();
1043        pos = Bytes.putAsShort(bytes, pos, tlen + Tag.TYPE_LENGTH_SIZE);
1044        pos = Bytes.putByte(bytes, pos, t.getType());
1045        Tag.copyValueTo(t, bytes, pos);
1046        pos += tlen;
1047      }
1048    }
1049    return bytes;
1050  }
1051
1052  /**
1053   * Needed doing 'contains' on List.  Only compares the key portion, not the value.
1054   */
1055  @Override
1056  public boolean equals(Object other) {
1057    if (!(other instanceof Cell)) {
1058      return false;
1059    }
1060    return CellUtil.equals(this, (Cell)other);
1061  }
1062
1063  /**
1064   * In line with {@link #equals(Object)}, only uses the key portion, not the value.
1065   */
1066  @Override
1067  public int hashCode() {
1068    return calculateHashForKey(this);
1069  }
1070
1071  private int calculateHashForKey(Cell cell) {
1072    // pre-calculate the 3 hashes made of byte ranges
1073    int rowHash = Bytes.hashCode(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
1074    int familyHash = Bytes.hashCode(cell.getFamilyArray(), cell.getFamilyOffset(),
1075        cell.getFamilyLength());
1076    int qualifierHash = Bytes.hashCode(cell.getQualifierArray(), cell.getQualifierOffset(),
1077        cell.getQualifierLength());
1078
1079    // combine the 6 sub-hashes
1080    int hash = 31 * rowHash + familyHash;
1081    hash = 31 * hash + qualifierHash;
1082    hash = 31 * hash + (int) cell.getTimestamp();
1083    hash = 31 * hash + cell.getTypeByte();
1084    return hash;
1085  }
1086
1087  //---------------------------------------------------------------------------
1088  //
1089  //  KeyValue cloning
1090  //
1091  //---------------------------------------------------------------------------
1092
1093  /**
1094   * Clones a KeyValue.  This creates a copy, re-allocating the buffer.
1095   * @return Fully copied clone of this KeyValue
1096   * @throws CloneNotSupportedException
1097   */
1098  @Override
1099  public KeyValue clone() throws CloneNotSupportedException {
1100    super.clone();
1101    byte [] b = new byte[this.length];
1102    System.arraycopy(this.bytes, this.offset, b, 0, this.length);
1103    KeyValue ret = new KeyValue(b, 0, b.length);
1104    // Important to clone the memstoreTS as well - otherwise memstore's
1105    // update-in-place methods (eg increment) will end up creating
1106    // new entries
1107    ret.setSequenceId(seqId);
1108    return ret;
1109  }
1110
1111  /**
1112   * Creates a shallow copy of this KeyValue, reusing the data byte buffer.
1113   * http://en.wikipedia.org/wiki/Object_copy
1114   * @return Shallow copy of this KeyValue
1115   */
1116  public KeyValue shallowCopy() {
1117    KeyValue shallowCopy = new KeyValue(this.bytes, this.offset, this.length);
1118    shallowCopy.setSequenceId(this.seqId);
1119    return shallowCopy;
1120  }
1121
1122  //---------------------------------------------------------------------------
1123  //
1124  //  String representation
1125  //
1126  //---------------------------------------------------------------------------
1127
1128  @Override
1129  public String toString() {
1130    if (this.bytes == null || this.bytes.length == 0) {
1131      return "empty";
1132    }
1133    return keyToString(this.bytes, this.offset + ROW_OFFSET, getKeyLength()) + "/vlen="
1134      + getValueLength() + "/seqid=" + seqId;
1135  }
1136
1137  /**
1138   * @param k Key portion of a KeyValue.
1139   * @return Key as a String, empty string if k is null.
1140   */
1141  public static String keyToString(final byte [] k) {
1142    if (k == null) {
1143      return "";
1144    }
1145    return keyToString(k, 0, k.length);
1146  }
1147
1148  /**
1149   * Produces a string map for this key/value pair. Useful for programmatic use
1150   * and manipulation of the data stored in an WALKey, for example, printing
1151   * as JSON. Values are left out due to their tendency to be large. If needed,
1152   * they can be added manually.
1153   *
1154   * @return the Map&lt;String,?&gt; containing data from this key
1155   */
1156  public Map<String, Object> toStringMap() {
1157    Map<String, Object> stringMap = new HashMap<>();
1158    stringMap.put("row", Bytes.toStringBinary(getRowArray(), getRowOffset(), getRowLength()));
1159    stringMap.put("family",
1160      Bytes.toStringBinary(getFamilyArray(), getFamilyOffset(), getFamilyLength()));
1161    stringMap.put("qualifier",
1162      Bytes.toStringBinary(getQualifierArray(), getQualifierOffset(), getQualifierLength()));
1163    stringMap.put("timestamp", getTimestamp());
1164    stringMap.put("vlen", getValueLength());
1165    Iterator<Tag> tags = getTags();
1166    if (tags != null) {
1167      List<String> tagsString = new ArrayList<String>();
1168      while (tags.hasNext()) {
1169        tagsString.add(tags.next().toString());
1170      }
1171      stringMap.put("tag", tagsString);
1172    }
1173    return stringMap;
1174  }
1175
1176  /**
1177   * Use for logging.
1178   * @param b Key portion of a KeyValue.
1179   * @param o Offset to start of key
1180   * @param l Length of key.
1181   * @return Key as a String.
1182   */
1183  public static String keyToString(final byte [] b, final int o, final int l) {
1184    if (b == null) return "";
1185    int rowlength = Bytes.toShort(b, o);
1186    String row = Bytes.toStringBinary(b, o + Bytes.SIZEOF_SHORT, rowlength);
1187    int columnoffset = o + Bytes.SIZEOF_SHORT + 1 + rowlength;
1188    int familylength = b[columnoffset - 1];
1189    int columnlength = l - ((columnoffset - o) + TIMESTAMP_TYPE_SIZE);
1190    String family = familylength == 0? "":
1191      Bytes.toStringBinary(b, columnoffset, familylength);
1192    String qualifier = columnlength == 0? "":
1193      Bytes.toStringBinary(b, columnoffset + familylength,
1194      columnlength - familylength);
1195    long timestamp = Bytes.toLong(b, o + (l - TIMESTAMP_TYPE_SIZE));
1196    String timestampStr = humanReadableTimestamp(timestamp);
1197    byte type = b[o + l - 1];
1198    return row + "/" + family +
1199      (family != null && family.length() > 0? ":" :"") +
1200      qualifier + "/" + timestampStr + "/" + Type.codeToType(type);
1201  }
1202
1203  public static String humanReadableTimestamp(final long timestamp) {
1204    if (timestamp == HConstants.LATEST_TIMESTAMP) {
1205      return "LATEST_TIMESTAMP";
1206    }
1207    if (timestamp == HConstants.OLDEST_TIMESTAMP) {
1208      return "OLDEST_TIMESTAMP";
1209    }
1210    return String.valueOf(timestamp);
1211  }
1212
1213  //---------------------------------------------------------------------------
1214  //
1215  //  Public Member Accessors
1216  //
1217  //---------------------------------------------------------------------------
1218
1219  /**
1220   * To be used only in tests where the Cells are clearly assumed to be of type KeyValue
1221   * and that we need access to the backing array to do some test case related assertions.
1222   * @return The byte array backing this KeyValue.
1223   */
1224  @VisibleForTesting
1225  public byte [] getBuffer() {
1226    return this.bytes;
1227  }
1228
1229  /**
1230   * @return Offset into {@link #getBuffer()} at which this KeyValue starts.
1231   */
1232  public int getOffset() {
1233    return this.offset;
1234  }
1235
1236  /**
1237   * @return Length of bytes this KeyValue occupies in {@link #getBuffer()}.
1238   */
1239  public int getLength() {
1240    return length;
1241  }
1242
1243  //---------------------------------------------------------------------------
1244  //
1245  //  Length and Offset Calculators
1246  //
1247  //---------------------------------------------------------------------------
1248
1249  /**
1250   * Determines the total length of the KeyValue stored in the specified
1251   * byte array and offset.  Includes all headers.
1252   * @param bytes byte array
1253   * @param offset offset to start of the KeyValue
1254   * @return length of entire KeyValue, in bytes
1255   */
1256  private static int getLength(byte [] bytes, int offset) {
1257    int klength = ROW_OFFSET + Bytes.toInt(bytes, offset);
1258    int vlength = Bytes.toInt(bytes, offset + Bytes.SIZEOF_INT);
1259    return klength + vlength;
1260  }
1261
1262  /**
1263   * @return Key offset in backing buffer..
1264   */
1265  public int getKeyOffset() {
1266    return this.offset + ROW_OFFSET;
1267  }
1268
1269  public String getKeyString() {
1270    return Bytes.toStringBinary(getBuffer(), getKeyOffset(), getKeyLength());
1271  }
1272
1273  /**
1274   * @return Length of key portion.
1275   */
1276  public int getKeyLength() {
1277    return Bytes.toInt(this.bytes, this.offset);
1278  }
1279
1280  /**
1281   * @return the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1282   */
1283  @Override
1284  public byte[] getValueArray() {
1285    return bytes;
1286  }
1287
1288  /**
1289   * @return the value offset
1290   */
1291  @Override
1292  public int getValueOffset() {
1293    int voffset = getKeyOffset() + getKeyLength();
1294    return voffset;
1295  }
1296
1297  /**
1298   * @return Value length
1299   */
1300  @Override
1301  public int getValueLength() {
1302    int vlength = Bytes.toInt(this.bytes, this.offset + Bytes.SIZEOF_INT);
1303    return vlength;
1304  }
1305
1306  /**
1307   * @return the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1308   */
1309  @Override
1310  public byte[] getRowArray() {
1311    return bytes;
1312  }
1313
1314  /**
1315   * @return Row offset
1316   */
1317  @Override
1318  public int getRowOffset() {
1319    return this.offset + ROW_KEY_OFFSET;
1320  }
1321
1322  /**
1323   * @return Row length
1324   */
1325  @Override
1326  public short getRowLength() {
1327    return Bytes.toShort(this.bytes, getKeyOffset());
1328  }
1329
1330  /**
1331   * @return the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1332   */
1333  @Override
1334  public byte[] getFamilyArray() {
1335    return bytes;
1336  }
1337
1338  /**
1339   * @return Family offset
1340   */
1341  @Override
1342  public int getFamilyOffset() {
1343    return getFamilyOffset(getRowLength());
1344  }
1345
1346  /**
1347   * @return Family offset
1348   */
1349  private int getFamilyOffset(int rlength) {
1350    return this.offset + ROW_KEY_OFFSET + rlength + Bytes.SIZEOF_BYTE;
1351  }
1352
1353  /**
1354   * @return Family length
1355   */
1356  @Override
1357  public byte getFamilyLength() {
1358    return getFamilyLength(getFamilyOffset());
1359  }
1360
1361  /**
1362   * @return Family length
1363   */
1364  public byte getFamilyLength(int foffset) {
1365    return this.bytes[foffset-1];
1366  }
1367
1368  /**
1369   * @return the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1370   */
1371  @Override
1372  public byte[] getQualifierArray() {
1373    return bytes;
1374  }
1375
1376  /**
1377   * @return Qualifier offset
1378   */
1379  @Override
1380  public int getQualifierOffset() {
1381    return getQualifierOffset(getFamilyOffset());
1382  }
1383
1384  /**
1385   * @return Qualifier offset
1386   */
1387  private int getQualifierOffset(int foffset) {
1388    return foffset + getFamilyLength(foffset);
1389  }
1390
1391  /**
1392   * @return Qualifier length
1393   */
1394  @Override
1395  public int getQualifierLength() {
1396    return getQualifierLength(getRowLength(),getFamilyLength());
1397  }
1398
1399  /**
1400   * @return Qualifier length
1401   */
1402  private int getQualifierLength(int rlength, int flength) {
1403    return getKeyLength() - (int) getKeyDataStructureSize(rlength, flength, 0);
1404  }
1405
1406  /**
1407   * @return Timestamp offset
1408   */
1409  public int getTimestampOffset() {
1410    return getTimestampOffset(getKeyLength());
1411  }
1412
1413  /**
1414   * @param keylength Pass if you have it to save on a int creation.
1415   * @return Timestamp offset
1416   */
1417  private int getTimestampOffset(final int keylength) {
1418    return getKeyOffset() + keylength - TIMESTAMP_TYPE_SIZE;
1419  }
1420
1421  /**
1422   * @return True if this KeyValue has a LATEST_TIMESTAMP timestamp.
1423   */
1424  public boolean isLatestTimestamp() {
1425    return Bytes.equals(getBuffer(), getTimestampOffset(), Bytes.SIZEOF_LONG,
1426      HConstants.LATEST_TIMESTAMP_BYTES, 0, Bytes.SIZEOF_LONG);
1427  }
1428
1429  /**
1430   * @param now Time to set into <code>this</code> IFF timestamp ==
1431   * {@link HConstants#LATEST_TIMESTAMP} (else, its a noop).
1432   * @return True is we modified this.
1433   */
1434  public boolean updateLatestStamp(final byte [] now) {
1435    if (this.isLatestTimestamp()) {
1436      int tsOffset = getTimestampOffset();
1437      System.arraycopy(now, 0, this.bytes, tsOffset, Bytes.SIZEOF_LONG);
1438      // clear cache or else getTimestamp() possibly returns an old value
1439      return true;
1440    }
1441    return false;
1442  }
1443
1444  @Override
1445  public void setTimestamp(long ts) {
1446    Bytes.putBytes(this.bytes, this.getTimestampOffset(), Bytes.toBytes(ts), 0, Bytes.SIZEOF_LONG);
1447  }
1448
1449  @Override
1450  public void setTimestamp(byte[] ts) {
1451    Bytes.putBytes(this.bytes, this.getTimestampOffset(), ts, 0, Bytes.SIZEOF_LONG);
1452  }
1453
1454  //---------------------------------------------------------------------------
1455  //
1456  //  Methods that return copies of fields
1457  //
1458  //---------------------------------------------------------------------------
1459
1460  /**
1461   * Do not use unless you have to. Used internally for compacting and testing. Use
1462   * {@link #getRowArray()}, {@link #getFamilyArray()}, {@link #getQualifierArray()}, and
1463   * {@link #getValueArray()} if accessing a KeyValue client-side.
1464   * @return Copy of the key portion only.
1465   */
1466  public byte [] getKey() {
1467    int keylength = getKeyLength();
1468    byte [] key = new byte[keylength];
1469    System.arraycopy(getBuffer(), getKeyOffset(), key, 0, keylength);
1470    return key;
1471  }
1472
1473  /**
1474   *
1475   * @return Timestamp
1476   */
1477  @Override
1478  public long getTimestamp() {
1479    return getTimestamp(getKeyLength());
1480  }
1481
1482  /**
1483   * @param keylength Pass if you have it to save on a int creation.
1484   * @return Timestamp
1485   */
1486  long getTimestamp(final int keylength) {
1487    int tsOffset = getTimestampOffset(keylength);
1488    return Bytes.toLong(this.bytes, tsOffset);
1489  }
1490
1491  /**
1492   * @return KeyValue.TYPE byte representation
1493   */
1494  @Override
1495  public byte getTypeByte() {
1496    return this.bytes[this.offset + getKeyLength() - 1 + ROW_OFFSET];
1497  }
1498
1499  /**
1500   * This returns the offset where the tag actually starts.
1501   */
1502  @Override
1503  public int getTagsOffset() {
1504    int tagsLen = getTagsLength();
1505    if (tagsLen == 0) {
1506      return this.offset + this.length;
1507    }
1508    return this.offset + this.length - tagsLen;
1509  }
1510
1511  /**
1512   * This returns the total length of the tag bytes
1513   */
1514  @Override
1515  public int getTagsLength() {
1516    int tagsLen = this.length - (getKeyLength() + getValueLength() + KEYVALUE_INFRASTRUCTURE_SIZE);
1517    if (tagsLen > 0) {
1518      // There are some Tag bytes in the byte[]. So reduce 2 bytes which is added to denote the tags
1519      // length
1520      tagsLen -= TAGS_LENGTH_SIZE;
1521    }
1522    return tagsLen;
1523  }
1524
1525  /**
1526   * @return the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1527   */
1528  @Override
1529  public byte[] getTagsArray() {
1530    return bytes;
1531  }
1532
1533  /**
1534   * Creates a new KeyValue that only contains the key portion (the value is
1535   * set to be null).
1536   *
1537   * TODO only used by KeyOnlyFilter -- move there.
1538   * @param lenAsVal replace value with the actual value length (false=empty)
1539   */
1540  public KeyValue createKeyOnly(boolean lenAsVal) {
1541    // KV format:  <keylen:4><valuelen:4><key:keylen><value:valuelen>
1542    // Rebuild as: <keylen:4><0:4><key:keylen>
1543    int dataLen = lenAsVal? Bytes.SIZEOF_INT : 0;
1544    byte [] newBuffer = new byte[getKeyLength() + ROW_OFFSET + dataLen];
1545    System.arraycopy(this.bytes, this.offset, newBuffer, 0,
1546        Math.min(newBuffer.length,this.length));
1547    Bytes.putInt(newBuffer, Bytes.SIZEOF_INT, dataLen);
1548    if (lenAsVal) {
1549      Bytes.putInt(newBuffer, newBuffer.length - dataLen, this.getValueLength());
1550    }
1551    return new KeyValue(newBuffer);
1552  }
1553
1554  /**
1555   * @param b
1556   * @param delimiter
1557   * @return Index of delimiter having started from start of <code>b</code>
1558   * moving rightward.
1559   */
1560  public static int getDelimiter(final byte [] b, int offset, final int length,
1561      final int delimiter) {
1562    if (b == null) {
1563      throw new IllegalArgumentException("Passed buffer is null");
1564    }
1565    int result = -1;
1566    for (int i = offset; i < length + offset; i++) {
1567      if (b[i] == delimiter) {
1568        result = i;
1569        break;
1570      }
1571    }
1572    return result;
1573  }
1574
1575  /**
1576   * Find index of passed delimiter walking from end of buffer backwards.
1577   * @param b
1578   * @param delimiter
1579   * @return Index of delimiter
1580   */
1581  public static int getDelimiterInReverse(final byte [] b, final int offset,
1582      final int length, final int delimiter) {
1583    if (b == null) {
1584      throw new IllegalArgumentException("Passed buffer is null");
1585    }
1586    int result = -1;
1587    for (int i = (offset + length) - 1; i >= offset; i--) {
1588      if (b[i] == delimiter) {
1589        result = i;
1590        break;
1591      }
1592    }
1593    return result;
1594  }
1595
1596  /**
1597   * A {@link KVComparator} for <code>hbase:meta</code> catalog table
1598   * {@link KeyValue}s.
1599   * @deprecated : {@link CellComparatorImpl#META_COMPARATOR} to be used. Deprecated for hbase 2.0, remove for hbase 3.0.
1600   */
1601  @Deprecated
1602  public static class MetaComparator extends KVComparator {
1603    /**
1604     * Compare key portion of a {@link KeyValue} for keys in <code>hbase:meta</code>
1605     * table.
1606     */
1607    @Override
1608    public int compare(final Cell left, final Cell right) {
1609      return PrivateCellUtil.compareKeyIgnoresMvcc(CellComparatorImpl.META_COMPARATOR, left, right);
1610    }
1611
1612    @Override
1613    public int compareOnlyKeyPortion(Cell left, Cell right) {
1614      return compare(left, right);
1615    }
1616
1617    @Override
1618    public int compareRows(byte [] left, int loffset, int llength,
1619        byte [] right, int roffset, int rlength) {
1620      int leftDelimiter = getDelimiter(left, loffset, llength,
1621          HConstants.DELIMITER);
1622      int rightDelimiter = getDelimiter(right, roffset, rlength,
1623          HConstants.DELIMITER);
1624      // Compare up to the delimiter
1625      int lpart = (leftDelimiter < 0 ? llength :leftDelimiter - loffset);
1626      int rpart = (rightDelimiter < 0 ? rlength :rightDelimiter - roffset);
1627      int result = Bytes.compareTo(left, loffset, lpart, right, roffset, rpart);
1628      if (result != 0) {
1629        return result;
1630      } else {
1631        if (leftDelimiter < 0 && rightDelimiter >= 0) {
1632          return -1;
1633        } else if (rightDelimiter < 0 && leftDelimiter >= 0) {
1634          return 1;
1635        } else if (leftDelimiter < 0 && rightDelimiter < 0) {
1636          return 0;
1637        }
1638      }
1639      // Compare middle bit of the row.
1640      // Move past delimiter
1641      leftDelimiter++;
1642      rightDelimiter++;
1643      int leftFarDelimiter = getDelimiterInReverse(left, leftDelimiter,
1644          llength - (leftDelimiter - loffset), HConstants.DELIMITER);
1645      int rightFarDelimiter = getDelimiterInReverse(right,
1646          rightDelimiter, rlength - (rightDelimiter - roffset),
1647          HConstants.DELIMITER);
1648      // Now compare middlesection of row.
1649      lpart = (leftFarDelimiter < 0 ? llength + loffset: leftFarDelimiter) - leftDelimiter;
1650      rpart = (rightFarDelimiter < 0 ? rlength + roffset: rightFarDelimiter)- rightDelimiter;
1651      result = super.compareRows(left, leftDelimiter, lpart, right, rightDelimiter, rpart);
1652      if (result != 0) {
1653        return result;
1654      }  else {
1655        if (leftDelimiter < 0 && rightDelimiter >= 0) {
1656          return -1;
1657        } else if (rightDelimiter < 0 && leftDelimiter >= 0) {
1658          return 1;
1659        } else if (leftDelimiter < 0 && rightDelimiter < 0) {
1660          return 0;
1661        }
1662      }
1663      // Compare last part of row, the rowid.
1664      leftFarDelimiter++;
1665      rightFarDelimiter++;
1666      result = Bytes.compareTo(left, leftFarDelimiter, llength - (leftFarDelimiter - loffset),
1667          right, rightFarDelimiter, rlength - (rightFarDelimiter - roffset));
1668      return result;
1669    }
1670
1671    /**
1672     * Don't do any fancy Block Index splitting tricks.
1673     */
1674    @Override
1675    public byte[] getShortMidpointKey(final byte[] leftKey, final byte[] rightKey) {
1676      return Arrays.copyOf(rightKey, rightKey.length);
1677    }
1678
1679    /**
1680     * The HFileV2 file format's trailer contains this class name.  We reinterpret this and
1681     * instantiate the appropriate comparator.
1682     * TODO: With V3 consider removing this.
1683     * @return legacy class name for FileFileTrailer#comparatorClassName
1684     */
1685    @Override
1686    public String getLegacyKeyComparatorName() {
1687      return "org.apache.hadoop.hbase.KeyValue$MetaKeyComparator";
1688    }
1689
1690    @Override
1691    protected Object clone() throws CloneNotSupportedException {
1692      return new MetaComparator();
1693    }
1694
1695    /**
1696     * Override the row key comparison to parse and compare the meta row key parts.
1697     */
1698    @Override
1699    protected int compareRowKey(final Cell l, final Cell r) {
1700      byte[] left = l.getRowArray();
1701      int loffset = l.getRowOffset();
1702      int llength = l.getRowLength();
1703      byte[] right = r.getRowArray();
1704      int roffset = r.getRowOffset();
1705      int rlength = r.getRowLength();
1706      return compareRows(left, loffset, llength, right, roffset, rlength);
1707    }
1708  }
1709
1710  /**
1711   * Compare KeyValues.  When we compare KeyValues, we only compare the Key
1712   * portion.  This means two KeyValues with same Key but different Values are
1713   * considered the same as far as this Comparator is concerned.
1714   * @deprecated : Use {@link CellComparatorImpl}. Deprecated for hbase 2.0, remove for hbase 3.0.
1715   */
1716  @Deprecated
1717  public static class KVComparator implements RawComparator<Cell>, SamePrefixComparator<byte[]> {
1718
1719    /**
1720     * The HFileV2 file format's trailer contains this class name.  We reinterpret this and
1721     * instantiate the appropriate comparator.
1722     * TODO: With V3 consider removing this.
1723     * @return legacy class name for FileFileTrailer#comparatorClassName
1724     */
1725    public String getLegacyKeyComparatorName() {
1726      return "org.apache.hadoop.hbase.KeyValue$KeyComparator";
1727    }
1728
1729    @Override // RawComparator
1730    public int compare(byte[] l, int loff, int llen, byte[] r, int roff, int rlen) {
1731      return compareFlatKey(l,loff,llen, r,roff,rlen);
1732    }
1733
1734
1735    /**
1736     * Compares the only the user specified portion of a Key.  This is overridden by MetaComparator.
1737     * @param left
1738     * @param right
1739     * @return 0 if equal, &lt;0 if left smaller, &gt;0 if right smaller
1740     */
1741    protected int compareRowKey(final Cell left, final Cell right) {
1742      return CellComparatorImpl.COMPARATOR.compareRows(left, right);
1743    }
1744
1745    /**
1746     * Compares left to right assuming that left,loffset,llength and right,roffset,rlength are
1747     * full KVs laid out in a flat byte[]s.
1748     * @param left
1749     * @param loffset
1750     * @param llength
1751     * @param right
1752     * @param roffset
1753     * @param rlength
1754     * @return  0 if equal, &lt;0 if left smaller, &gt;0 if right smaller
1755     */
1756    public int compareFlatKey(byte[] left, int loffset, int llength,
1757        byte[] right, int roffset, int rlength) {
1758      // Compare row
1759      short lrowlength = Bytes.toShort(left, loffset);
1760      short rrowlength = Bytes.toShort(right, roffset);
1761      int compare = compareRows(left, loffset + Bytes.SIZEOF_SHORT,
1762          lrowlength, right, roffset + Bytes.SIZEOF_SHORT, rrowlength);
1763      if (compare != 0) {
1764        return compare;
1765      }
1766
1767      // Compare the rest of the two KVs without making any assumptions about
1768      // the common prefix. This function will not compare rows anyway, so we
1769      // don't need to tell it that the common prefix includes the row.
1770      return compareWithoutRow(0, left, loffset, llength, right, roffset,
1771          rlength, rrowlength);
1772    }
1773
1774    public int compareFlatKey(byte[] left, byte[] right) {
1775      return compareFlatKey(left, 0, left.length, right, 0, right.length);
1776    }
1777
1778    // compare a key against row/fam/qual/ts/type
1779    public int compareKey(Cell cell,
1780        byte[] row, int roff, int rlen,
1781        byte[] fam, int foff, int flen,
1782        byte[] col, int coff, int clen,
1783        long ts, byte type) {
1784
1785      int compare = compareRows(
1786        cell.getRowArray(), cell.getRowOffset(), cell.getRowLength(),
1787        row, roff, rlen);
1788      if (compare != 0) {
1789        return compare;
1790      }
1791      // If the column is not specified, the "minimum" key type appears the
1792      // latest in the sorted order, regardless of the timestamp. This is used
1793      // for specifying the last key/value in a given row, because there is no
1794      // "lexicographically last column" (it would be infinitely long). The
1795      // "maximum" key type does not need this behavior.
1796      if (cell.getFamilyLength() + cell.getQualifierLength() == 0
1797          && cell.getTypeByte() == Type.Minimum.getCode()) {
1798        // left is "bigger", i.e. it appears later in the sorted order
1799        return 1;
1800      }
1801      if (flen+clen == 0 && type == Type.Minimum.getCode()) {
1802        return -1;
1803      }
1804
1805      compare = compareFamilies(
1806        cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength(),
1807        fam, foff, flen);
1808      if (compare != 0) {
1809        return compare;
1810      }
1811      compare = compareColumns(
1812        cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength(),
1813        col, coff, clen);
1814      if (compare != 0) {
1815        return compare;
1816      }
1817      // Next compare timestamps.
1818      compare = compareTimestamps(cell.getTimestamp(), ts);
1819      if (compare != 0) {
1820        return compare;
1821      }
1822
1823      // Compare types. Let the delete types sort ahead of puts; i.e. types
1824      // of higher numbers sort before those of lesser numbers. Maximum (255)
1825      // appears ahead of everything, and minimum (0) appears after
1826      // everything.
1827      return (0xff & type) - (0xff & cell.getTypeByte());
1828    }
1829
1830    public int compareOnlyKeyPortion(Cell left, Cell right) {
1831      return PrivateCellUtil.compareKeyIgnoresMvcc(CellComparatorImpl.COMPARATOR, left, right);
1832    }
1833
1834    /**
1835     * Compares the Key of a cell -- with fields being more significant in this order:
1836     * rowkey, colfam/qual, timestamp, type, mvcc
1837     */
1838    @Override
1839    public int compare(final Cell left, final Cell right) {
1840      int compare = CellComparatorImpl.COMPARATOR.compare(left, right);
1841      return compare;
1842    }
1843
1844    public int compareTimestamps(final Cell left, final Cell right) {
1845      return CellComparatorImpl.COMPARATOR.compareTimestamps(left, right);
1846    }
1847
1848    /**
1849     * @param left
1850     * @param right
1851     * @return Result comparing rows.
1852     */
1853    public int compareRows(final Cell left, final Cell right) {
1854      return compareRows(left.getRowArray(),left.getRowOffset(), left.getRowLength(),
1855      right.getRowArray(), right.getRowOffset(), right.getRowLength());
1856    }
1857
1858    /**
1859     * Get the b[],o,l for left and right rowkey portions and compare.
1860     * @param left
1861     * @param loffset
1862     * @param llength
1863     * @param right
1864     * @param roffset
1865     * @param rlength
1866     * @return 0 if equal, &lt;0 if left smaller, &gt;0 if right smaller
1867     */
1868    public int compareRows(byte [] left, int loffset, int llength,
1869        byte [] right, int roffset, int rlength) {
1870      return Bytes.compareTo(left, loffset, llength, right, roffset, rlength);
1871    }
1872
1873    int compareColumns(final Cell left, final short lrowlength, final Cell right,
1874        final short rrowlength) {
1875      return CellComparatorImpl.COMPARATOR.compareColumns(left, right);
1876    }
1877
1878    protected int compareColumns(
1879        byte [] left, int loffset, int llength, final int lfamilylength,
1880        byte [] right, int roffset, int rlength, final int rfamilylength) {
1881      // Compare family portion first.
1882      int diff = Bytes.compareTo(left, loffset, lfamilylength,
1883        right, roffset, rfamilylength);
1884      if (diff != 0) {
1885        return diff;
1886      }
1887      // Compare qualifier portion
1888      return Bytes.compareTo(left, loffset + lfamilylength,
1889        llength - lfamilylength,
1890        right, roffset + rfamilylength, rlength - rfamilylength);
1891      }
1892
1893    static int compareTimestamps(final long ltimestamp, final long rtimestamp) {
1894      // The below older timestamps sorting ahead of newer timestamps looks
1895      // wrong but it is intentional. This way, newer timestamps are first
1896      // found when we iterate over a memstore and newer versions are the
1897      // first we trip over when reading from a store file.
1898      if (ltimestamp < rtimestamp) {
1899        return 1;
1900      } else if (ltimestamp > rtimestamp) {
1901        return -1;
1902      }
1903      return 0;
1904    }
1905
1906    /**
1907     * Overridden
1908     * @param commonPrefix
1909     * @param left
1910     * @param loffset
1911     * @param llength
1912     * @param right
1913     * @param roffset
1914     * @param rlength
1915     * @return 0 if equal, &lt;0 if left smaller, &gt;0 if right smaller
1916     */
1917    @Override // SamePrefixComparator
1918    public int compareIgnoringPrefix(int commonPrefix, byte[] left,
1919        int loffset, int llength, byte[] right, int roffset, int rlength) {
1920      // Compare row
1921      short lrowlength = Bytes.toShort(left, loffset);
1922      short rrowlength;
1923
1924      int comparisonResult = 0;
1925      if (commonPrefix < ROW_LENGTH_SIZE) {
1926        // almost nothing in common
1927        rrowlength = Bytes.toShort(right, roffset);
1928        comparisonResult = compareRows(left, loffset + ROW_LENGTH_SIZE,
1929            lrowlength, right, roffset + ROW_LENGTH_SIZE, rrowlength);
1930      } else { // the row length is the same
1931        rrowlength = lrowlength;
1932        if (commonPrefix < ROW_LENGTH_SIZE + rrowlength) {
1933          // The rows are not the same. Exclude the common prefix and compare
1934          // the rest of the two rows.
1935          int common = commonPrefix - ROW_LENGTH_SIZE;
1936          comparisonResult = compareRows(
1937              left, loffset + common + ROW_LENGTH_SIZE, lrowlength - common,
1938              right, roffset + common + ROW_LENGTH_SIZE, rrowlength - common);
1939        }
1940      }
1941      if (comparisonResult != 0) {
1942        return comparisonResult;
1943      }
1944
1945      assert lrowlength == rrowlength;
1946      return compareWithoutRow(commonPrefix, left, loffset, llength, right,
1947          roffset, rlength, lrowlength);
1948    }
1949
1950    /**
1951     * Compare columnFamily, qualifier, timestamp, and key type (everything
1952     * except the row). This method is used both in the normal comparator and
1953     * the "same-prefix" comparator. Note that we are assuming that row portions
1954     * of both KVs have already been parsed and found identical, and we don't
1955     * validate that assumption here.
1956     * @param commonPrefix
1957     *          the length of the common prefix of the two key-values being
1958     *          compared, including row length and row
1959     */
1960    private int compareWithoutRow(int commonPrefix, byte[] left, int loffset,
1961        int llength, byte[] right, int roffset, int rlength, short rowlength) {
1962      /***
1963       * KeyValue Format and commonLength:
1964       * |_keyLen_|_valLen_|_rowLen_|_rowKey_|_famiLen_|_fami_|_Quali_|....
1965       * ------------------|-------commonLength--------|--------------
1966       */
1967      int commonLength = ROW_LENGTH_SIZE + FAMILY_LENGTH_SIZE + rowlength;
1968
1969      // commonLength + TIMESTAMP_TYPE_SIZE
1970      int commonLengthWithTSAndType = TIMESTAMP_TYPE_SIZE + commonLength;
1971      // ColumnFamily + Qualifier length.
1972      int lcolumnlength = llength - commonLengthWithTSAndType;
1973      int rcolumnlength = rlength - commonLengthWithTSAndType;
1974
1975      byte ltype = left[loffset + (llength - 1)];
1976      byte rtype = right[roffset + (rlength - 1)];
1977
1978      // If the column is not specified, the "minimum" key type appears the
1979      // latest in the sorted order, regardless of the timestamp. This is used
1980      // for specifying the last key/value in a given row, because there is no
1981      // "lexicographically last column" (it would be infinitely long). The
1982      // "maximum" key type does not need this behavior.
1983      if (lcolumnlength == 0 && ltype == Type.Minimum.getCode()) {
1984        // left is "bigger", i.e. it appears later in the sorted order
1985        return 1;
1986      }
1987      if (rcolumnlength == 0 && rtype == Type.Minimum.getCode()) {
1988        return -1;
1989      }
1990
1991      int lfamilyoffset = commonLength + loffset;
1992      int rfamilyoffset = commonLength + roffset;
1993
1994      // Column family length.
1995      int lfamilylength = left[lfamilyoffset - 1];
1996      int rfamilylength = right[rfamilyoffset - 1];
1997      // If left family size is not equal to right family size, we need not
1998      // compare the qualifiers.
1999      boolean sameFamilySize = (lfamilylength == rfamilylength);
2000      int common = 0;
2001      if (commonPrefix > 0) {
2002        common = Math.max(0, commonPrefix - commonLength);
2003        if (!sameFamilySize) {
2004          // Common should not be larger than Math.min(lfamilylength,
2005          // rfamilylength).
2006          common = Math.min(common, Math.min(lfamilylength, rfamilylength));
2007        } else {
2008          common = Math.min(common, Math.min(lcolumnlength, rcolumnlength));
2009        }
2010      }
2011      if (!sameFamilySize) {
2012        // comparing column family is enough.
2013        return Bytes.compareTo(left, lfamilyoffset + common, lfamilylength
2014            - common, right, rfamilyoffset + common, rfamilylength - common);
2015      }
2016      // Compare family & qualifier together.
2017      final int comparison = Bytes.compareTo(left, lfamilyoffset + common,
2018          lcolumnlength - common, right, rfamilyoffset + common,
2019          rcolumnlength - common);
2020      if (comparison != 0) {
2021        return comparison;
2022      }
2023
2024      ////
2025      // Next compare timestamps.
2026      long ltimestamp = Bytes.toLong(left,
2027          loffset + (llength - TIMESTAMP_TYPE_SIZE));
2028      long rtimestamp = Bytes.toLong(right,
2029          roffset + (rlength - TIMESTAMP_TYPE_SIZE));
2030      int compare = compareTimestamps(ltimestamp, rtimestamp);
2031      if (compare != 0) {
2032        return compare;
2033      }
2034
2035      // Compare types. Let the delete types sort ahead of puts; i.e. types
2036      // of higher numbers sort before those of lesser numbers. Maximum (255)
2037      // appears ahead of everything, and minimum (0) appears after
2038      // everything.
2039      return (0xff & rtype) - (0xff & ltype);
2040    }
2041
2042    protected int compareFamilies(final byte[] left, final int loffset, final int lfamilylength,
2043        final byte[] right, final int roffset, final int rfamilylength) {
2044      int diff = Bytes.compareTo(left, loffset, lfamilylength, right, roffset, rfamilylength);
2045      return diff;
2046    }
2047
2048    protected int compareColumns(final byte[] left, final int loffset, final int lquallength,
2049        final byte[] right, final int roffset, final int rquallength) {
2050      int diff = Bytes.compareTo(left, loffset, lquallength, right, roffset, rquallength);
2051      return diff;
2052    }
2053    /**
2054     * Compares the row and column of two keyvalues for equality
2055     * @param left
2056     * @param right
2057     * @return True if same row and column.
2058     */
2059    public boolean matchingRowColumn(final Cell left,
2060        final Cell right) {
2061      short lrowlength = left.getRowLength();
2062      short rrowlength = right.getRowLength();
2063
2064      // TsOffset = end of column data. just comparing Row+CF length of each
2065      if ((left.getRowLength() + left.getFamilyLength() + left.getQualifierLength()) != (right
2066          .getRowLength() + right.getFamilyLength() + right.getQualifierLength())) {
2067        return false;
2068      }
2069
2070      if (!matchingRows(left, lrowlength, right, rrowlength)) {
2071        return false;
2072      }
2073
2074      int lfoffset = left.getFamilyOffset();
2075      int rfoffset = right.getFamilyOffset();
2076      int lclength = left.getQualifierLength();
2077      int rclength = right.getQualifierLength();
2078      int lfamilylength = left.getFamilyLength();
2079      int rfamilylength = right.getFamilyLength();
2080      int diff = compareFamilies(left.getFamilyArray(), lfoffset, lfamilylength,
2081          right.getFamilyArray(), rfoffset, rfamilylength);
2082      if (diff != 0) {
2083        return false;
2084      } else {
2085        diff = compareColumns(left.getQualifierArray(), left.getQualifierOffset(), lclength,
2086            right.getQualifierArray(), right.getQualifierOffset(), rclength);
2087        return diff == 0;
2088      }
2089    }
2090
2091    /**
2092     * Compares the row of two keyvalues for equality
2093     * @param left
2094     * @param right
2095     * @return True if rows match.
2096     */
2097    public boolean matchingRows(final Cell left, final Cell right) {
2098      short lrowlength = left.getRowLength();
2099      short rrowlength = right.getRowLength();
2100      return matchingRows(left, lrowlength, right, rrowlength);
2101    }
2102
2103    /**
2104     * @param left
2105     * @param lrowlength
2106     * @param right
2107     * @param rrowlength
2108     * @return True if rows match.
2109     */
2110    private boolean matchingRows(final Cell left, final short lrowlength,
2111        final Cell right, final short rrowlength) {
2112      return lrowlength == rrowlength &&
2113          matchingRows(left.getRowArray(), left.getRowOffset(), lrowlength,
2114              right.getRowArray(), right.getRowOffset(), rrowlength);
2115    }
2116
2117    /**
2118     * Compare rows. Just calls Bytes.equals, but it's good to have this encapsulated.
2119     * @param left Left row array.
2120     * @param loffset Left row offset.
2121     * @param llength Left row length.
2122     * @param right Right row array.
2123     * @param roffset Right row offset.
2124     * @param rlength Right row length.
2125     * @return Whether rows are the same row.
2126     */
2127    public boolean matchingRows(final byte [] left, final int loffset, final int llength,
2128        final byte [] right, final int roffset, final int rlength) {
2129      return Bytes.equals(left, loffset, llength, right, roffset, rlength);
2130    }
2131
2132    public byte[] calcIndexKey(byte[] lastKeyOfPreviousBlock, byte[] firstKeyInBlock) {
2133      byte[] fakeKey = getShortMidpointKey(lastKeyOfPreviousBlock, firstKeyInBlock);
2134      if (compareFlatKey(fakeKey, firstKeyInBlock) > 0) {
2135        LOG.error("Unexpected getShortMidpointKey result, fakeKey:"
2136            + Bytes.toStringBinary(fakeKey) + ", firstKeyInBlock:"
2137            + Bytes.toStringBinary(firstKeyInBlock));
2138        return firstKeyInBlock;
2139      }
2140      if (lastKeyOfPreviousBlock != null && compareFlatKey(lastKeyOfPreviousBlock, fakeKey) >= 0) {
2141        LOG.error("Unexpected getShortMidpointKey result, lastKeyOfPreviousBlock:" +
2142            Bytes.toStringBinary(lastKeyOfPreviousBlock) + ", fakeKey:" +
2143            Bytes.toStringBinary(fakeKey));
2144        return firstKeyInBlock;
2145      }
2146      return fakeKey;
2147    }
2148
2149    /**
2150     * This is a HFile block index key optimization.
2151     * @param leftKey
2152     * @param rightKey
2153     * @return 0 if equal, &lt;0 if left smaller, &gt;0 if right smaller
2154     * @deprecated Since 0.99.2;
2155     */
2156    @Deprecated
2157    public byte[] getShortMidpointKey(final byte[] leftKey, final byte[] rightKey) {
2158      if (rightKey == null) {
2159        throw new IllegalArgumentException("rightKey can not be null");
2160      }
2161      if (leftKey == null) {
2162        return Arrays.copyOf(rightKey, rightKey.length);
2163      }
2164      if (compareFlatKey(leftKey, rightKey) >= 0) {
2165        throw new IllegalArgumentException("Unexpected input, leftKey:" + Bytes.toString(leftKey)
2166          + ", rightKey:" + Bytes.toString(rightKey));
2167      }
2168
2169      short leftRowLength = Bytes.toShort(leftKey, 0);
2170      short rightRowLength = Bytes.toShort(rightKey, 0);
2171      int leftCommonLength = ROW_LENGTH_SIZE + FAMILY_LENGTH_SIZE + leftRowLength;
2172      int rightCommonLength = ROW_LENGTH_SIZE + FAMILY_LENGTH_SIZE + rightRowLength;
2173      int leftCommonLengthWithTSAndType = TIMESTAMP_TYPE_SIZE + leftCommonLength;
2174      int rightCommonLengthWithTSAndType = TIMESTAMP_TYPE_SIZE + rightCommonLength;
2175      int leftColumnLength = leftKey.length - leftCommonLengthWithTSAndType;
2176      int rightColumnLength = rightKey.length - rightCommonLengthWithTSAndType;
2177      // rows are equal
2178      if (leftRowLength == rightRowLength && compareRows(leftKey, ROW_LENGTH_SIZE, leftRowLength,
2179        rightKey, ROW_LENGTH_SIZE, rightRowLength) == 0) {
2180        // Compare family & qualifier together.
2181        int comparison = Bytes.compareTo(leftKey, leftCommonLength, leftColumnLength, rightKey,
2182          rightCommonLength, rightColumnLength);
2183        // same with "row + family + qualifier", return rightKey directly
2184        if (comparison == 0) {
2185          return Arrays.copyOf(rightKey, rightKey.length);
2186        }
2187        // "family + qualifier" are different, generate a faked key per rightKey
2188        byte[] newKey = Arrays.copyOf(rightKey, rightKey.length);
2189        Bytes.putLong(newKey, rightKey.length - TIMESTAMP_TYPE_SIZE, HConstants.LATEST_TIMESTAMP);
2190        Bytes.putByte(newKey, rightKey.length - TYPE_SIZE, Type.Maximum.getCode());
2191        return newKey;
2192      }
2193      // rows are different
2194      short minLength = leftRowLength < rightRowLength ? leftRowLength : rightRowLength;
2195      short diffIdx = 0;
2196      while (diffIdx < minLength
2197          && leftKey[ROW_LENGTH_SIZE + diffIdx] == rightKey[ROW_LENGTH_SIZE + diffIdx]) {
2198        diffIdx++;
2199      }
2200      byte[] newRowKey = null;
2201      if (diffIdx >= minLength) {
2202        // leftKey's row is prefix of rightKey's.
2203        newRowKey = new byte[diffIdx + 1];
2204        System.arraycopy(rightKey, ROW_LENGTH_SIZE, newRowKey, 0, diffIdx + 1);
2205      } else {
2206        int diffByte = leftKey[ROW_LENGTH_SIZE + diffIdx];
2207        if ((0xff & diffByte) < 0xff && (diffByte + 1) <
2208            (rightKey[ROW_LENGTH_SIZE + diffIdx] & 0xff)) {
2209          newRowKey = new byte[diffIdx + 1];
2210          System.arraycopy(leftKey, ROW_LENGTH_SIZE, newRowKey, 0, diffIdx);
2211          newRowKey[diffIdx] = (byte) (diffByte + 1);
2212        } else {
2213          newRowKey = new byte[diffIdx + 1];
2214          System.arraycopy(rightKey, ROW_LENGTH_SIZE, newRowKey, 0, diffIdx + 1);
2215        }
2216      }
2217      return new KeyValue(newRowKey, null, null, HConstants.LATEST_TIMESTAMP,
2218        Type.Maximum).getKey();
2219    }
2220
2221    @Override
2222    protected Object clone() throws CloneNotSupportedException {
2223      super.clone();
2224      return new KVComparator();
2225    }
2226
2227  }
2228
2229  /**
2230   * @param in Where to read bytes from.  Creates a byte array to hold the KeyValue
2231   * backing bytes copied from the steam.
2232   * @return KeyValue created by deserializing from <code>in</code> OR if we find a length
2233   * of zero, we will return null which can be useful marking a stream as done.
2234   * @throws IOException
2235   */
2236  public static KeyValue create(final DataInput in) throws IOException {
2237    return create(in.readInt(), in);
2238  }
2239
2240  /**
2241   * Create a KeyValue reading <code>length</code> from <code>in</code>
2242   * @param length
2243   * @param in
2244   * @return Created KeyValue OR if we find a length of zero, we will return null which
2245   * can be useful marking a stream as done.
2246   * @throws IOException
2247   */
2248  public static KeyValue create(int length, final DataInput in) throws IOException {
2249
2250    if (length <= 0) {
2251      if (length == 0) return null;
2252      throw new IOException("Failed read " + length + " bytes, stream corrupt?");
2253    }
2254
2255    // This is how the old Writables.readFrom used to deserialize.  Didn't even vint.
2256    byte [] bytes = new byte[length];
2257    in.readFully(bytes);
2258    return new KeyValue(bytes, 0, length);
2259  }
2260
2261  /**
2262   * Write out a KeyValue in the manner in which we used to when KeyValue was a Writable.
2263   * @param kv
2264   * @param out
2265   * @return Length written on stream
2266   * @throws IOException
2267   * @see #create(DataInput) for the inverse function
2268   */
2269  public static long write(final KeyValue kv, final DataOutput out) throws IOException {
2270    // This is how the old Writables write used to serialize KVs.  Need to figure way to make it
2271    // work for all implementations.
2272    int length = kv.getLength();
2273    out.writeInt(length);
2274    out.write(kv.getBuffer(), kv.getOffset(), length);
2275    return (long) length + Bytes.SIZEOF_INT;
2276  }
2277
2278  /**
2279   * Write out a KeyValue in the manner in which we used to when KeyValue was a Writable but do
2280   * not require a {@link DataOutput}, just take plain {@link OutputStream}
2281   * Named <code>oswrite</code> so does not clash with {@link #write(KeyValue, DataOutput)}
2282   * @param kv
2283   * @param out
2284   * @param withTags
2285   * @return Length written on stream
2286   * @throws IOException
2287   * @see #create(DataInput) for the inverse function
2288   * @see #write(KeyValue, DataOutput)
2289   * @see KeyValueUtil#oswrite(Cell, OutputStream, boolean)
2290   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
2291   *             Instead use {@link #write(OutputStream, boolean)}
2292   */
2293  @Deprecated
2294  public static long oswrite(final KeyValue kv, final OutputStream out, final boolean withTags)
2295      throws IOException {
2296    ByteBufferUtils.putInt(out, kv.getSerializedSize(withTags));
2297    return (long) kv.write(out, withTags) + Bytes.SIZEOF_INT;
2298  }
2299
2300  @Override
2301  public int write(OutputStream out, boolean withTags) throws IOException {
2302    int len = getSerializedSize(withTags);
2303    out.write(this.bytes, this.offset, len);
2304    return len;
2305  }
2306
2307  @Override
2308  public int getSerializedSize(boolean withTags) {
2309    if (withTags) {
2310      return this.length;
2311    }
2312    return this.getKeyLength() + this.getValueLength() + KEYVALUE_INFRASTRUCTURE_SIZE;
2313  }
2314
2315  @Override
2316  public void write(ByteBuffer buf, int offset) {
2317    ByteBufferUtils.copyFromArrayToBuffer(buf, offset, this.bytes, this.offset, this.length);
2318  }
2319
2320  /**
2321   * Avoids redundant comparisons for better performance.
2322   *
2323   * TODO get rid of this wart
2324   */
2325  public interface SamePrefixComparator<T> {
2326    /**
2327     * Compare two keys assuming that the first n bytes are the same.
2328     * @param commonPrefix How many bytes are the same.
2329     */
2330    int compareIgnoringPrefix(int commonPrefix, byte[] left, int loffset, int llength,
2331        byte[] right, int roffset, int rlength
2332    );
2333  }
2334
2335  /**
2336   * HeapSize implementation
2337   *
2338   * We do not count the bytes in the rowCache because it should be empty for a KeyValue in the
2339   * MemStore.
2340   */
2341  @Override
2342  public long heapSize() {
2343    /*
2344     * Deep object overhead for this KV consists of two parts. The first part is the KV object
2345     * itself, while the second part is the backing byte[]. We will only count the array overhead
2346     * from the byte[] only if this is the first KV in there.
2347     */
2348    return ClassSize.align(FIXED_OVERHEAD) +
2349        (offset == 0
2350          ? ClassSize.sizeOfByteArray(length)  // count both length and object overhead
2351          : length);                           // only count the number of bytes
2352  }
2353
2354  /**
2355   * A simple form of KeyValue that creates a keyvalue with only the key part of the byte[]
2356   * Mainly used in places where we need to compare two cells.  Avoids copying of bytes
2357   * In places like block index keys, we need to compare the key byte[] with a cell.
2358   * Hence create a Keyvalue(aka Cell) that would help in comparing as two cells
2359   */
2360  public static class KeyOnlyKeyValue extends KeyValue {
2361    private short rowLen = -1;
2362    public KeyOnlyKeyValue() {
2363
2364    }
2365    public KeyOnlyKeyValue(byte[] b) {
2366      this(b, 0, b.length);
2367    }
2368
2369    public KeyOnlyKeyValue(byte[] b, int offset, int length) {
2370      this.bytes = b;
2371      this.length = length;
2372      this.offset = offset;
2373      this.rowLen = Bytes.toShort(this.bytes, this.offset);
2374    }
2375
2376    public void set(KeyOnlyKeyValue keyOnlyKeyValue) {
2377      this.bytes = keyOnlyKeyValue.bytes;
2378      this.length = keyOnlyKeyValue.length;
2379      this.offset = keyOnlyKeyValue.offset;
2380      this.rowLen = keyOnlyKeyValue.rowLen;
2381    }
2382
2383    public void clear() {
2384      rowLen = -1;
2385      bytes = null;
2386      offset = 0;
2387      length = 0;
2388    }
2389
2390    @Override
2391    public int getKeyOffset() {
2392      return this.offset;
2393    }
2394
2395    /**
2396     * A setter that helps to avoid object creation every time and whenever
2397     * there is a need to create new KeyOnlyKeyValue.
2398     * @param key
2399     * @param offset
2400     * @param length
2401     */
2402    public void setKey(byte[] key, int offset, int length) {
2403      this.bytes = key;
2404      this.offset = offset;
2405      this.length = length;
2406      this.rowLen = Bytes.toShort(this.bytes, this.offset);
2407    }
2408
2409    @Override
2410    public byte[] getKey() {
2411      int keylength = getKeyLength();
2412      byte[] key = new byte[keylength];
2413      System.arraycopy(this.bytes, getKeyOffset(), key, 0, keylength);
2414      return key;
2415    }
2416
2417    @Override
2418    public byte[] getRowArray() {
2419      return bytes;
2420    }
2421
2422    @Override
2423    public int getRowOffset() {
2424      return getKeyOffset() + Bytes.SIZEOF_SHORT;
2425    }
2426
2427    @Override
2428    public byte[] getFamilyArray() {
2429      return bytes;
2430    }
2431
2432    @Override
2433    public byte getFamilyLength() {
2434      return this.bytes[getFamilyOffset() - 1];
2435    }
2436
2437    @Override
2438    public int getFamilyOffset() {
2439      return this.offset + Bytes.SIZEOF_SHORT + getRowLength() + Bytes.SIZEOF_BYTE;
2440    }
2441
2442    @Override
2443    public byte[] getQualifierArray() {
2444      return bytes;
2445    }
2446
2447    @Override
2448    public int getQualifierLength() {
2449      return getQualifierLength(getRowLength(), getFamilyLength());
2450    }
2451
2452    @Override
2453    public int getQualifierOffset() {
2454      return getFamilyOffset() + getFamilyLength();
2455    }
2456
2457    @Override
2458    public int getKeyLength() {
2459      return length;
2460    }
2461
2462    @Override
2463    public short getRowLength() {
2464      return rowLen;
2465    }
2466
2467    @Override
2468    public byte getTypeByte() {
2469      return this.bytes[this.offset + getKeyLength() - 1];
2470    }
2471
2472    private int getQualifierLength(int rlength, int flength) {
2473      return getKeyLength() - (int) getKeyDataStructureSize(rlength, flength, 0);
2474    }
2475
2476    @Override
2477    public long getTimestamp() {
2478      int tsOffset = getTimestampOffset();
2479      return Bytes.toLong(this.bytes, tsOffset);
2480    }
2481
2482    @Override
2483    public int getTimestampOffset() {
2484      return getKeyOffset() + getKeyLength() - TIMESTAMP_TYPE_SIZE;
2485    }
2486
2487    @Override
2488    public byte[] getTagsArray() {
2489      return HConstants.EMPTY_BYTE_ARRAY;
2490    }
2491
2492    @Override
2493    public int getTagsOffset() {
2494      return 0;
2495    }
2496
2497    @Override
2498    public byte[] getValueArray() {
2499      throw new IllegalArgumentException("KeyOnlyKeyValue does not work with values.");
2500    }
2501
2502    @Override
2503    public int getValueOffset() {
2504      throw new IllegalArgumentException("KeyOnlyKeyValue does not work with values.");
2505    }
2506
2507    @Override
2508    public int getValueLength() {
2509      throw new IllegalArgumentException("KeyOnlyKeyValue does not work with values.");
2510    }
2511
2512    @Override
2513    public int getTagsLength() {
2514      return 0;
2515    }
2516
2517    @Override
2518    public String toString() {
2519      if (this.bytes == null || this.bytes.length == 0) {
2520        return "empty";
2521      }
2522      return keyToString(this.bytes, this.offset, getKeyLength()) + "/vlen=0/mvcc=0";
2523    }
2524
2525    @Override
2526    public int hashCode() {
2527      return super.hashCode();
2528    }
2529
2530    @Override
2531    public boolean equals(Object other) {
2532      return super.equals(other);
2533    }
2534
2535    @Override
2536    public long heapSize() {
2537      return super.heapSize() + Bytes.SIZEOF_SHORT;
2538    }
2539
2540    @Override
2541    public int write(OutputStream out, boolean withTags) throws IOException {
2542      // This type of Cell is used only to maintain some internal states. We never allow this type
2543      // of Cell to be returned back over the RPC
2544      throw new IllegalStateException("A reader should never return this type of a Cell");
2545    }
2546  }
2547
2548  @Override
2549  public ExtendedCell deepClone() {
2550    byte[] copy = Bytes.copy(this.bytes, this.offset, this.length);
2551    KeyValue kv = new KeyValue(copy, 0, copy.length);
2552    kv.setSequenceId(this.getSequenceId());
2553    return kv;
2554  }
2555}