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.junit.Assert.assertEquals;
021import static org.junit.Assert.assertFalse;
022import static org.junit.Assert.assertTrue;
023import static org.junit.Assert.fail;
024
025import java.io.ByteArrayOutputStream;
026import java.io.IOException;
027import java.math.BigDecimal;
028import java.nio.ByteBuffer;
029import java.util.ArrayList;
030import java.util.List;
031import java.util.NavigableMap;
032import java.util.TreeMap;
033import org.apache.hadoop.hbase.testclassification.MiscTests;
034import org.apache.hadoop.hbase.testclassification.SmallTests;
035import org.apache.hadoop.hbase.util.Bytes;
036import org.junit.Assert;
037import org.junit.ClassRule;
038import org.junit.Test;
039import org.junit.experimental.categories.Category;
040import org.mockito.Mockito;
041
042@Category({ MiscTests.class, SmallTests.class })
043public class TestCellUtil {
044  @ClassRule
045  public static final HBaseClassTestRule CLASS_RULE =
046    HBaseClassTestRule.forClass(TestCellUtil.class);
047
048  /**
049   * CellScannable used in test. Returns a {@link TestCellScanner}
050   */
051  private static class TestCellScannable implements CellScannable {
052    private final int cellsCount;
053
054    TestCellScannable(final int cellsCount) {
055      this.cellsCount = cellsCount;
056    }
057
058    @Override
059    public CellScanner cellScanner() {
060      return new TestCellScanner(this.cellsCount);
061    }
062  }
063
064  /**
065   * CellScanner used in test.
066   */
067  private static class TestCellScanner implements CellScanner {
068    private int count = 0;
069    private Cell current = null;
070    private final int cellsCount;
071
072    TestCellScanner(final int cellsCount) {
073      this.cellsCount = cellsCount;
074    }
075
076    @Override
077    public Cell current() {
078      return this.current;
079    }
080
081    @Override
082    public boolean advance() {
083      if (this.count < cellsCount) {
084        this.current = new TestCell(this.count);
085        this.count++;
086        return true;
087      }
088      return false;
089    }
090  }
091
092  /**
093   * Cell used in test. Has row only.
094   */
095  private static class TestCell implements Cell {
096    private final byte[] row;
097
098    TestCell(final int i) {
099      this.row = Bytes.toBytes(i);
100    }
101
102    @Override
103    public byte[] getRowArray() {
104      return this.row;
105    }
106
107    @Override
108    public int getRowOffset() {
109      return 0;
110    }
111
112    @Override
113    public short getRowLength() {
114      return (short) this.row.length;
115    }
116
117    @Override
118    public byte[] getFamilyArray() {
119      // TODO Auto-generated method stub
120      return null;
121    }
122
123    @Override
124    public int getFamilyOffset() {
125      // TODO Auto-generated method stub
126      return 0;
127    }
128
129    @Override
130    public byte getFamilyLength() {
131      // TODO Auto-generated method stub
132      return 0;
133    }
134
135    @Override
136    public byte[] getQualifierArray() {
137      // TODO Auto-generated method stub
138      return null;
139    }
140
141    @Override
142    public int getQualifierOffset() {
143      // TODO Auto-generated method stub
144      return 0;
145    }
146
147    @Override
148    public int getQualifierLength() {
149      // TODO Auto-generated method stub
150      return 0;
151    }
152
153    @Override
154    public long getTimestamp() {
155      // TODO Auto-generated method stub
156      return 0;
157    }
158
159    @Override
160    public byte getTypeByte() {
161      // TODO Auto-generated method stub
162      return 0;
163    }
164
165    @Override
166    public byte[] getValueArray() {
167      // TODO Auto-generated method stub
168      return null;
169    }
170
171    @Override
172    public int getValueOffset() {
173      // TODO Auto-generated method stub
174      return 0;
175    }
176
177    @Override
178    public int getValueLength() {
179      // TODO Auto-generated method stub
180      return 0;
181    }
182
183    @Override
184    public int getSerializedSize() {
185      return 0;
186    }
187
188    @Override
189    public byte[] getTagsArray() {
190      // TODO Auto-generated method stub
191      return null;
192    }
193
194    @Override
195    public int getTagsOffset() {
196      // TODO Auto-generated method stub
197      return 0;
198    }
199
200    @Override
201    public long getSequenceId() {
202      // TODO Auto-generated method stub
203      return 0;
204    }
205
206    @Override
207    public int getTagsLength() {
208      // TODO Auto-generated method stub
209      return 0;
210    }
211
212    @Override
213    public long heapSize() {
214      return 0;
215    }
216  }
217
218  /**
219   * Was overflowing if 100k or so lists of cellscanners to return.
220   */
221  @Test
222  public void testCreateCellScannerOverflow() throws IOException {
223    consume(doCreateCellScanner(1, 1), 1);
224    consume(doCreateCellScanner(3, 0), 0);
225    consume(doCreateCellScanner(3, 3), 3 * 3);
226    consume(doCreateCellScanner(0, 1), 0);
227    // Do big number. See HBASE-11813 for why.
228    final int hundredK = 100000;
229    consume(doCreateCellScanner(hundredK, 0), 0);
230    consume(doCreateCellArray(1), 1);
231    consume(doCreateCellArray(0), 0);
232    consume(doCreateCellArray(3), 3);
233    List<CellScannable> cells = new ArrayList<>(hundredK);
234    for (int i = 0; i < hundredK; i++) {
235      cells.add(new TestCellScannable(1));
236    }
237    consume(CellUtil.createCellScanner(cells), hundredK);
238    NavigableMap<byte[], List<Cell>> m = new TreeMap<>(Bytes.BYTES_COMPARATOR);
239    List<Cell> cellArray = new ArrayList<>(hundredK);
240    for (int i = 0; i < hundredK; i++) {
241      cellArray.add(new TestCell(i));
242    }
243    m.put(new byte[] { 'f' }, cellArray);
244    consume(CellUtil.createCellScanner(m), hundredK);
245  }
246
247  private CellScanner doCreateCellArray(final int itemsPerList) {
248    Cell[] cells = new Cell[itemsPerList];
249    for (int i = 0; i < itemsPerList; i++) {
250      cells[i] = new TestCell(i);
251    }
252    return CellUtil.createCellScanner(cells);
253  }
254
255  private CellScanner doCreateCellScanner(final int listsCount, final int itemsPerList) {
256    List<CellScannable> cells = new ArrayList<>(listsCount);
257    for (int i = 0; i < listsCount; i++) {
258      CellScannable cs = new CellScannable() {
259        @Override
260        public CellScanner cellScanner() {
261          return new TestCellScanner(itemsPerList);
262        }
263      };
264      cells.add(cs);
265    }
266    return CellUtil.createCellScanner(cells);
267  }
268
269  private void consume(final CellScanner scanner, final int expected) throws IOException {
270    int count = 0;
271    while (scanner.advance()) {
272      count++;
273    }
274    Assert.assertEquals(expected, count);
275  }
276
277  @Test
278  public void testOverlappingKeys() {
279    byte[] empty = HConstants.EMPTY_BYTE_ARRAY;
280    byte[] a = Bytes.toBytes("a");
281    byte[] b = Bytes.toBytes("b");
282    byte[] c = Bytes.toBytes("c");
283    byte[] d = Bytes.toBytes("d");
284
285    // overlaps
286    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, b, a, b));
287    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, c, a, b));
288    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, b, a, c));
289    Assert.assertTrue(PrivateCellUtil.overlappingKeys(b, c, a, c));
290    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, c, b, c));
291    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, d, b, c));
292    Assert.assertTrue(PrivateCellUtil.overlappingKeys(b, c, a, d));
293
294    Assert.assertTrue(PrivateCellUtil.overlappingKeys(empty, b, a, b));
295    Assert.assertTrue(PrivateCellUtil.overlappingKeys(empty, b, a, c));
296
297    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, b, empty, b));
298    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, b, empty, c));
299
300    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, empty, a, b));
301    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, empty, a, c));
302
303    Assert.assertTrue(PrivateCellUtil.overlappingKeys(a, b, empty, empty));
304    Assert.assertTrue(PrivateCellUtil.overlappingKeys(empty, empty, a, b));
305
306    // non overlaps
307    Assert.assertFalse(PrivateCellUtil.overlappingKeys(a, b, c, d));
308    Assert.assertFalse(PrivateCellUtil.overlappingKeys(c, d, a, b));
309
310    Assert.assertFalse(PrivateCellUtil.overlappingKeys(b, c, c, d));
311    Assert.assertFalse(PrivateCellUtil.overlappingKeys(b, c, c, empty));
312    Assert.assertFalse(PrivateCellUtil.overlappingKeys(b, c, d, empty));
313    Assert.assertFalse(PrivateCellUtil.overlappingKeys(c, d, b, c));
314    Assert.assertFalse(PrivateCellUtil.overlappingKeys(c, empty, b, c));
315    Assert.assertFalse(PrivateCellUtil.overlappingKeys(d, empty, b, c));
316
317    Assert.assertFalse(PrivateCellUtil.overlappingKeys(b, c, a, b));
318    Assert.assertFalse(PrivateCellUtil.overlappingKeys(b, c, empty, b));
319    Assert.assertFalse(PrivateCellUtil.overlappingKeys(b, c, empty, a));
320    Assert.assertFalse(PrivateCellUtil.overlappingKeys(a, b, b, c));
321    Assert.assertFalse(PrivateCellUtil.overlappingKeys(empty, b, b, c));
322    Assert.assertFalse(PrivateCellUtil.overlappingKeys(empty, a, b, c));
323  }
324
325  @Test
326  public void testFindCommonPrefixInFlatKey() {
327    // The whole key matching case
328    KeyValue kv1 =
329      new KeyValue(Bytes.toBytes("r1"), Bytes.toBytes("f1"), Bytes.toBytes("q1"), null);
330    Assert.assertEquals(kv1.getKeyLength(),
331      PrivateCellUtil.findCommonPrefixInFlatKey(kv1, kv1, true, true));
332    Assert.assertEquals(kv1.getKeyLength(),
333      PrivateCellUtil.findCommonPrefixInFlatKey(kv1, kv1, false, true));
334    Assert.assertEquals(kv1.getKeyLength() - KeyValue.TIMESTAMP_TYPE_SIZE,
335      PrivateCellUtil.findCommonPrefixInFlatKey(kv1, kv1, true, false));
336    // The rk length itself mismatch
337    KeyValue kv2 =
338      new KeyValue(Bytes.toBytes("r12"), Bytes.toBytes("f1"), Bytes.toBytes("q1"), null);
339    Assert.assertEquals(1, PrivateCellUtil.findCommonPrefixInFlatKey(kv1, kv2, true, true));
340    // part of rk is same
341    KeyValue kv3 =
342      new KeyValue(Bytes.toBytes("r14"), Bytes.toBytes("f1"), Bytes.toBytes("q1"), null);
343    Assert.assertEquals(KeyValue.ROW_LENGTH_SIZE + Bytes.toBytes("r1").length,
344      PrivateCellUtil.findCommonPrefixInFlatKey(kv2, kv3, true, true));
345    // entire rk is same but different cf name
346    KeyValue kv4 =
347      new KeyValue(Bytes.toBytes("r14"), Bytes.toBytes("f2"), Bytes.toBytes("q1"), null);
348    Assert.assertEquals(
349      KeyValue.ROW_LENGTH_SIZE + kv3.getRowLength() + KeyValue.FAMILY_LENGTH_SIZE
350        + Bytes.toBytes("f").length,
351      PrivateCellUtil.findCommonPrefixInFlatKey(kv3, kv4, false, true));
352    // rk and family are same and part of qualifier
353    KeyValue kv5 =
354      new KeyValue(Bytes.toBytes("r14"), Bytes.toBytes("f2"), Bytes.toBytes("q123"), null);
355    Assert.assertEquals(
356      KeyValue.ROW_LENGTH_SIZE + kv3.getRowLength() + KeyValue.FAMILY_LENGTH_SIZE
357        + kv4.getFamilyLength() + kv4.getQualifierLength(),
358      PrivateCellUtil.findCommonPrefixInFlatKey(kv4, kv5, true, true));
359    // rk, cf and q are same. ts differs
360    KeyValue kv6 = new KeyValue(Bytes.toBytes("rk"), 1234L);
361    KeyValue kv7 = new KeyValue(Bytes.toBytes("rk"), 1235L);
362    // only last byte out of 8 ts bytes in ts part differs
363    Assert.assertEquals(
364      KeyValue.ROW_LENGTH_SIZE + kv6.getRowLength() + KeyValue.FAMILY_LENGTH_SIZE
365        + kv6.getFamilyLength() + kv6.getQualifierLength() + 7,
366      PrivateCellUtil.findCommonPrefixInFlatKey(kv6, kv7, true, true));
367    // rk, cf, q and ts are same. Only type differs
368    KeyValue kv8 = new KeyValue(Bytes.toBytes("rk"), 1234L, KeyValue.Type.Delete);
369    Assert.assertEquals(
370      KeyValue.ROW_LENGTH_SIZE + kv6.getRowLength() + KeyValue.FAMILY_LENGTH_SIZE
371        + kv6.getFamilyLength() + kv6.getQualifierLength() + KeyValue.TIMESTAMP_SIZE,
372      PrivateCellUtil.findCommonPrefixInFlatKey(kv6, kv8, true, true));
373    // With out TS_TYPE check
374    Assert.assertEquals(
375      KeyValue.ROW_LENGTH_SIZE + kv6.getRowLength() + KeyValue.FAMILY_LENGTH_SIZE
376        + kv6.getFamilyLength() + kv6.getQualifierLength(),
377      PrivateCellUtil.findCommonPrefixInFlatKey(kv6, kv8, true, false));
378  }
379
380  /**
381   * Assert CellUtil makes Cell toStrings same way we do KeyValue toStrings.
382   */
383  @Test
384  public void testToString() {
385    byte[] row = Bytes.toBytes("row");
386    long ts = 123L;
387    // Make a KeyValue and a Cell and see if same toString result.
388    KeyValue kv = new KeyValue(row, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, ts,
389      KeyValue.Type.Minimum, HConstants.EMPTY_BYTE_ARRAY);
390    Cell cell = CellUtil.createCell(row, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY,
391      ts, KeyValue.Type.Minimum.getCode(), HConstants.EMPTY_BYTE_ARRAY);
392    String cellToString = CellUtil.getCellKeyAsString(cell);
393    assertEquals(kv.toString(), cellToString);
394    // Do another w/ non-null family.
395    byte[] f = new byte[] { 'f' };
396    byte[] q = new byte[] { 'q' };
397    kv = new KeyValue(row, f, q, ts, KeyValue.Type.Minimum, HConstants.EMPTY_BYTE_ARRAY);
398    cell = CellUtil.createCell(row, f, q, ts, KeyValue.Type.Minimum.getCode(),
399      HConstants.EMPTY_BYTE_ARRAY);
400    cellToString = CellUtil.getCellKeyAsString(cell);
401    assertEquals(kv.toString(), cellToString);
402
403  }
404
405  @Test
406  public void testToString1() {
407    String row = "test.row";
408    String family = "test.family";
409    String qualifier = "test.qualifier";
410    long timestamp = 42;
411    KeyValue.Type type = KeyValue.Type.Put;
412    String value = "test.value";
413    long seqId = 1042;
414
415    Cell cell = CellUtil.createCell(Bytes.toBytes(row), Bytes.toBytes(family),
416      Bytes.toBytes(qualifier), timestamp, type.getCode(), Bytes.toBytes(value), seqId);
417
418    String nonVerbose = CellUtil.toString(cell, false);
419    String verbose = CellUtil.toString(cell, true);
420
421    System.out.println("nonVerbose=" + nonVerbose);
422    System.out.println("verbose=" + verbose);
423
424    Assert.assertEquals(String.format("%s/%s:%s/%d/%s/vlen=%s/seqid=%s", row, family, qualifier,
425      timestamp, type.toString(), Bytes.toBytes(value).length, seqId), nonVerbose);
426
427    Assert.assertEquals(String.format("%s/%s:%s/%d/%s/vlen=%s/seqid=%s/%s", row, family, qualifier,
428      timestamp, type.toString(), Bytes.toBytes(value).length, seqId, value), verbose);
429
430    // TODO: test with tags
431  }
432
433  @Test
434  public void testCloneCellFieldsFromByteBufferedCell() {
435    byte[] r = Bytes.toBytes("row1");
436    byte[] f = Bytes.toBytes("cf1");
437    byte[] q = Bytes.toBytes("qual1");
438    byte[] v = Bytes.toBytes("val1");
439    byte[] tags = Bytes.toBytes("tag1");
440    KeyValue kv =
441      new KeyValue(r, f, q, 0, q.length, 1234L, KeyValue.Type.Put, v, 0, v.length, tags);
442    ByteBuffer buffer = ByteBuffer.wrap(kv.getBuffer());
443    Cell bbCell = new ByteBufferKeyValue(buffer, 0, buffer.remaining());
444    byte[] rDest = CellUtil.cloneRow(bbCell);
445    assertTrue(Bytes.equals(r, rDest));
446    byte[] fDest = CellUtil.cloneFamily(bbCell);
447    assertTrue(Bytes.equals(f, fDest));
448    byte[] qDest = CellUtil.cloneQualifier(bbCell);
449    assertTrue(Bytes.equals(q, qDest));
450    byte[] vDest = CellUtil.cloneValue(bbCell);
451    assertTrue(Bytes.equals(v, vDest));
452    byte[] tDest = new byte[tags.length];
453    PrivateCellUtil.copyTagsTo(bbCell, tDest, 0);
454    assertTrue(Bytes.equals(tags, tDest));
455  }
456
457  @Test
458  public void testMatchingCellFieldsFromByteBufferedCell() {
459    byte[] r = Bytes.toBytes("row1");
460    byte[] f = Bytes.toBytes("cf1");
461    byte[] q1 = Bytes.toBytes("qual1");
462    byte[] q2 = Bytes.toBytes("qual2");
463    byte[] v = Bytes.toBytes("val1");
464    byte[] tags = Bytes.toBytes("tag1");
465    KeyValue kv =
466      new KeyValue(r, f, q1, 0, q1.length, 1234L, KeyValue.Type.Put, v, 0, v.length, tags);
467    ByteBuffer buffer = ByteBuffer.wrap(kv.getBuffer());
468    Cell bbCell1 = new ByteBufferKeyValue(buffer, 0, buffer.remaining());
469    kv = new KeyValue(r, f, q2, 0, q2.length, 1234L, KeyValue.Type.Put, v, 0, v.length, tags);
470    buffer = ByteBuffer.wrap(kv.getBuffer());
471    Cell bbCell2 = new ByteBufferKeyValue(buffer, 0, buffer.remaining());
472    assertTrue(CellUtil.matchingRows(bbCell1, bbCell2));
473    assertTrue(CellUtil.matchingRows(kv, bbCell2));
474    assertTrue(CellUtil.matchingRows(bbCell1, r));
475    assertTrue(CellUtil.matchingFamily(bbCell1, bbCell2));
476    assertTrue(CellUtil.matchingFamily(kv, bbCell2));
477    assertTrue(CellUtil.matchingFamily(bbCell1, f));
478    assertFalse(CellUtil.matchingQualifier(bbCell1, bbCell2));
479    assertTrue(CellUtil.matchingQualifier(kv, bbCell2));
480    assertTrue(CellUtil.matchingQualifier(bbCell1, q1));
481    assertTrue(CellUtil.matchingQualifier(bbCell2, q2));
482    assertTrue(CellUtil.matchingValue(bbCell1, bbCell2));
483    assertTrue(CellUtil.matchingValue(kv, bbCell2));
484    assertTrue(CellUtil.matchingValue(bbCell1, v));
485    assertFalse(CellUtil.matchingColumn(bbCell1, bbCell2));
486    assertTrue(CellUtil.matchingColumn(kv, bbCell2));
487    assertTrue(CellUtil.matchingColumn(bbCell1, f, q1));
488    assertTrue(CellUtil.matchingColumn(bbCell2, f, q2));
489  }
490
491  @Test
492  public void testCellFieldsAsPrimitiveTypesFromByteBufferedCell() {
493    int ri = 123;
494    byte[] r = Bytes.toBytes(ri);
495    byte[] f = Bytes.toBytes("cf1");
496    byte[] q = Bytes.toBytes("qual1");
497    long vl = 10981L;
498    byte[] v = Bytes.toBytes(vl);
499    KeyValue kv = new KeyValue(r, f, q, v);
500    ByteBuffer buffer = ByteBuffer.wrap(kv.getBuffer());
501    Cell bbCell = new ByteBufferKeyValue(buffer, 0, buffer.remaining());
502    assertEquals(ri, PrivateCellUtil.getRowAsInt(bbCell));
503    assertEquals(vl, PrivateCellUtil.getValueAsLong(bbCell));
504    double vd = 3005.5;
505    v = Bytes.toBytes(vd);
506    kv = new KeyValue(r, f, q, v);
507    buffer = ByteBuffer.wrap(kv.getBuffer());
508    bbCell = new ByteBufferKeyValue(buffer, 0, buffer.remaining());
509    assertEquals(vd, PrivateCellUtil.getValueAsDouble(bbCell), 0.0);
510    BigDecimal bd = new BigDecimal(9999);
511    v = Bytes.toBytes(bd);
512    kv = new KeyValue(r, f, q, v);
513    buffer = ByteBuffer.wrap(kv.getBuffer());
514    bbCell = new ByteBufferKeyValue(buffer, 0, buffer.remaining());
515    assertEquals(bd, PrivateCellUtil.getValueAsBigDecimal(bbCell));
516  }
517
518  @Test
519  public void testWriteCell() throws IOException {
520    byte[] r = Bytes.toBytes("row1");
521    byte[] f = Bytes.toBytes("cf1");
522    byte[] q1 = Bytes.toBytes("qual1");
523    byte[] v = Bytes.toBytes("val1");
524    byte[] tags = Bytes.toBytes("tag1");
525    KeyValue kv =
526      new KeyValue(r, f, q1, 0, q1.length, 1234L, KeyValue.Type.Put, v, 0, v.length, tags);
527    NonExtendedCell nonExtCell = new NonExtendedCell(kv);
528    ByteArrayOutputStream os = new ByteArrayOutputStream();
529    PrivateCellUtil.writeCell(nonExtCell, os, true);
530    byte[] byteArray = os.toByteArray();
531    KeyValue res = new KeyValue(byteArray);
532    assertTrue(CellUtil.equals(kv, res));
533  }
534
535  // Workaround for jdk 11 - reflective access to interface default methods for testGetType
536  private static abstract class CellForMockito implements Cell {
537  }
538
539  @Test
540  public void testGetType() {
541    CellForMockito c = Mockito.mock(CellForMockito.class);
542    Mockito.when(c.getType()).thenCallRealMethod();
543    for (Cell.Type type : Cell.Type.values()) {
544      Mockito.when(c.getTypeByte()).thenReturn(type.getCode());
545      assertEquals(type, c.getType());
546    }
547
548    try {
549      Mockito.when(c.getTypeByte()).thenReturn(KeyValue.Type.Maximum.getCode());
550      c.getType();
551      fail("The code of Maximum can't be handled by Cell.Type");
552    } catch (UnsupportedOperationException e) {
553    }
554
555    try {
556      Mockito.when(c.getTypeByte()).thenReturn(KeyValue.Type.Minimum.getCode());
557      c.getType();
558      fail("The code of Maximum can't be handled by Cell.Type");
559    } catch (UnsupportedOperationException e) {
560    }
561  }
562
563  private static class NonExtendedCell implements Cell {
564    private KeyValue kv;
565
566    public NonExtendedCell(KeyValue kv) {
567      this.kv = kv;
568    }
569
570    @Override
571    public byte[] getRowArray() {
572      return this.kv.getRowArray();
573    }
574
575    @Override
576    public int getRowOffset() {
577      return this.kv.getRowOffset();
578    }
579
580    @Override
581    public short getRowLength() {
582      return this.kv.getRowLength();
583    }
584
585    @Override
586    public byte[] getFamilyArray() {
587      return this.kv.getFamilyArray();
588    }
589
590    @Override
591    public int getFamilyOffset() {
592      return this.kv.getFamilyOffset();
593    }
594
595    @Override
596    public byte getFamilyLength() {
597      return this.kv.getFamilyLength();
598    }
599
600    @Override
601    public byte[] getQualifierArray() {
602      return this.kv.getQualifierArray();
603    }
604
605    @Override
606    public int getQualifierOffset() {
607      return this.kv.getQualifierOffset();
608    }
609
610    @Override
611    public int getQualifierLength() {
612      return this.kv.getQualifierLength();
613    }
614
615    @Override
616    public long getTimestamp() {
617      return this.kv.getTimestamp();
618    }
619
620    @Override
621    public byte getTypeByte() {
622      return this.kv.getTypeByte();
623    }
624
625    @Override
626    public long getSequenceId() {
627      return this.kv.getSequenceId();
628    }
629
630    @Override
631    public byte[] getValueArray() {
632      return this.kv.getValueArray();
633    }
634
635    @Override
636    public int getValueOffset() {
637      return this.kv.getValueOffset();
638    }
639
640    @Override
641    public int getValueLength() {
642      return this.kv.getValueLength();
643    }
644
645    @Override
646    public int getSerializedSize() {
647      return this.kv.getSerializedSize();
648    }
649
650    @Override
651    public byte[] getTagsArray() {
652      return this.kv.getTagsArray();
653    }
654
655    @Override
656    public int getTagsOffset() {
657      return this.kv.getTagsOffset();
658    }
659
660    @Override
661    public int getTagsLength() {
662      return this.kv.getTagsLength();
663    }
664
665    @Override
666    public long heapSize() {
667      return this.kv.heapSize();
668    }
669  }
670}