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.mapreduce;
019
020import java.io.ByteArrayInputStream;
021import java.io.DataInput;
022import java.io.DataInputStream;
023import java.io.DataOutput;
024import java.io.IOException;
025import org.apache.hadoop.hbase.CellComparator;
026import org.apache.hadoop.hbase.ExtendedCell;
027import org.apache.hadoop.hbase.KeyValue;
028import org.apache.hadoop.hbase.PrivateCellUtil;
029import org.apache.hadoop.io.WritableComparable;
030import org.apache.hadoop.io.WritableComparator;
031import org.apache.yetus.audience.InterfaceAudience;
032
033@InterfaceAudience.Private
034public class KeyOnlyCellComparable implements WritableComparable<KeyOnlyCellComparable> {
035
036  static {
037    WritableComparator.define(KeyOnlyCellComparable.class, new KeyOnlyCellComparator());
038  }
039
040  private ExtendedCell cell = null;
041
042  public KeyOnlyCellComparable() {
043  }
044
045  public KeyOnlyCellComparable(ExtendedCell cell) {
046    this.cell = cell;
047  }
048
049  public ExtendedCell getCell() {
050    return cell;
051  }
052
053  @Override
054  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "EQ_COMPARETO_USE_OBJECT_EQUALS",
055      justification = "This is wrong, yes, but we should be purging Writables, not fixing them")
056  public int compareTo(KeyOnlyCellComparable o) {
057    return CellComparator.getInstance().compare(cell, o.cell);
058  }
059
060  @Override
061  public void write(DataOutput out) throws IOException {
062    int keyLen = PrivateCellUtil.estimatedSerializedSizeOfKey(cell);
063    int valueLen = 0; // We avoid writing value here. So just serialize as if an empty value.
064    out.writeInt(keyLen + valueLen + KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE);
065    out.writeInt(keyLen);
066    out.writeInt(valueLen);
067    PrivateCellUtil.writeFlatKey(cell, out);
068    out.writeLong(cell.getSequenceId());
069  }
070
071  @Override
072  public void readFields(DataInput in) throws IOException {
073    cell = KeyValue.create(in);
074    long seqId = in.readLong();
075    cell.setSequenceId(seqId);
076  }
077
078  public static class KeyOnlyCellComparator extends WritableComparator {
079
080    @Override
081    public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
082      try (DataInputStream d1 = new DataInputStream(new ByteArrayInputStream(b1, s1, l1));
083        DataInputStream d2 = new DataInputStream(new ByteArrayInputStream(b2, s2, l2))) {
084        KeyOnlyCellComparable kv1 = new KeyOnlyCellComparable();
085        kv1.readFields(d1);
086        KeyOnlyCellComparable kv2 = new KeyOnlyCellComparable();
087        kv2.readFields(d2);
088        return compare(kv1, kv2);
089      } catch (IOException e) {
090        throw new RuntimeException(e);
091      }
092    }
093  }
094}