/**
* Copyright 2011 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.index;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.hbase.index.ValuePartition.PartitionType;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.WritableComparable;
/**
* A ColumnQualifier contains information about column family name,qualifier and maximum value
* length used in index specification. maValueLength is used to make sure the common pattern for all
* the rowkeys in the index table. ColumnQualifier is used as input for index specification to
* specify column family and column qualifier on which we are going to do indexing.
*/
public class ColumnQualifier implements WritableComparable<ColumnQualifier> {
private byte[] cfBytes;
private byte[] qualifierBytes;
private int maxValueLength;
private ValuePartition valuePartition = null;
private ValueType type;
public ColumnQualifier() {
// Dummy constructor which is needed for the readFields
}
public ColumnQualifier(String cf, String qualifier) {
this(Bytes.toBytes(cf), Bytes.toBytes(qualifier));
}
public ColumnQualifier(byte[] cf, byte[] qualifier) {
this(cf, qualifier, ValueType.String, 0, null);
}
public ColumnQualifier(String cf, String qualifier, ValueType type, int maxValueLength) {
this(Bytes.toBytes(cf), Bytes.toBytes(qualifier), type, maxValueLength, null);
}
public ColumnQualifier(String cf, String qualifier, ValueType type, int maxValueLength,
ValuePartition vp) {
this(Bytes.toBytes(cf), Bytes.toBytes(qualifier), type, maxValueLength, vp);
}
public ColumnQualifier(byte[] cf, byte[] qualifier, ValueType type, int maxValueLength,
ValuePartition vp) {
this.cfBytes = cf;
this.qualifierBytes = qualifier;
this.type = type;
this.maxValueLength = maxValueLength;
this.valuePartition = vp;
}
/**
* @return Column Family as string
*/
public String getColumnFamilyString() {
return Bytes.toString(this.cfBytes);
}
/**
* @return Column qualifier as string
*/
public String getQualifierString() {
return Bytes.toString(this.qualifierBytes);
}
/**
* @return Column family as byte array
*/
public byte[] getColumnFamily() {
return this.cfBytes;
}
/**
* @return Column qualifier as byte array
*/
public byte[] getQualifier() {
return this.qualifierBytes;
}
public ValuePartition getValuePartition() {
return valuePartition;
}
/**
* @param DataInput Stream
* @throws IOException
*/
public void readFields(DataInput in) throws IOException {
this.cfBytes = Bytes.readByteArray(in);
this.qualifierBytes = Bytes.readByteArray(in);
this.type = ValueType.valueOf(Bytes.toString(Bytes.readByteArray(in)));
this.maxValueLength = in.readInt();
PartitionType p = PartitionType.valueOf(in.readUTF());
if (p.equals(PartitionType.SEPARATOR)) {
valuePartition = new SeparatorPartition();
} else if (p.equals(PartitionType.SPATIAL)) {
valuePartition = new SpatialPartition();
}
if (valuePartition != null) {
valuePartition.readFields(in);
}
}
/**
* @param DataOutput stream
* @throws IOException
*/
public void write(DataOutput out) throws IOException {
Bytes.writeByteArray(out, this.cfBytes);
Bytes.writeByteArray(out, this.qualifierBytes);
Bytes.writeByteArray(out, Bytes.toBytes(this.type.name()));
out.writeInt(maxValueLength);
if (valuePartition == null) {
out.writeUTF(PartitionType.NONE.name());
} else {
out.writeUTF(valuePartition.getPartitionType().name());
valuePartition.write(out);
}
}
/**
* @param ColumnQualifier with whom to compare
* @return return true if both objects are equal otherwise false
*/
@Override
public boolean equals(Object cq) {
if (this == cq) {
return true;
}
if (false == (cq instanceof ColumnQualifier)) {
return false;
}
return this.compareTo((ColumnQualifier) cq) == 0;
}
/**
* return hashcode of object
*/
public int hashCode() {
int result = Bytes.hashCode(this.cfBytes);
result ^= Bytes.hashCode(this.qualifierBytes);
result ^= this.maxValueLength;
if (valuePartition != null) result ^= valuePartition.hashCode();
return result;
}
/**
* @param IndexSpecification
* @return int
*/
@Override
public int compareTo(ColumnQualifier cq) {
int diff = 0;
diff = Bytes.compareTo(this.cfBytes, cq.cfBytes);
if (0 == diff) {
diff = Bytes.compareTo(this.qualifierBytes, cq.qualifierBytes);
if (0 == diff) {
if (valuePartition != null && cq.valuePartition != null) {
return valuePartition.compareTo(cq.valuePartition);
} else if (valuePartition == null && cq.valuePartition == null) {
return 0;
} else {
return 1;
}
}
}
return diff;
}
public int getMaxValueLength() {
return this.maxValueLength;
}
public ValueType getType() {
return this.type;
}
public enum ValueType {
String, Int, Float, Long, Double, Short, Byte, Char
};
// TODO - Include valuePartition also into this
public String toString() {
return "CF : " + getColumnFamilyString() + ",Qualifier : " + getQualifierString();
}
}