001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase;
019
020import static org.apache.hadoop.hbase.util.Bytes.len;
021
022import java.io.DataInput;
023import java.io.DataOutput;
024import java.io.IOException;
025import java.io.OutputStream;
026import java.nio.ByteBuffer;
027import java.util.ArrayList;
028import java.util.Arrays;
029import java.util.HashMap;
030import java.util.Iterator;
031import java.util.List;
032import java.util.Map;
033import org.apache.hadoop.hbase.util.ByteBufferUtils;
034import org.apache.hadoop.hbase.util.Bytes;
035import org.apache.hadoop.hbase.util.ClassSize;
036import org.apache.yetus.audience.InterfaceAudience;
037import org.slf4j.Logger;
038import org.slf4j.LoggerFactory;
039
040/**
041 * An HBase Key/Value. This is the fundamental HBase Type.
042 * <p>
043 * HBase applications and users should use the Cell interface and avoid directly using KeyValue and
044 * member functions not defined in Cell.
045 * <p>
046 * If being used client-side, the primary methods to access individual fields are
047 * {@link #getRowArray()}, {@link #getFamilyArray()}, {@link #getQualifierArray()},
048 * {@link #getTimestamp()}, and {@link #getValueArray()}. These methods allocate new byte arrays and
049 * return copies. Avoid their use server-side.
050 * <p>
051 * Instances of this class are immutable. They do not implement Comparable but Comparators are
052 * provided. Comparators change with context, whether user table or a catalog table comparison. Its
053 * critical you use the appropriate comparator. There are Comparators for normal HFiles, Meta's
054 * Hfiles, and bloom filter keys.
055 * <p>
056 * KeyValue wraps a byte array and takes offsets and lengths into passed array at where to start
057 * interpreting the content as KeyValue. The KeyValue format inside a byte array is:
058 * <code>&lt;keylength&gt; &lt;valuelength&gt; &lt;key&gt; &lt;value&gt;</code> Key is further
059 * decomposed as: <code>&lt;rowlength&gt; &lt;row&gt; &lt;columnfamilylength&gt;
060 * &lt;columnfamily&gt; &lt;columnqualifier&gt;
061 * &lt;timestamp&gt; &lt;keytype&gt;</code> The <code>rowlength</code> maximum is
062 * <code>Short.MAX_SIZE</code>, column family length maximum is <code>Byte.MAX_SIZE</code>, and
063 * column qualifier + key length must be &lt; <code>Integer.MAX_SIZE</code>. The column does not
064 * contain the family/qualifier delimiter, {@link #COLUMN_FAMILY_DELIMITER}<br>
065 * KeyValue can optionally contain Tags. When it contains tags, it is added in the byte array after
066 * the value part. The format for this part is: <code>&lt;tagslength&gt;&lt;tagsbytes&gt;</code>.
067 * <code>tagslength</code> maximum is <code>Short.MAX_SIZE</code>. The <code>tagsbytes</code>
068 * contain one or more tags where as each tag is of the form
069 * <code>&lt;taglength&gt;&lt;tagtype&gt;&lt;tagbytes&gt;</code>. <code>tagtype</code> is one byte
070 * and <code>taglength</code> maximum is <code>Short.MAX_SIZE</code> and it includes 1 byte type
071 * length and actual tag bytes length.
072 */
073@InterfaceAudience.Private
074public class KeyValue implements ExtendedCell, Cloneable {
075  private static final Logger LOG = LoggerFactory.getLogger(KeyValue.class);
076
077  public static final int FIXED_OVERHEAD = ClassSize.OBJECT + // the KeyValue object itself
078    ClassSize.REFERENCE + // pointer to "bytes"
079    2 * Bytes.SIZEOF_INT + // offset, length
080    Bytes.SIZEOF_LONG;// memstoreTS
081
082  /**
083   * Colon character in UTF-8
084   */
085  public static final char COLUMN_FAMILY_DELIMITER = ':';
086
087  public static final byte[] COLUMN_FAMILY_DELIM_ARRAY = new byte[] { COLUMN_FAMILY_DELIMITER };
088
089  /** Size of the key length field in bytes */
090  public static final int KEY_LENGTH_SIZE = Bytes.SIZEOF_INT;
091
092  /** Size of the key type field in bytes */
093  public static final int TYPE_SIZE = Bytes.SIZEOF_BYTE;
094
095  /** Size of the row length field in bytes */
096  public static final int ROW_LENGTH_SIZE = Bytes.SIZEOF_SHORT;
097
098  /** Size of the family length field in bytes */
099  public static final int FAMILY_LENGTH_SIZE = Bytes.SIZEOF_BYTE;
100
101  /** Size of the timestamp field in bytes */
102  public static final int TIMESTAMP_SIZE = Bytes.SIZEOF_LONG;
103
104  // Size of the timestamp and type byte on end of a key -- a long + a byte.
105  public static final int TIMESTAMP_TYPE_SIZE = TIMESTAMP_SIZE + TYPE_SIZE;
106
107  // Size of the length shorts and bytes in key.
108  public static final int KEY_INFRASTRUCTURE_SIZE =
109    ROW_LENGTH_SIZE + FAMILY_LENGTH_SIZE + TIMESTAMP_TYPE_SIZE;
110
111  // How far into the key the row starts at. First thing to read is the short
112  // that says how long the row is.
113  public static final int ROW_OFFSET =
114    Bytes.SIZEOF_INT /* keylength */ + Bytes.SIZEOF_INT /* valuelength */;
115
116  public static final int ROW_KEY_OFFSET = ROW_OFFSET + ROW_LENGTH_SIZE;
117
118  // Size of the length ints in a KeyValue datastructure.
119  public static final int KEYVALUE_INFRASTRUCTURE_SIZE = ROW_OFFSET;
120
121  /** Size of the tags length field in bytes */
122  public static final int TAGS_LENGTH_SIZE = Bytes.SIZEOF_SHORT;
123
124  public static final int KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE = ROW_OFFSET + TAGS_LENGTH_SIZE;
125
126  /**
127   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided
128   * characteristics would take up for its underlying data structure.
129   * @param rlength row length
130   * @param flength family length
131   * @param qlength qualifier length
132   * @param vlength value length
133   * @return the <code>KeyValue</code> data structure length
134   */
135  public static long getKeyValueDataStructureSize(int rlength, int flength, int qlength,
136    int vlength) {
137    return KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE
138      + getKeyDataStructureSize(rlength, flength, qlength) + vlength;
139  }
140
141  /**
142   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided
143   * characteristics would take up for its underlying data structure.
144   * @param rlength    row length
145   * @param flength    family length
146   * @param qlength    qualifier length
147   * @param vlength    value length
148   * @param tagsLength total length of the tags
149   * @return the <code>KeyValue</code> data structure length
150   */
151  public static long getKeyValueDataStructureSize(int rlength, int flength, int qlength,
152    int vlength, int tagsLength) {
153    if (tagsLength == 0) {
154      return getKeyValueDataStructureSize(rlength, flength, qlength, vlength);
155    }
156    return KeyValue.KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE
157      + getKeyDataStructureSize(rlength, flength, qlength) + vlength + tagsLength;
158  }
159
160  /**
161   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided
162   * characteristics would take up for its underlying data structure.
163   * @param klength    key length
164   * @param vlength    value length
165   * @param tagsLength total length of the tags
166   * @return the <code>KeyValue</code> data structure length
167   */
168  public static long getKeyValueDataStructureSize(int klength, int vlength, int tagsLength) {
169    if (tagsLength == 0) {
170      return (long) KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE + klength + vlength;
171    }
172    return (long) KeyValue.KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE + klength + vlength + tagsLength;
173  }
174
175  /**
176   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided
177   * characteristics would take up in its underlying data structure for the key.
178   * @param rlength row length
179   * @param flength family length
180   * @param qlength qualifier length
181   * @return the key data structure length
182   */
183  public static long getKeyDataStructureSize(int rlength, int flength, int qlength) {
184    return (long) KeyValue.KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
185  }
186
187  /**
188   * Key type. Has space for other key types to be added later. Cannot rely on enum ordinals . They
189   * change if item is removed or moved. Do our own codes.
190   */
191  public static enum Type {
192    Minimum((byte) 0),
193    Put((byte) 4),
194
195    Delete((byte) 8),
196    DeleteFamilyVersion((byte) 10),
197    DeleteColumn((byte) 12),
198    DeleteFamily((byte) 14),
199
200    // Maximum is used when searching; you look from maximum on down.
201    Maximum((byte) 255);
202
203    private final byte code;
204
205    Type(final byte c) {
206      this.code = c;
207    }
208
209    public byte getCode() {
210      return this.code;
211    }
212
213    private static Type[] codeArray = new Type[256];
214
215    static {
216      for (Type t : Type.values()) {
217        codeArray[t.code & 0xff] = t;
218      }
219    }
220
221    /**
222     * True to indicate that the byte b is a valid type.
223     * @param b byte to check
224     * @return true or false
225     */
226    static boolean isValidType(byte b) {
227      return codeArray[b & 0xff] != null;
228    }
229
230    /**
231     * Cannot rely on enum ordinals . They change if item is removed or moved. Do our own codes.
232     * @param b the kv serialized byte[] to process
233     * @return Type associated with passed code.
234     */
235    public static Type codeToType(final byte b) {
236      Type t = codeArray[b & 0xff];
237      if (t != null) {
238        return t;
239      }
240      throw new RuntimeException("Unknown code " + b);
241    }
242  }
243
244  /**
245   * Lowest possible key. Makes a Key with highest possible Timestamp, empty row and column. No key
246   * can be equal or lower than this one in memstore or in store file.
247   */
248  public static final KeyValue LOWESTKEY =
249    new KeyValue(HConstants.EMPTY_BYTE_ARRAY, HConstants.LATEST_TIMESTAMP);
250
251  ////
252  // KeyValue core instance fields.
253  protected byte[] bytes = null; // an immutable byte array that contains the KV
254  protected int offset = 0; // offset into bytes buffer KV starts at
255  protected int length = 0; // length of the KV starting from offset.
256
257  /** Here be dragons **/
258
259  /**
260   * used to achieve atomic operations in the memstore.
261   */
262  @Override
263  public long getSequenceId() {
264    return seqId;
265  }
266
267  @Override
268  public void setSequenceId(long seqId) {
269    this.seqId = seqId;
270  }
271
272  // multi-version concurrency control version. default value is 0, aka do not care.
273  private long seqId = 0;
274
275  /** Dragon time over, return to normal business */
276
277  /** Writable Constructor -- DO NOT USE */
278  public KeyValue() {
279  }
280
281  /**
282   * Creates a KeyValue from the start of the specified byte array. Presumes <code>bytes</code>
283   * content is formatted as a KeyValue blob.
284   * @param bytes byte array
285   */
286  public KeyValue(final byte[] bytes) {
287    this(bytes, 0);
288  }
289
290  /**
291   * Creates a KeyValue from the specified byte array and offset. Presumes <code>bytes</code>
292   * content starting at <code>offset</code> is formatted as a KeyValue blob.
293   * @param bytes  byte array
294   * @param offset offset to start of KeyValue
295   */
296  public KeyValue(final byte[] bytes, final int offset) {
297    this(bytes, offset, getLength(bytes, offset));
298  }
299
300  /**
301   * Creates a KeyValue from the specified byte array, starting at offset, and for length
302   * <code>length</code>.
303   * @param bytes  byte array
304   * @param offset offset to start of the KeyValue
305   * @param length length of the KeyValue
306   */
307  public KeyValue(final byte[] bytes, final int offset, final int length) {
308    KeyValueUtil.checkKeyValueBytes(bytes, offset, length, true);
309    this.bytes = bytes;
310    this.offset = offset;
311    this.length = length;
312  }
313
314  /**
315   * Creates a KeyValue from the specified byte array, starting at offset, and for length
316   * <code>length</code>.
317   * @param bytes  byte array
318   * @param offset offset to start of the KeyValue
319   * @param length length of the KeyValue
320   * @param ts     timestamp
321   */
322  public KeyValue(final byte[] bytes, final int offset, final int length, long ts) {
323    this(bytes, offset, length, null, 0, 0, null, 0, 0, ts, Type.Maximum, null, 0, 0, null);
324  }
325
326  /** Constructors that build a new backing byte array from fields */
327
328  /**
329   * Constructs KeyValue structure filled with null value. Sets type to
330   * {@link KeyValue.Type#Maximum}
331   * @param row       - row key (arbitrary byte array)
332   * @param timestamp version timestamp
333   */
334  public KeyValue(final byte[] row, final long timestamp) {
335    this(row, null, null, timestamp, Type.Maximum, null);
336  }
337
338  /**
339   * Constructs KeyValue structure filled with null value.
340   * @param row       - row key (arbitrary byte array)
341   * @param timestamp version timestamp
342   */
343  public KeyValue(final byte[] row, final long timestamp, Type type) {
344    this(row, null, null, timestamp, type, null);
345  }
346
347  /**
348   * Constructs KeyValue structure filled with null value. Sets type to
349   * {@link KeyValue.Type#Maximum}
350   * @param row       - row key (arbitrary byte array)
351   * @param family    family name
352   * @param qualifier column qualifier
353   */
354  public KeyValue(final byte[] row, final byte[] family, final byte[] qualifier) {
355    this(row, family, qualifier, HConstants.LATEST_TIMESTAMP, Type.Maximum);
356  }
357
358  /**
359   * Constructs KeyValue structure as a put filled with specified values and LATEST_TIMESTAMP.
360   * @param row       - row key (arbitrary byte array)
361   * @param family    family name
362   * @param qualifier column qualifier
363   */
364  public KeyValue(final byte[] row, final byte[] family, final byte[] qualifier,
365    final byte[] value) {
366    this(row, family, qualifier, HConstants.LATEST_TIMESTAMP, Type.Put, value);
367  }
368
369  /**
370   * Constructs KeyValue structure filled with specified values.
371   * @param row       row key
372   * @param family    family name
373   * @param qualifier column qualifier
374   * @param timestamp version timestamp
375   * @param type      key type
376   * @throws IllegalArgumentException an illegal value was passed
377   */
378  public KeyValue(final byte[] row, final byte[] family, final byte[] qualifier,
379    final long timestamp, Type type) {
380    this(row, family, qualifier, timestamp, type, null);
381  }
382
383  /**
384   * Constructs KeyValue structure filled with specified values.
385   * @param row       row key
386   * @param family    family name
387   * @param qualifier column qualifier
388   * @param timestamp version timestamp
389   * @param value     column value
390   * @throws IllegalArgumentException an illegal value was passed
391   */
392  public KeyValue(final byte[] row, final byte[] family, final byte[] qualifier,
393    final long timestamp, final byte[] value) {
394    this(row, family, qualifier, timestamp, Type.Put, value);
395  }
396
397  /**
398   * Constructs KeyValue structure filled with specified values.
399   * @param row       row key
400   * @param family    family name
401   * @param qualifier column qualifier
402   * @param timestamp version timestamp
403   * @param value     column value
404   * @param tags      tags
405   * @throws IllegalArgumentException an illegal value was passed
406   */
407  public KeyValue(final byte[] row, final byte[] family, final byte[] qualifier,
408    final long timestamp, final byte[] value, final Tag[] tags) {
409    this(row, family, qualifier, timestamp, value, tags != null ? Arrays.asList(tags) : 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   * @param tags      tags non-empty list of tags or null
420   * @throws IllegalArgumentException an illegal value was passed
421   */
422  public KeyValue(final byte[] row, final byte[] family, final byte[] qualifier,
423    final long timestamp, final byte[] value, final List<Tag> tags) {
424    this(row, 0, row == null ? 0 : row.length, family, 0, family == null ? 0 : family.length,
425      qualifier, 0, qualifier == null ? 0 : qualifier.length, timestamp, Type.Put, value, 0,
426      value == null ? 0 : value.length, tags);
427  }
428
429  /**
430   * Constructs KeyValue structure filled with specified values.
431   * @param row       row key
432   * @param family    family name
433   * @param qualifier column qualifier
434   * @param timestamp version timestamp
435   * @param type      key type
436   * @param value     column value
437   * @throws IllegalArgumentException an illegal value was passed
438   */
439  public KeyValue(final byte[] row, final byte[] family, final byte[] qualifier,
440    final long timestamp, Type type, final byte[] value) {
441    this(row, 0, len(row), family, 0, len(family), qualifier, 0, len(qualifier), timestamp, type,
442      value, 0, len(value));
443  }
444
445  /**
446   * Constructs KeyValue structure filled with specified values.
447   * <p>
448   * Column is split into two fields, family and qualifier.
449   * @param row       row key
450   * @param family    family name
451   * @param qualifier column qualifier
452   * @param timestamp version timestamp
453   * @param type      key type
454   * @param value     column value
455   * @throws IllegalArgumentException an illegal value was passed
456   */
457  public KeyValue(final byte[] row, final byte[] family, final byte[] qualifier,
458    final long timestamp, Type type, final byte[] value, final List<Tag> tags) {
459    this(row, family, qualifier, 0, qualifier == null ? 0 : qualifier.length, timestamp, type,
460      value, 0, value == null ? 0 : value.length, tags);
461  }
462
463  /**
464   * Constructs KeyValue structure filled with specified values.
465   * @param row       row key
466   * @param family    family name
467   * @param qualifier column qualifier
468   * @param timestamp version timestamp
469   * @param type      key type
470   * @param value     column value
471   * @throws IllegalArgumentException an illegal value was passed
472   */
473  public KeyValue(final byte[] row, final byte[] family, final byte[] qualifier,
474    final long timestamp, Type type, final byte[] value, final byte[] tags) {
475    this(row, family, qualifier, 0, qualifier == null ? 0 : qualifier.length, timestamp, type,
476      value, 0, value == null ? 0 : value.length, tags);
477  }
478
479  /**
480   * Constructs KeyValue structure filled with specified values.
481   * @param row       row key
482   * @param family    family name
483   * @param qualifier column qualifier
484   * @param qoffset   qualifier offset
485   * @param qlength   qualifier length
486   * @param timestamp version timestamp
487   * @param type      key type
488   * @param value     column value
489   * @param voffset   value offset
490   * @param vlength   value length
491   * @throws IllegalArgumentException an illegal value was passed
492   */
493  public KeyValue(byte[] row, byte[] family, byte[] qualifier, int qoffset, int qlength,
494    long timestamp, Type type, byte[] value, int voffset, int vlength, List<Tag> tags) {
495    this(row, 0, row == null ? 0 : row.length, family, 0, family == null ? 0 : family.length,
496      qualifier, qoffset, qlength, timestamp, type, value, voffset, vlength, tags);
497  }
498
499  /**
500   * @param row       row key
501   * @param family    family name
502   * @param qualifier qualifier name
503   * @param qoffset   qualifier offset
504   * @param qlength   qualifier length
505   * @param timestamp version timestamp
506   * @param type      key type
507   * @param value     column value
508   * @param voffset   value offset
509   * @param vlength   value length
510   * @param tags      tags
511   */
512  public KeyValue(byte[] row, byte[] family, byte[] qualifier, int qoffset, int qlength,
513    long timestamp, Type type, byte[] value, int voffset, int vlength, byte[] tags) {
514    this(row, 0, row == null ? 0 : row.length, family, 0, family == null ? 0 : family.length,
515      qualifier, qoffset, qlength, timestamp, type, value, voffset, vlength, tags, 0,
516      tags == null ? 0 : tags.length);
517  }
518
519  /**
520   * Constructs KeyValue structure filled with specified values.
521   * <p>
522   * Column is split into two fields, family and qualifier.
523   * @param row row key
524   * @throws IllegalArgumentException an illegal value was passed
525   */
526  public KeyValue(final byte[] row, final int roffset, final int rlength, final byte[] family,
527    final int foffset, final int flength, final byte[] qualifier, final int qoffset,
528    final int qlength, final long timestamp, final Type type, final byte[] value, final int voffset,
529    final int vlength) {
530    this(row, roffset, rlength, family, foffset, flength, qualifier, qoffset, qlength, timestamp,
531      type, value, voffset, vlength, null);
532  }
533
534  /**
535   * Constructs KeyValue structure filled with specified values. Uses the provided buffer as the
536   * data buffer.
537   * <p>
538   * Column is split into two fields, family and qualifier.
539   * @param buffer    the bytes buffer to use
540   * @param boffset   buffer offset
541   * @param row       row key
542   * @param roffset   row offset
543   * @param rlength   row length
544   * @param family    family name
545   * @param foffset   family offset
546   * @param flength   family length
547   * @param qualifier column qualifier
548   * @param qoffset   qualifier offset
549   * @param qlength   qualifier length
550   * @param timestamp version timestamp
551   * @param type      key type
552   * @param value     column value
553   * @param voffset   value offset
554   * @param vlength   value length
555   * @param tags      non-empty list of tags or null
556   * @throws IllegalArgumentException an illegal value was passed or there is insufficient space
557   *                                  remaining in the buffer
558   */
559  public KeyValue(byte[] buffer, final int boffset, final byte[] row, final int roffset,
560    final int rlength, final byte[] family, final int foffset, final int flength,
561    final byte[] qualifier, final int qoffset, final int qlength, final long timestamp,
562    final Type type, final byte[] value, final int voffset, final int vlength, final Tag[] tags) {
563    this.bytes = buffer;
564    this.length = writeByteArray(buffer, boffset, row, roffset, rlength, family, foffset, flength,
565      qualifier, qoffset, qlength, timestamp, type, value, voffset, vlength, tags);
566    this.offset = boffset;
567  }
568
569  /**
570   * Constructs KeyValue structure filled with specified values.
571   * <p>
572   * Column is split into two fields, family and qualifier.
573   * @param row       row key
574   * @param roffset   row offset
575   * @param rlength   row length
576   * @param family    family name
577   * @param foffset   family offset
578   * @param flength   family length
579   * @param qualifier column qualifier
580   * @param qoffset   qualifier offset
581   * @param qlength   qualifier length
582   * @param timestamp version timestamp
583   * @param type      key type
584   * @param value     column value
585   * @param voffset   value offset
586   * @param vlength   value length
587   * @param tags      tags
588   * @throws IllegalArgumentException an illegal value was passed
589   */
590  public KeyValue(final byte[] row, final int roffset, final int rlength, final byte[] family,
591    final int foffset, final int flength, final byte[] qualifier, final int qoffset,
592    final int qlength, final long timestamp, final Type type, final byte[] value, final int voffset,
593    final int vlength, final List<Tag> tags) {
594    this.bytes = createByteArray(row, roffset, rlength, family, foffset, flength, qualifier,
595      qoffset, qlength, timestamp, type, value, voffset, vlength, tags);
596    this.length = bytes.length;
597    this.offset = 0;
598  }
599
600  /**
601   * @param row       row key
602   * @param roffset   row offset
603   * @param rlength   row length
604   * @param family    family name
605   * @param foffset   fammily offset
606   * @param flength   family length
607   * @param qualifier column qualifier
608   * @param qoffset   qualifier offset
609   * @param qlength   qualifier length
610   * @param timestamp version timestamp
611   * @param type      key type
612   * @param value     column value
613   * @param voffset   value offset
614   * @param vlength   value length
615   * @param tags      input tags
616   */
617  public KeyValue(final byte[] row, final int roffset, final int rlength, final byte[] family,
618    final int foffset, final int flength, final byte[] qualifier, final int qoffset,
619    final int qlength, final long timestamp, final Type type, final byte[] value, final int voffset,
620    final int vlength, final byte[] tags, final int tagsOffset, final int tagsLength) {
621    this.bytes = createByteArray(row, roffset, rlength, family, foffset, flength, qualifier,
622      qoffset, qlength, timestamp, type, value, voffset, vlength, tags, tagsOffset, tagsLength);
623    this.length = bytes.length;
624    this.offset = 0;
625  }
626
627  /**
628   * Constructs an empty KeyValue structure, with specified sizes. This can be used to partially
629   * fill up KeyValues.
630   * <p>
631   * Column is split into two fields, family and qualifier.
632   * @param rlength   row length
633   * @param flength   family length
634   * @param qlength   qualifier length
635   * @param timestamp version timestamp
636   * @param type      key type
637   * @param vlength   value length
638   * @throws IllegalArgumentException an illegal value was passed
639   */
640  public KeyValue(final int rlength, final int flength, final int qlength, final long timestamp,
641    final Type type, final int vlength) {
642    this(rlength, flength, qlength, timestamp, type, vlength, 0);
643  }
644
645  /**
646   * Constructs an empty KeyValue structure, with specified sizes. This can be used to partially
647   * fill up KeyValues.
648   * <p>
649   * Column is split into two fields, family and qualifier.
650   * @param rlength    row length
651   * @param flength    family length
652   * @param qlength    qualifier length
653   * @param timestamp  version timestamp
654   * @param type       key type
655   * @param vlength    value length
656   * @param tagsLength length of the tags
657   * @throws IllegalArgumentException an illegal value was passed
658   */
659  public KeyValue(final int rlength, final int flength, final int qlength, final long timestamp,
660    final Type type, final int vlength, final int tagsLength) {
661    this.bytes =
662      createEmptyByteArray(rlength, flength, qlength, timestamp, type, vlength, tagsLength);
663    this.length = bytes.length;
664    this.offset = 0;
665  }
666
667  public KeyValue(byte[] row, int roffset, int rlength, byte[] family, int foffset, int flength,
668    ByteBuffer qualifier, long ts, Type type, ByteBuffer value, List<Tag> tags) {
669    this.bytes = createByteArray(row, roffset, rlength, family, foffset, flength, qualifier, 0,
670      qualifier == null ? 0 : qualifier.remaining(), ts, type, value, 0,
671      value == null ? 0 : value.remaining(), tags);
672    this.length = bytes.length;
673    this.offset = 0;
674  }
675
676  public KeyValue(ExtendedCell c) {
677    this(c.getRowArray(), c.getRowOffset(), c.getRowLength(), c.getFamilyArray(),
678      c.getFamilyOffset(), c.getFamilyLength(), c.getQualifierArray(), c.getQualifierOffset(),
679      c.getQualifierLength(), c.getTimestamp(), Type.codeToType(c.getTypeByte()), c.getValueArray(),
680      c.getValueOffset(), c.getValueLength(), c.getTagsArray(), c.getTagsOffset(),
681      c.getTagsLength());
682    this.seqId = c.getSequenceId();
683  }
684
685  /**
686   * Create an empty byte[] representing a KeyValue All lengths are preset and can be filled in
687   * later.
688   * @param rlength   row length
689   * @param flength   family length
690   * @param qlength   qualifier length
691   * @param timestamp version timestamp
692   * @param type      key type
693   * @param vlength   value length
694   * @return The newly created byte array.
695   */
696  private static byte[] createEmptyByteArray(final int rlength, int flength, int qlength,
697    final long timestamp, final Type type, int vlength, int tagsLength) {
698    if (rlength > Short.MAX_VALUE) {
699      throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
700    }
701    if (flength > Byte.MAX_VALUE) {
702      throw new IllegalArgumentException("Family > " + Byte.MAX_VALUE);
703    }
704    // Qualifier length
705    if (qlength > Integer.MAX_VALUE - rlength - flength) {
706      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
707    }
708    RawCell.checkForTagsLength(tagsLength);
709    // Key length
710    long longkeylength = getKeyDataStructureSize(rlength, flength, qlength);
711    if (longkeylength > Integer.MAX_VALUE) {
712      throw new IllegalArgumentException("keylength " + longkeylength + " > " + Integer.MAX_VALUE);
713    }
714    int keylength = (int) longkeylength;
715    // Value length
716    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
717      throw new IllegalArgumentException("Valuer > " + HConstants.MAXIMUM_VALUE_LENGTH);
718    }
719
720    // Allocate right-sized byte array.
721    byte[] bytes =
722      new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength, tagsLength)];
723    // Write the correct size markers
724    int pos = 0;
725    pos = Bytes.putInt(bytes, pos, keylength);
726    pos = Bytes.putInt(bytes, pos, vlength);
727    pos = Bytes.putShort(bytes, pos, (short) (rlength & 0x0000ffff));
728    pos += rlength;
729    pos = Bytes.putByte(bytes, pos, (byte) (flength & 0x0000ff));
730    pos += flength + qlength;
731    pos = Bytes.putLong(bytes, pos, timestamp);
732    pos = Bytes.putByte(bytes, pos, type.getCode());
733    pos += vlength;
734    if (tagsLength > 0) {
735      pos = Bytes.putAsShort(bytes, pos, tagsLength);
736    }
737    return bytes;
738  }
739
740  /**
741   * Checks the parameters passed to a constructor.
742   * @param row     row key
743   * @param rlength row length
744   * @param family  family name
745   * @param flength family length
746   * @param qlength qualifier length
747   * @param vlength value length
748   * @throws IllegalArgumentException an illegal value was passed
749   */
750  static void checkParameters(final byte[] row, final int rlength, final byte[] family, int flength,
751    int qlength, int vlength) throws IllegalArgumentException {
752    if (rlength > Short.MAX_VALUE) {
753      throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
754    }
755    if (row == null) {
756      throw new IllegalArgumentException("Row is null");
757    }
758    // Family length
759    flength = family == null ? 0 : flength;
760    if (flength > Byte.MAX_VALUE) {
761      throw new IllegalArgumentException("Family > " + Byte.MAX_VALUE);
762    }
763    // Qualifier length
764    if (qlength > Integer.MAX_VALUE - rlength - flength) {
765      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
766    }
767    // Key length
768    long longKeyLength = getKeyDataStructureSize(rlength, flength, qlength);
769    if (longKeyLength > Integer.MAX_VALUE) {
770      throw new IllegalArgumentException("keylength " + longKeyLength + " > " + Integer.MAX_VALUE);
771    }
772    // Value length
773    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
774      throw new IllegalArgumentException(
775        "Value length " + vlength + " > " + HConstants.MAXIMUM_VALUE_LENGTH);
776    }
777  }
778
779  /**
780   * Write KeyValue format into the provided byte array.
781   * @param buffer    the bytes buffer to use
782   * @param boffset   buffer offset
783   * @param row       row key
784   * @param roffset   row offset
785   * @param rlength   row length
786   * @param family    family name
787   * @param foffset   family offset
788   * @param flength   family length
789   * @param qualifier column qualifier
790   * @param qoffset   qualifier offset
791   * @param qlength   qualifier length
792   * @param timestamp version timestamp
793   * @param type      key type
794   * @param value     column value
795   * @param voffset   value offset
796   * @param vlength   value length
797   * @return The number of useful bytes in the buffer.
798   * @throws IllegalArgumentException an illegal value was passed or there is insufficient space
799   *                                  remaining in the buffer
800   */
801  public static int writeByteArray(byte[] buffer, final int boffset, final byte[] row,
802    final int roffset, final int rlength, final byte[] family, final int foffset, int flength,
803    final byte[] qualifier, final int qoffset, int qlength, final long timestamp, final Type type,
804    final byte[] value, final int voffset, int vlength, Tag[] tags) {
805
806    checkParameters(row, rlength, family, flength, qlength, vlength);
807
808    // Calculate length of tags area
809    int tagsLength = 0;
810    if (tags != null && tags.length > 0) {
811      for (Tag t : tags) {
812        tagsLength += t.getValueLength() + Tag.INFRASTRUCTURE_SIZE;
813      }
814    }
815    RawCell.checkForTagsLength(tagsLength);
816    int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
817    int keyValueLength =
818      (int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength, tagsLength);
819    if (keyValueLength > buffer.length - boffset) {
820      throw new IllegalArgumentException(
821        "Buffer size " + (buffer.length - boffset) + " < " + keyValueLength);
822    }
823
824    // Write key, value and key row length.
825    int pos = boffset;
826    pos = Bytes.putInt(buffer, pos, keyLength);
827    pos = Bytes.putInt(buffer, pos, vlength);
828    pos = Bytes.putShort(buffer, pos, (short) (rlength & 0x0000ffff));
829    pos = Bytes.putBytes(buffer, pos, row, roffset, rlength);
830    pos = Bytes.putByte(buffer, pos, (byte) (flength & 0x0000ff));
831    if (flength != 0) {
832      pos = Bytes.putBytes(buffer, pos, family, foffset, flength);
833    }
834    if (qlength != 0) {
835      pos = Bytes.putBytes(buffer, pos, qualifier, qoffset, qlength);
836    }
837    pos = Bytes.putLong(buffer, pos, timestamp);
838    pos = Bytes.putByte(buffer, pos, type.getCode());
839    if (value != null && value.length > 0) {
840      pos = Bytes.putBytes(buffer, pos, value, voffset, vlength);
841    }
842    // Write the number of tags. If it is 0 then it means there are no tags.
843    if (tagsLength > 0) {
844      pos = Bytes.putAsShort(buffer, pos, tagsLength);
845      for (Tag t : tags) {
846        int tlen = t.getValueLength();
847        pos = Bytes.putAsShort(buffer, pos, tlen + Tag.TYPE_LENGTH_SIZE);
848        pos = Bytes.putByte(buffer, pos, t.getType());
849        Tag.copyValueTo(t, buffer, pos);
850        pos += tlen;
851      }
852    }
853    return keyValueLength;
854  }
855
856  /**
857   * Write KeyValue format into a byte array.
858   * @param row       row key
859   * @param roffset   row offset
860   * @param rlength   row length
861   * @param family    family name
862   * @param foffset   family offset
863   * @param flength   family length
864   * @param qualifier column qualifier
865   * @param qoffset   qualifier offset
866   * @param qlength   qualifier length
867   * @param timestamp version timestamp
868   * @param type      key type
869   * @param value     column value
870   * @param voffset   value offset
871   * @param vlength   value length
872   * @return The newly created byte array.
873   */
874  private static byte[] createByteArray(final byte[] row, final int roffset, final int rlength,
875    final byte[] family, final int foffset, int flength, final byte[] qualifier, final int qoffset,
876    int qlength, final long timestamp, final Type type, final byte[] value, final int voffset,
877    int vlength, byte[] tags, int tagsOffset, int tagsLength) {
878
879    checkParameters(row, rlength, family, flength, qlength, vlength);
880    RawCell.checkForTagsLength(tagsLength);
881    // Allocate right-sized byte array.
882    int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
883    byte[] bytes =
884      new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength, tagsLength)];
885    // Write key, value and key row length.
886    int pos = 0;
887    pos = Bytes.putInt(bytes, pos, keyLength);
888    pos = Bytes.putInt(bytes, pos, vlength);
889    pos = Bytes.putShort(bytes, pos, (short) (rlength & 0x0000ffff));
890    pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
891    pos = Bytes.putByte(bytes, pos, (byte) (flength & 0x0000ff));
892    if (flength != 0) {
893      pos = Bytes.putBytes(bytes, pos, family, foffset, flength);
894    }
895    if (qlength != 0) {
896      pos = Bytes.putBytes(bytes, pos, qualifier, qoffset, qlength);
897    }
898    pos = Bytes.putLong(bytes, pos, timestamp);
899    pos = Bytes.putByte(bytes, pos, type.getCode());
900    if (value != null && value.length > 0) {
901      pos = Bytes.putBytes(bytes, pos, value, voffset, vlength);
902    }
903    // Add the tags after the value part
904    if (tagsLength > 0) {
905      pos = Bytes.putAsShort(bytes, pos, tagsLength);
906      pos = Bytes.putBytes(bytes, pos, tags, tagsOffset, tagsLength);
907    }
908    return bytes;
909  }
910
911  /**
912   * @param qualifier can be a ByteBuffer or a byte[], or null.
913   * @param value     can be a ByteBuffer or a byte[], or null.
914   */
915  private static byte[] createByteArray(final byte[] row, final int roffset, final int rlength,
916    final byte[] family, final int foffset, int flength, final Object qualifier, final int qoffset,
917    int qlength, final long timestamp, final Type type, final Object value, final int voffset,
918    int vlength, List<Tag> tags) {
919
920    checkParameters(row, rlength, family, flength, qlength, vlength);
921
922    // Calculate length of tags area
923    int tagsLength = 0;
924    if (tags != null && !tags.isEmpty()) {
925      for (Tag t : tags) {
926        tagsLength += t.getValueLength() + Tag.INFRASTRUCTURE_SIZE;
927      }
928    }
929    RawCell.checkForTagsLength(tagsLength);
930    // Allocate right-sized byte array.
931    int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
932    byte[] bytes =
933      new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength, tagsLength)];
934
935    // Write key, value and key row length.
936    int pos = 0;
937    pos = Bytes.putInt(bytes, pos, keyLength);
938
939    pos = Bytes.putInt(bytes, pos, vlength);
940    pos = Bytes.putShort(bytes, pos, (short) (rlength & 0x0000ffff));
941    pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
942    pos = Bytes.putByte(bytes, pos, (byte) (flength & 0x0000ff));
943    if (flength != 0) {
944      pos = Bytes.putBytes(bytes, pos, family, foffset, flength);
945    }
946    if (qlength > 0) {
947      if (qualifier instanceof ByteBuffer) {
948        pos = Bytes.putByteBuffer(bytes, pos, (ByteBuffer) qualifier);
949      } else {
950        pos = Bytes.putBytes(bytes, pos, (byte[]) qualifier, qoffset, qlength);
951      }
952    }
953    pos = Bytes.putLong(bytes, pos, timestamp);
954    pos = Bytes.putByte(bytes, pos, type.getCode());
955    if (vlength > 0) {
956      if (value instanceof ByteBuffer) {
957        pos = Bytes.putByteBuffer(bytes, pos, (ByteBuffer) value);
958      } else {
959        pos = Bytes.putBytes(bytes, pos, (byte[]) value, voffset, vlength);
960      }
961    }
962    // Add the tags after the value part
963    if (tagsLength > 0) {
964      pos = Bytes.putAsShort(bytes, pos, tagsLength);
965      for (Tag t : tags) {
966        int tlen = t.getValueLength();
967        pos = Bytes.putAsShort(bytes, pos, tlen + Tag.TYPE_LENGTH_SIZE);
968        pos = Bytes.putByte(bytes, pos, t.getType());
969        Tag.copyValueTo(t, bytes, pos);
970        pos += tlen;
971      }
972    }
973    return bytes;
974  }
975
976  /**
977   * Needed doing 'contains' on List. Only compares the key portion, not the value.
978   */
979  @Override
980  public boolean equals(Object other) {
981    if (!(other instanceof ExtendedCell)) {
982      return false;
983    }
984    return PrivateCellUtil.equals(this, (ExtendedCell) other);
985  }
986
987  /**
988   * In line with {@link #equals(Object)}, only uses the key portion, not the value.
989   */
990  @Override
991  public int hashCode() {
992    return calculateHashForKey(this);
993  }
994
995  private int calculateHashForKey(ExtendedCell cell) {
996    // pre-calculate the 3 hashes made of byte ranges
997    int rowHash = Bytes.hashCode(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
998    int familyHash =
999      Bytes.hashCode(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
1000    int qualifierHash = Bytes.hashCode(cell.getQualifierArray(), cell.getQualifierOffset(),
1001      cell.getQualifierLength());
1002
1003    // combine the 6 sub-hashes
1004    int hash = 31 * rowHash + familyHash;
1005    hash = 31 * hash + qualifierHash;
1006    hash = 31 * hash + (int) cell.getTimestamp();
1007    hash = 31 * hash + cell.getTypeByte();
1008    return hash;
1009  }
1010
1011  // ---------------------------------------------------------------------------
1012  //
1013  // KeyValue cloning
1014  //
1015  // ---------------------------------------------------------------------------
1016
1017  /**
1018   * Clones a KeyValue. This creates a copy, re-allocating the buffer.
1019   * @return Fully copied clone of this KeyValue
1020   * @throws CloneNotSupportedException if cloning of keyValue is not supported
1021   */
1022  @Override
1023  public KeyValue clone() throws CloneNotSupportedException {
1024    KeyValue ret = (KeyValue) super.clone();
1025    ret.bytes = Arrays.copyOf(this.bytes, this.bytes.length);
1026    ret.offset = 0;
1027    ret.length = ret.bytes.length;
1028    // Important to clone the memstoreTS as well - otherwise memstore's
1029    // update-in-place methods (eg increment) will end up creating
1030    // new entries
1031    ret.setSequenceId(seqId);
1032    return ret;
1033  }
1034
1035  /**
1036   * Creates a shallow copy of this KeyValue, reusing the data byte buffer.
1037   * http://en.wikipedia.org/wiki/Object_copy
1038   * @return Shallow copy of this KeyValue
1039   */
1040  public KeyValue shallowCopy() {
1041    KeyValue shallowCopy = new KeyValue(this.bytes, this.offset, this.length);
1042    shallowCopy.setSequenceId(this.seqId);
1043    return shallowCopy;
1044  }
1045
1046  // ---------------------------------------------------------------------------
1047  //
1048  // String representation
1049  //
1050  // ---------------------------------------------------------------------------
1051
1052  @Override
1053  public String toString() {
1054    if (this.bytes == null || this.bytes.length == 0) {
1055      return "empty";
1056    }
1057    return keyToString(this.bytes, this.offset + ROW_OFFSET, getKeyLength()) + "/vlen="
1058      + getValueLength() + "/seqid=" + seqId;
1059  }
1060
1061  /** Return key as a String, empty string if k is null. */
1062  public static String keyToString(final byte[] k) {
1063    if (k == null) {
1064      return "";
1065    }
1066    return keyToString(k, 0, k.length);
1067  }
1068
1069  /**
1070   * Produces a string map for this key/value pair. Useful for programmatic use and manipulation of
1071   * the data stored in an WALKey, for example, printing as JSON. Values are left out due to their
1072   * tendency to be large. If needed, they can be added manually.
1073   * @return the Map&lt;String,?&gt; containing data from this key
1074   */
1075  public Map<String, Object> toStringMap() {
1076    Map<String, Object> stringMap = new HashMap<>();
1077    stringMap.put("row", Bytes.toStringBinary(getRowArray(), getRowOffset(), getRowLength()));
1078    stringMap.put("family",
1079      Bytes.toStringBinary(getFamilyArray(), getFamilyOffset(), getFamilyLength()));
1080    stringMap.put("qualifier",
1081      Bytes.toStringBinary(getQualifierArray(), getQualifierOffset(), getQualifierLength()));
1082    stringMap.put("timestamp", getTimestamp());
1083    stringMap.put("vlen", getValueLength());
1084    Iterator<Tag> tags = getTags();
1085    if (tags != null) {
1086      List<String> tagsString = new ArrayList<String>();
1087      while (tags.hasNext()) {
1088        tagsString.add(tags.next().toString());
1089      }
1090      stringMap.put("tag", tagsString);
1091    }
1092    return stringMap;
1093  }
1094
1095  /**
1096   * Use for logging.
1097   * @param b Key portion of a KeyValue.
1098   * @param o Offset to start of key
1099   * @param l Length of key.
1100   * @return Key as a String.
1101   */
1102  public static String keyToString(final byte[] b, final int o, final int l) {
1103    if (b == null) {
1104      return "";
1105    }
1106    int rowlength = Bytes.toShort(b, o);
1107    String row = Bytes.toStringBinary(b, o + Bytes.SIZEOF_SHORT, rowlength);
1108    int columnoffset = o + Bytes.SIZEOF_SHORT + 1 + rowlength;
1109    int familylength = b[columnoffset - 1];
1110    int columnlength = l - ((columnoffset - o) + TIMESTAMP_TYPE_SIZE);
1111    String family = familylength == 0 ? "" : Bytes.toStringBinary(b, columnoffset, familylength);
1112    String qualifier = columnlength == 0
1113      ? ""
1114      : Bytes.toStringBinary(b, columnoffset + familylength, columnlength - familylength);
1115    long timestamp = Bytes.toLong(b, o + (l - TIMESTAMP_TYPE_SIZE));
1116    String timestampStr = humanReadableTimestamp(timestamp);
1117    byte type = b[o + l - 1];
1118    return row + "/" + family + (family != null && family.length() > 0 ? ":" : "") + qualifier + "/"
1119      + timestampStr + "/" + Type.codeToType(type);
1120  }
1121
1122  public static String humanReadableTimestamp(final long timestamp) {
1123    if (timestamp == HConstants.LATEST_TIMESTAMP) {
1124      return "LATEST_TIMESTAMP";
1125    }
1126    if (timestamp == PrivateConstants.OLDEST_TIMESTAMP) {
1127      return "OLDEST_TIMESTAMP";
1128    }
1129    return String.valueOf(timestamp);
1130  }
1131
1132  // ---------------------------------------------------------------------------
1133  //
1134  // Public Member Accessors
1135  //
1136  // ---------------------------------------------------------------------------
1137
1138  /**
1139   * To be used only in tests where the Cells are clearly assumed to be of type KeyValue and that we
1140   * need access to the backing array to do some test case related assertions.
1141   * @return The byte array backing this KeyValue.
1142   */
1143  public byte[] getBuffer() {
1144    return this.bytes;
1145  }
1146
1147  /** Returns Offset into {@link #getBuffer()} at which this KeyValue starts. */
1148  public int getOffset() {
1149    return this.offset;
1150  }
1151
1152  /** Returns Length of bytes this KeyValue occupies in {@link #getBuffer()}. */
1153  public int getLength() {
1154    return length;
1155  }
1156
1157  // ---------------------------------------------------------------------------
1158  //
1159  // Length and Offset Calculators
1160  //
1161  // ---------------------------------------------------------------------------
1162
1163  /**
1164   * Determines the total length of the KeyValue stored in the specified byte array and offset.
1165   * Includes all headers.
1166   * @param bytes  byte array
1167   * @param offset offset to start of the KeyValue
1168   * @return length of entire KeyValue, in bytes
1169   */
1170  private static int getLength(byte[] bytes, int offset) {
1171    int klength = ROW_OFFSET + Bytes.toInt(bytes, offset);
1172    int vlength = Bytes.toInt(bytes, offset + Bytes.SIZEOF_INT);
1173    return klength + vlength;
1174  }
1175
1176  /** Returns Key offset in backing buffer.. */
1177  public int getKeyOffset() {
1178    return this.offset + ROW_OFFSET;
1179  }
1180
1181  public String getKeyString() {
1182    return Bytes.toStringBinary(getBuffer(), getKeyOffset(), getKeyLength());
1183  }
1184
1185  /** Returns Length of key portion. */
1186  public int getKeyLength() {
1187    return Bytes.toInt(this.bytes, this.offset);
1188  }
1189
1190  /**
1191   * Returns the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1192   */
1193  @Override
1194  public byte[] getValueArray() {
1195    return bytes;
1196  }
1197
1198  /** Returns the value offset */
1199  @Override
1200  public int getValueOffset() {
1201    int voffset = getKeyOffset() + getKeyLength();
1202    return voffset;
1203  }
1204
1205  /** Returns Value length */
1206  @Override
1207  public int getValueLength() {
1208    int vlength = Bytes.toInt(this.bytes, this.offset + Bytes.SIZEOF_INT);
1209    return vlength;
1210  }
1211
1212  /**
1213   * Returns the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1214   */
1215  @Override
1216  public byte[] getRowArray() {
1217    return bytes;
1218  }
1219
1220  /** Returns Row offset */
1221  @Override
1222  public int getRowOffset() {
1223    return this.offset + ROW_KEY_OFFSET;
1224  }
1225
1226  /** Returns Row length */
1227  @Override
1228  public short getRowLength() {
1229    return Bytes.toShort(this.bytes, getKeyOffset());
1230  }
1231
1232  /**
1233   * Returns the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1234   */
1235  @Override
1236  public byte[] getFamilyArray() {
1237    return bytes;
1238  }
1239
1240  /** Returns Family offset */
1241  @Override
1242  public int getFamilyOffset() {
1243    return getFamilyOffset(getFamilyLengthPosition(getRowLength()));
1244  }
1245
1246  /** Returns Family offset */
1247  int getFamilyOffset(int familyLenPosition) {
1248    return familyLenPosition + Bytes.SIZEOF_BYTE;
1249  }
1250
1251  /** Returns Family length */
1252  @Override
1253  public byte getFamilyLength() {
1254    return getFamilyLength(getFamilyLengthPosition(getRowLength()));
1255  }
1256
1257  /** Returns Family length */
1258  public byte getFamilyLength(int famLenPos) {
1259    return this.bytes[famLenPos];
1260  }
1261
1262  int getFamilyLengthPosition(int rowLength) {
1263    return this.offset + KeyValue.ROW_KEY_OFFSET + rowLength;
1264  }
1265
1266  /**
1267   * Returns the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1268   */
1269  @Override
1270  public byte[] getQualifierArray() {
1271    return bytes;
1272  }
1273
1274  /** Returns Qualifier offset */
1275  @Override
1276  public int getQualifierOffset() {
1277    return getQualifierOffset(getFamilyOffset());
1278  }
1279
1280  /** Returns Qualifier offset */
1281  private int getQualifierOffset(int foffset) {
1282    return getQualifierOffset(foffset, getFamilyLength());
1283  }
1284
1285  /** Returns Qualifier offset */
1286  int getQualifierOffset(int foffset, int flength) {
1287    return foffset + flength;
1288  }
1289
1290  /** Returns Qualifier length */
1291  @Override
1292  public int getQualifierLength() {
1293    return getQualifierLength(getRowLength(), getFamilyLength());
1294  }
1295
1296  /** Returns Qualifier length */
1297  private int getQualifierLength(int rlength, int flength) {
1298    return getQualifierLength(getKeyLength(), rlength, flength);
1299  }
1300
1301  /** Returns Qualifier length */
1302  int getQualifierLength(int keyLength, int rlength, int flength) {
1303    return keyLength - (int) getKeyDataStructureSize(rlength, flength, 0);
1304  }
1305
1306  /** Returns Timestamp offset */
1307  public int getTimestampOffset() {
1308    return getTimestampOffset(getKeyLength());
1309  }
1310
1311  /** Return the timestamp offset */
1312  private int getTimestampOffset(final int keylength) {
1313    return getKeyOffset() + keylength - TIMESTAMP_TYPE_SIZE;
1314  }
1315
1316  /** Returns True if this KeyValue has a LATEST_TIMESTAMP timestamp. */
1317  public boolean isLatestTimestamp() {
1318    return Bytes.equals(getBuffer(), getTimestampOffset(), Bytes.SIZEOF_LONG,
1319      HConstants.LATEST_TIMESTAMP_BYTES, 0, Bytes.SIZEOF_LONG);
1320  }
1321
1322  /**
1323   * Update the timestamp.
1324   * @param now Time to set into <code>this</code> IFF timestamp ==
1325   *            {@link HConstants#LATEST_TIMESTAMP} (else, its a noop).
1326   * @return True is we modified this.
1327   */
1328  public boolean updateLatestStamp(final byte[] now) {
1329    if (this.isLatestTimestamp()) {
1330      int tsOffset = getTimestampOffset();
1331      System.arraycopy(now, 0, this.bytes, tsOffset, Bytes.SIZEOF_LONG);
1332      // clear cache or else getTimestamp() possibly returns an old value
1333      return true;
1334    }
1335    return false;
1336  }
1337
1338  @Override
1339  public void setTimestamp(long ts) {
1340    Bytes.putBytes(this.bytes, this.getTimestampOffset(), Bytes.toBytes(ts), 0, Bytes.SIZEOF_LONG);
1341  }
1342
1343  @Override
1344  public void setTimestamp(byte[] ts) {
1345    Bytes.putBytes(this.bytes, this.getTimestampOffset(), ts, 0, Bytes.SIZEOF_LONG);
1346  }
1347
1348  // ---------------------------------------------------------------------------
1349  //
1350  // Methods that return copies of fields
1351  //
1352  // ---------------------------------------------------------------------------
1353
1354  /**
1355   * Do not use unless you have to. Used internally for compacting and testing. Use
1356   * {@link #getRowArray()}, {@link #getFamilyArray()}, {@link #getQualifierArray()}, and
1357   * {@link #getValueArray()} if accessing a KeyValue client-side.
1358   * @return Copy of the key portion only.
1359   */
1360  public byte[] getKey() {
1361    int keylength = getKeyLength();
1362    byte[] key = new byte[keylength];
1363    System.arraycopy(getBuffer(), getKeyOffset(), key, 0, keylength);
1364    return key;
1365  }
1366
1367  /** Return the timestamp. */
1368  @Override
1369  public long getTimestamp() {
1370    return getTimestamp(getKeyLength());
1371  }
1372
1373  /** Return the timestamp. */
1374  long getTimestamp(final int keylength) {
1375    int tsOffset = getTimestampOffset(keylength);
1376    return Bytes.toLong(this.bytes, tsOffset);
1377  }
1378
1379  /** Returns KeyValue.TYPE byte representation */
1380  @Override
1381  public byte getTypeByte() {
1382    return getTypeByte(getKeyLength());
1383  }
1384
1385  /** Return the KeyValue.TYPE byte representation */
1386  byte getTypeByte(int keyLength) {
1387    return this.bytes[this.offset + keyLength - 1 + ROW_OFFSET];
1388  }
1389
1390  /** Return the offset where the tag data starts. */
1391  @Override
1392  public int getTagsOffset() {
1393    int tagsLen = getTagsLength();
1394    if (tagsLen == 0) {
1395      return this.offset + this.length;
1396    }
1397    return this.offset + this.length - tagsLen;
1398  }
1399
1400  /** Return the total length of the tag bytes */
1401  @Override
1402  public int getTagsLength() {
1403    int tagsLen = this.length - (getKeyLength() + getValueLength() + KEYVALUE_INFRASTRUCTURE_SIZE);
1404    if (tagsLen > 0) {
1405      // There are some Tag bytes in the byte[]. So reduce 2 bytes which is added to denote the tags
1406      // length
1407      tagsLen -= TAGS_LENGTH_SIZE;
1408    }
1409    return tagsLen;
1410  }
1411
1412  /**
1413   * Returns the backing array of the entire KeyValue (all KeyValue fields are in a single array)
1414   */
1415  @Override
1416  public byte[] getTagsArray() {
1417    return bytes;
1418  }
1419
1420  /**
1421   * Creates a new KeyValue that only contains the key portion (the value is set to be null). TODO
1422   * only used by KeyOnlyFilter -- move there.
1423   * @param lenAsVal replace value with the actual value length (false=empty)
1424   */
1425  public KeyValue createKeyOnly(boolean lenAsVal) {
1426    // KV format: <keylen:4><valuelen:4><key:keylen><value:valuelen>
1427    // Rebuild as: <keylen:4><0:4><key:keylen>
1428    int dataLen = lenAsVal ? Bytes.SIZEOF_INT : 0;
1429    byte[] newBuffer = new byte[getKeyLength() + ROW_OFFSET + dataLen];
1430    System.arraycopy(this.bytes, this.offset, newBuffer, 0,
1431      Math.min(newBuffer.length, this.length));
1432    Bytes.putInt(newBuffer, Bytes.SIZEOF_INT, dataLen);
1433    if (lenAsVal) {
1434      Bytes.putInt(newBuffer, newBuffer.length - dataLen, this.getValueLength());
1435    }
1436    return new KeyValue(newBuffer);
1437  }
1438
1439  /**
1440   * Find index of passed delimiter walking from start of buffer forwards.
1441   * @param b         the kv serialized byte[] to process
1442   * @param delimiter input delimeter to fetch index from start
1443   * @return Index of delimiter having started from start of <code>b</code> moving rightward.
1444   */
1445  public static int getDelimiter(final byte[] b, int offset, final int length,
1446    final int delimiter) {
1447    if (b == null) {
1448      throw new IllegalArgumentException("Passed buffer is null");
1449    }
1450    int result = -1;
1451    for (int i = offset; i < length + offset; i++) {
1452      if (b[i] == delimiter) {
1453        result = i;
1454        break;
1455      }
1456    }
1457    return result;
1458  }
1459
1460  /**
1461   * Find index of passed delimiter walking from end of buffer backwards.
1462   * @param b         the kv serialized byte[] to process
1463   * @param offset    the offset in the byte[]
1464   * @param length    the length in the byte[]
1465   * @param delimiter input delimeter to fetch index from end
1466   * @return Index of delimiter
1467   */
1468  public static int getDelimiterInReverse(final byte[] b, final int offset, final int length,
1469    final int delimiter) {
1470    if (b == null) {
1471      throw new IllegalArgumentException("Passed buffer is null");
1472    }
1473    int result = -1;
1474    for (int i = (offset + length) - 1; i >= offset; i--) {
1475      if (b[i] == delimiter) {
1476        result = i;
1477        break;
1478      }
1479    }
1480    return result;
1481  }
1482
1483  /**
1484   * Create a KeyValue reading from <code>in</code>
1485   * @param in Where to read bytes from. Creates a byte array to hold the KeyValue backing bytes
1486   *           copied from the steam.
1487   * @return KeyValue created by deserializing from <code>in</code> OR if we find a length of zero,
1488   *         we will return null which can be useful marking a stream as done.
1489   * @throws IOException if any IO error happen
1490   */
1491  public static KeyValue create(final DataInput in) throws IOException {
1492    return create(in.readInt(), in);
1493  }
1494
1495  /**
1496   * Create a KeyValue reading <code>length</code> from <code>in</code>
1497   * @param length length of the Key
1498   * @param in     Input to read from
1499   * @return Created KeyValue OR if we find a length of zero, we will return null which can be
1500   *         useful marking a stream as done.
1501   * @throws IOException if any IO error happen
1502   */
1503  public static KeyValue create(int length, final DataInput in) throws IOException {
1504
1505    if (length <= 0) {
1506      if (length == 0) {
1507        return null;
1508      }
1509      throw new IOException("Failed read " + length + " bytes, stream corrupt?");
1510    }
1511
1512    // This is how the old Writables.readFrom used to deserialize. Didn't even vint.
1513    byte[] bytes = new byte[length];
1514    in.readFully(bytes);
1515    return new KeyValue(bytes, 0, length);
1516  }
1517
1518  /**
1519   * Write out a KeyValue in the manner in which we used to when KeyValue was a Writable.
1520   * @param kv  the KeyValue on which write is being requested
1521   * @param out OutputStream to write keyValue to
1522   * @return Length written on stream
1523   * @throws IOException if any IO error happen
1524   * @see #create(DataInput) for the inverse function
1525   */
1526  public static long write(final KeyValue kv, final DataOutput out) throws IOException {
1527    // This is how the old Writables write used to serialize KVs. Need to figure way to make it
1528    // work for all implementations.
1529    int length = kv.getLength();
1530    out.writeInt(length);
1531    out.write(kv.getBuffer(), kv.getOffset(), length);
1532    return (long) length + Bytes.SIZEOF_INT;
1533  }
1534
1535  @Override
1536  public int write(OutputStream out, boolean withTags) throws IOException {
1537    int len = getSerializedSize(withTags);
1538    out.write(this.bytes, this.offset, len);
1539    return len;
1540  }
1541
1542  @Override
1543  public int getSerializedSize(boolean withTags) {
1544    if (withTags) {
1545      return this.length;
1546    }
1547    return this.getKeyLength() + this.getValueLength() + KEYVALUE_INFRASTRUCTURE_SIZE;
1548  }
1549
1550  @Override
1551  public int getSerializedSize() {
1552    return this.length;
1553  }
1554
1555  @Override
1556  public void write(ByteBuffer buf, int offset) {
1557    ByteBufferUtils.copyFromArrayToBuffer(buf, offset, this.bytes, this.offset, this.length);
1558  }
1559
1560  /**
1561   * Avoids redundant comparisons for better performance. TODO get rid of this wart
1562   */
1563  public interface SamePrefixComparator<T> {
1564    /**
1565     * Compare two keys assuming that the first n bytes are the same.
1566     * @param commonPrefix How many bytes are the same.
1567     */
1568    int compareIgnoringPrefix(int commonPrefix, byte[] left, int loffset, int llength, byte[] right,
1569      int roffset, int rlength);
1570  }
1571
1572  /**
1573   * HeapSize implementation
1574   * <p/>
1575   * We do not count the bytes in the rowCache because it should be empty for a KeyValue in the
1576   * MemStore.
1577   */
1578  @Override
1579  public long heapSize() {
1580    // Deep object overhead for this KV consists of two parts. The first part is the KV object
1581    // itself, while the second part is the backing byte[]. We will only count the array overhead
1582    // from the byte[] only if this is the first KV in there.
1583    int fixed = ClassSize.align(FIXED_OVERHEAD);
1584    if (offset == 0) {
1585      // count both length and object overhead
1586      return fixed + ClassSize.sizeOfByteArray(length);
1587    } else {
1588      // only count the number of bytes
1589      return (long) fixed + length;
1590    }
1591  }
1592
1593  /**
1594   * A simple form of KeyValue that creates a keyvalue with only the key part of the byte[] Mainly
1595   * used in places where we need to compare two cells. Avoids copying of bytes In places like block
1596   * index keys, we need to compare the key byte[] with a cell. Hence create a Keyvalue(aka Cell)
1597   * that would help in comparing as two cells
1598   */
1599  public static class KeyOnlyKeyValue extends KeyValue {
1600    private short rowLen = -1;
1601
1602    public KeyOnlyKeyValue() {
1603
1604    }
1605
1606    public KeyOnlyKeyValue(byte[] b) {
1607      this(b, 0, b.length);
1608    }
1609
1610    public KeyOnlyKeyValue(byte[] b, int offset, int length) {
1611      this.bytes = b;
1612      this.length = length;
1613      this.offset = offset;
1614      this.rowLen = Bytes.toShort(this.bytes, this.offset);
1615    }
1616
1617    public void set(KeyOnlyKeyValue keyOnlyKeyValue) {
1618      this.bytes = keyOnlyKeyValue.bytes;
1619      this.length = keyOnlyKeyValue.length;
1620      this.offset = keyOnlyKeyValue.offset;
1621      this.rowLen = keyOnlyKeyValue.rowLen;
1622    }
1623
1624    public void clear() {
1625      rowLen = -1;
1626      bytes = null;
1627      offset = 0;
1628      length = 0;
1629    }
1630
1631    @Override
1632    public int getKeyOffset() {
1633      return this.offset;
1634    }
1635
1636    /**
1637     * A setter that helps to avoid object creation every time and whenever there is a need to
1638     * create new KeyOnlyKeyValue.
1639     * @param key    Key to set
1640     * @param offset Offset of the Key
1641     * @param length length of the Key
1642     */
1643    public void setKey(byte[] key, int offset, int length) {
1644      this.bytes = key;
1645      this.offset = offset;
1646      this.length = length;
1647      this.rowLen = Bytes.toShort(this.bytes, this.offset);
1648    }
1649
1650    @Override
1651    public byte[] getKey() {
1652      int keylength = getKeyLength();
1653      byte[] key = new byte[keylength];
1654      System.arraycopy(this.bytes, getKeyOffset(), key, 0, keylength);
1655      return key;
1656    }
1657
1658    @Override
1659    public byte[] getRowArray() {
1660      return bytes;
1661    }
1662
1663    @Override
1664    public int getRowOffset() {
1665      return getKeyOffset() + Bytes.SIZEOF_SHORT;
1666    }
1667
1668    @Override
1669    public byte[] getFamilyArray() {
1670      return bytes;
1671    }
1672
1673    @Override
1674    public byte getFamilyLength() {
1675      return this.bytes[getFamilyOffset() - 1];
1676    }
1677
1678    @Override
1679    int getFamilyLengthPosition(int rowLength) {
1680      return this.offset + Bytes.SIZEOF_SHORT + rowLength;
1681    }
1682
1683    @Override
1684    public int getFamilyOffset() {
1685      return this.offset + Bytes.SIZEOF_SHORT + getRowLength() + Bytes.SIZEOF_BYTE;
1686    }
1687
1688    @Override
1689    public byte[] getQualifierArray() {
1690      return bytes;
1691    }
1692
1693    @Override
1694    public int getQualifierLength() {
1695      return getQualifierLength(getRowLength(), getFamilyLength());
1696    }
1697
1698    @Override
1699    public int getQualifierOffset() {
1700      return getFamilyOffset() + getFamilyLength();
1701    }
1702
1703    @Override
1704    public int getKeyLength() {
1705      return length;
1706    }
1707
1708    @Override
1709    public short getRowLength() {
1710      return rowLen;
1711    }
1712
1713    @Override
1714    public byte getTypeByte() {
1715      return getTypeByte(getKeyLength());
1716    }
1717
1718    @Override
1719    byte getTypeByte(int keyLength) {
1720      return this.bytes[this.offset + keyLength - 1];
1721    }
1722
1723    private int getQualifierLength(int rlength, int flength) {
1724      return getKeyLength() - (int) getKeyDataStructureSize(rlength, flength, 0);
1725    }
1726
1727    @Override
1728    public long getTimestamp() {
1729      int tsOffset = getTimestampOffset();
1730      return Bytes.toLong(this.bytes, tsOffset);
1731    }
1732
1733    @Override
1734    public int getTimestampOffset() {
1735      return getKeyOffset() + getKeyLength() - TIMESTAMP_TYPE_SIZE;
1736    }
1737
1738    @Override
1739    public byte[] getTagsArray() {
1740      return HConstants.EMPTY_BYTE_ARRAY;
1741    }
1742
1743    @Override
1744    public int getTagsOffset() {
1745      return 0;
1746    }
1747
1748    @Override
1749    public byte[] getValueArray() {
1750      throw new IllegalArgumentException("KeyOnlyKeyValue does not work with values.");
1751    }
1752
1753    @Override
1754    public int getValueOffset() {
1755      throw new IllegalArgumentException("KeyOnlyKeyValue does not work with values.");
1756    }
1757
1758    @Override
1759    public int getValueLength() {
1760      throw new IllegalArgumentException("KeyOnlyKeyValue does not work with values.");
1761    }
1762
1763    @Override
1764    public int getTagsLength() {
1765      return 0;
1766    }
1767
1768    @Override
1769    public String toString() {
1770      if (this.bytes == null || this.bytes.length == 0) {
1771        return "empty";
1772      }
1773      return keyToString(this.bytes, this.offset, getKeyLength()) + "/vlen=0/mvcc=0";
1774    }
1775
1776    @Override
1777    public int hashCode() {
1778      return super.hashCode();
1779    }
1780
1781    @Override
1782    public boolean equals(Object other) {
1783      return super.equals(other);
1784    }
1785
1786    @Override
1787    public long heapSize() {
1788      return super.heapSize() + Bytes.SIZEOF_SHORT;
1789    }
1790
1791    @Override
1792    public int write(OutputStream out, boolean withTags) throws IOException {
1793      // This type of Cell is used only to maintain some internal states. We never allow this type
1794      // of Cell to be returned back over the RPC
1795      throw new IllegalStateException("A reader should never return this type of a Cell");
1796    }
1797  }
1798
1799  @Override
1800  public ExtendedCell deepClone() {
1801    byte[] copy = Bytes.copy(this.bytes, this.offset, this.length);
1802    KeyValue kv = new KeyValue(copy, 0, copy.length);
1803    kv.setSequenceId(this.getSequenceId());
1804    return kv;
1805  }
1806}