From 1c37aade7c5c8dbb58fb4a8e85724897e70b5353 Mon Sep 17 00:00:00 2001 From: Nick Dimiduk Date: Mon, 24 Jun 2013 15:06:37 -0700 Subject: [PATCH] HBASE-8693 Extensible data types API WIP. This patch introduces an extensible data types API for HBase. It is inspired by the following systems: - PostgreSQL. Postgres has a user-extensible data type API, which has been used to great effect by it's user community (ie, PostGIS). The desire is for HBase to expose an equally extensible data type API. One aspect of the Postgres data type is the ability to provide equivalence functions for index operations. This appears to be of critical performance utility for its execution engine. - Orderly. Orderly handles the issue of compound rowkeys by providing convenience classes for handling these kinds of data types. This influence is reflected in the Struct and Union family of classes. - Phoenix. The PDataType enum used in Phoenix provides type hints, similar Postgres's equivalence functions. These appear to be used during query execution for numerical type promotion. This initial WIP patch is intended to take a first cut at exercising the OrderedBytes API, particularly around numerical value support. The other intention is to establish the set of data types HBase should provide out of the box. The final intention of this WIP patch is to shop around the data types and API for their definition with a wider audience. Feedback from maintainers of both Phoenix and the Pig, Hive, and Impala HBase interoperability layers is desired. Patch TODOs include: - proper implementation of isComparableTo and isCoercibleTo - test coverage - javadocs --- .../java/org/apache/hadoop/hbase/types/Binary.java | 70 +++++++++++++ .../org/apache/hadoop/hbase/types/Boolean.java | 64 ++++++++++++ .../java/org/apache/hadoop/hbase/types/Byte.java | 72 +++++++++++++ .../java/org/apache/hadoop/hbase/types/Char.java | 60 +++++++++++ .../org/apache/hadoop/hbase/types/Decimal.java | 86 ++++++++++++++++ .../java/org/apache/hadoop/hbase/types/Double.java | 65 ++++++++++++ .../java/org/apache/hadoop/hbase/types/Float.java | 67 ++++++++++++ .../org/apache/hadoop/hbase/types/HDataType.java | 70 +++++++++++++ .../java/org/apache/hadoop/hbase/types/Int.java | 72 +++++++++++++ .../java/org/apache/hadoop/hbase/types/Long.java | 65 ++++++++++++ .../java/org/apache/hadoop/hbase/types/Short.java | 72 +++++++++++++ .../java/org/apache/hadoop/hbase/types/Struct.java | 113 +++++++++++++++++++++ .../java/org/apache/hadoop/hbase/types/Union2.java | 79 ++++++++++++++ .../java/org/apache/hadoop/hbase/types/Union3.java | 58 +++++++++++ .../java/org/apache/hadoop/hbase/types/Union4.java | 58 +++++++++++ .../org/apache/hadoop/hbase/types/Varbinary.java | 57 +++++++++++ .../org/apache/hadoop/hbase/types/Varchar.java | 50 +++++++++ .../java/org/apache/hadoop/hbase/types/Varint.java | 52 ++++++++++ 18 files changed, 1230 insertions(+) create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Binary.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Boolean.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Byte.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Char.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Decimal.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Double.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Float.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/HDataType.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Int.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Long.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Short.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Struct.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union2.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union3.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union4.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varbinary.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varchar.java create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varint.java diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Binary.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Binary.java new file mode 100644 index 0000000..3ddc260 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Binary.java @@ -0,0 +1,70 @@ +/** + * 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.types; + +import static org.apache.hadoop.hbase.types.Varbinary.VARBINARY; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Binary extends HDataType { + + protected final int size; + + public Binary(int size) { + this.size = size; + } + + @Override + public boolean isCoercibleTo(HDataType that, byte[] v) { + // TODO Auto-generated method stub + return false; + } + + @Override + public byte[] read(ByteBuffer b) { + byte[] ret = VARBINARY.read(b); + // TODO: ArithmeticException doesn't make sense here, but it maintains an + // API consistent with the other provided data types. + if (ret.length > size) throw new ArithmeticException("Overflow"); + return ret; + } + + @Override + public void write(ByteBuffer b, byte[] v, Order ord) { + // TODO: ArithmeticException doesn't make sense here, but it maintains an + // API consistent with the other provided data types. + if (v.length > size) throw new ArithmeticException("Overflow"); + VARBINARY.write(b, v, ord); + } + + /** + * Write a subset of v to b. + */ + public void write(ByteBuffer b, byte[] v, int length, int offset, Order ord) { + // TODO: ArithmeticException doesn't make sense here, but it maintains an + // API consistent with the other provided data types. + if (length > size) throw new ArithmeticException("Overflow"); + VARBINARY.write(b, v, length, offset, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Boolean.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Boolean.java new file mode 100644 index 0000000..ac76a04 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Boolean.java @@ -0,0 +1,64 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Boolean extends HDataType { + + @Override + public boolean isCoercibleTo(HDataType that, java.lang.Boolean v) { + // TODO Auto-generated method stub + return false; + } + + /** + * Read a boolean from buffer b. + */ + public boolean readBoolean(ByteBuffer b) { + // TODO: be more pedantic about decoded values? + long val = OrderedBytes.decodeInt(b); + return 0 != val; + } + + @Override + public java.lang.Boolean read(ByteBuffer b) { + return readBoolean(b); + } + + /** + * Write a boolean to buffer b respecting + * {@link Order} ord. + */ + public void write(ByteBuffer b, boolean v, Order ord) { + OrderedBytes.encodeInt(b, v == true ? 1 : 0, ord); + } + + @Override + public void write(ByteBuffer b, java.lang.Boolean v, Order ord) { + write(b, v, ord); + } + +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Byte.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Byte.java new file mode 100644 index 0000000..7dc1e60 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Byte.java @@ -0,0 +1,72 @@ +/** + * 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.types; + +import static java.lang.Byte.MAX_VALUE; +import static java.lang.Byte.MIN_VALUE; +import static java.lang.Byte.valueOf; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Byte extends HDataType { + + public static final Byte BYTE = new Byte(); + + protected Byte() {} + + @Override + public boolean isCoercibleTo(HDataType that, java.lang.Byte v) { + // TODO Auto-generated method stub + return false; + } + + /** + * Read a byte from buffer b. + */ + public byte readByte(ByteBuffer b) { + long val = OrderedBytes.decodeInt(b); + if (val < MIN_VALUE || val > MAX_VALUE) + throw new ArithmeticException("Overflow"); + return (byte) val; + } + + @Override + public java.lang.Byte read(ByteBuffer b) { + return valueOf(readByte(b)); + } + + /** + * Write a byte to buffer b respecting + * {@link Order} ord. + */ + public void write(ByteBuffer b, short v, Order ord) { + OrderedBytes.encodeInt(b, v, ord); + } + + @Override + public void write(ByteBuffer b, java.lang.Byte v, Order ord) { + write(b, v, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Char.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Char.java new file mode 100644 index 0000000..955848b --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Char.java @@ -0,0 +1,60 @@ +/** + * 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.types; + +import static org.apache.hadoop.hbase.types.Varchar.VARCHAR; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Char extends HDataType { + + protected final int size; + + public Char(int size) { + this.size = size; + } + + @Override + public boolean isCoercibleTo(HDataType that, String v) { + // TODO Auto-generated method stub + return false; + } + + @Override + public String read(ByteBuffer b) { + String ret = VARCHAR.read(b); + // TODO: ArithmeticException doesn't make sense here, but it maintains an + // API consistent with the other provided data types. + if (ret.length() > size) throw new ArithmeticException("Overflow"); + return ret; + } + + @Override + public void write(ByteBuffer b, String v, Order ord) { + // TODO: ArithmeticException doesn't make sense here, but it maintains an + // API consistent with the other provided data types. + if (v.length() > size) throw new ArithmeticException("Overflow"); + VARCHAR.write(b, v, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Decimal.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Decimal.java new file mode 100644 index 0000000..e625ebe --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Decimal.java @@ -0,0 +1,86 @@ +/** + * 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.types; + +import static org.apache.hadoop.hbase.types.Int.INT; +import static org.apache.hadoop.hbase.types.Long.LONG; +import static org.apache.hadoop.hbase.types.Short.SHORT; +import static org.apache.hadoop.hbase.types.Varint.VARINT; + +import java.math.BigDecimal; +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Decimal extends HDataType { + + public static final Decimal DECIMAL = new Decimal(); + + protected Decimal() {} + + @Override + public boolean isCoercibleTo(HDataType that, BigDecimal v) { + if (null != v) { + if (that == VARINT) { + try { + v.toBigIntegerExact(); + return true; + } catch (ArithmeticException e) { + return false; + } + } else if (that == LONG) { + try { + v.longValueExact(); + return true; + } catch (ArithmeticException e) { + return false; + } + } else if (that == INT) { + try { + v.intValueExact(); + return true; + } catch (ArithmeticException e) { + return false; + } + } else if (that == SHORT) { + try { + v.shortValueExact(); + return true; + } catch (ArithmeticException e) { + return false; + } + } + } + return super.isCoercibleTo(that); + } + + @Override + public BigDecimal read(ByteBuffer b) { + return BigDecimal.valueOf(OrderedBytes.decodeReal(b)); + } + + @Override + public void write(ByteBuffer b, BigDecimal o, Order ord) { + OrderedBytes.encodeReal(b, o, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Double.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Double.java new file mode 100644 index 0000000..733e4b5 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Double.java @@ -0,0 +1,65 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Double extends HDataType { + + public static final Double DOUBLE = new Double(); + + protected Double() {} + + @Override + public boolean isCoercibleTo(HDataType that, java.lang.Double v) { + // TODO Auto-generated method stub + return false; + } + + /** + * Read a double from buffer b. + */ + public double readDouble(ByteBuffer b) { + return OrderedBytes.decodeReal(b); + } + + @Override + public java.lang.Double read(ByteBuffer b) { + return java.lang.Double.valueOf(readDouble(b)); + } + + /** + * Write a double to buffer b respecting + * {@link Order} ord. + */ + public void write(ByteBuffer b, double v, Order ord) { + OrderedBytes.encodeReal(b, v, ord); + } + + @Override + public void write(ByteBuffer b, java.lang.Double v, Order ord) { + write(b, v, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Float.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Float.java new file mode 100644 index 0000000..99fd339 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Float.java @@ -0,0 +1,67 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Float extends HDataType { + + public static final Float FLOAT = new Float(); + + protected Float() {} + + @Override + public boolean isCoercibleTo(HDataType that, java.lang.Float v) { + // TODO Auto-generated method stub + return false; + } + + /** + * Read a float from buffer b. + */ + public float readFloat(ByteBuffer b) { + // TODO: should perform value checking and throw ArithmeticException like + // all the rest? + return (float) OrderedBytes.decodeReal(b); + } + + @Override + public java.lang.Float read(ByteBuffer b) { + return java.lang.Float.valueOf(readFloat(b)); + } + + /** + * Write a float to buffer b respecting + * {@link Order} ord. + */ + public void write(ByteBuffer b, float v, Order ord) { + OrderedBytes.encodeReal(b, v, ord); + } + + @Override + public void write(ByteBuffer b, java.lang.Float v, Order ord) { + write(b, v, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/HDataType.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/HDataType.java new file mode 100644 index 0000000..4c0f536 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/HDataType.java @@ -0,0 +1,70 @@ +/** + * 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.types; + +import static org.apache.hadoop.hbase.types.Varbinary.VARBINARY; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public abstract class HDataType { + + /** + * Compares this HDataType to another HDataType, + * ignoring any difference in {@link Order}. + */ + public boolean equalsIgnoreOrder(HDataType that) { + return getClass().equals(that.getClass()) || this == that; + } + + /** + * Return true when this type is comparable to that type, false + * otherwise. + */ + public boolean isComparableTo(HDataType that) { + return isCoercibleTo(that) || that.isCoercibleTo(this); + } + + /** + * Return true when this type can be coerced into that type. + */ + public boolean isCoercibleTo(HDataType that) { + return this == that || that == VARBINARY; + } + + /** + * Return true when v can be coerced into that + * type. + */ + public abstract boolean isCoercibleTo(HDataType that, T v); + + /** + * Read an instance of T from the buffer b. + */ + public abstract T read(ByteBuffer b); + + /** + * Write instance v into buffer b. + */ + public abstract void write(ByteBuffer b, T v, Order ord); +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Int.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Int.java new file mode 100644 index 0000000..ae7c955 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Int.java @@ -0,0 +1,72 @@ +/** + * 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.types; + +import static java.lang.Integer.MAX_VALUE; +import static java.lang.Integer.MIN_VALUE; +import static java.lang.Integer.valueOf; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Int extends HDataType { + + public static final Int INT = new Int(); + + protected Int() {} + + @Override + public boolean isCoercibleTo(HDataType that, Integer v) { + // TODO Auto-generated method stub + return false; + } + + /** + * Read an int from buffer b. + */ + public int readInt(ByteBuffer b) { + long val = OrderedBytes.decodeInt(b); + if (val < MIN_VALUE || val > MAX_VALUE) + throw new ArithmeticException("Overflow"); + return (int) val; + } + + @Override + public Integer read(ByteBuffer b) { + return valueOf(readInt(b)); + } + + /** + * Write an int to buffer b respecting + * {@link Order} ord. + */ + public void write(ByteBuffer b, int v, Order ord) { + OrderedBytes.encodeInt(b, v, ord); + } + + @Override + public void write(ByteBuffer b, Integer v, Order ord) { + write(b, v, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Long.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Long.java new file mode 100644 index 0000000..0471f92 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Long.java @@ -0,0 +1,65 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Long extends HDataType { + + public static Long LONG = new Long(); + + protected Long() {} + + @Override + public boolean isCoercibleTo(HDataType that, java.lang.Long v) { + // TODO Auto-generated method stub + return false; + } + + /** + * Read a long from buffer b. + */ + public long readLong(ByteBuffer b) { + return OrderedBytes.decodeInt(b); + } + + @Override + public java.lang.Long read(ByteBuffer b) { + return readLong(b); + } + + /** + * Write a long to buffer b respecting + * {@link Order} ord. + */ + public void write(ByteBuffer b, long v, Order ord) { + OrderedBytes.encodeInt(b, v, ord); + } + + @Override + public void write(ByteBuffer b, java.lang.Long v, Order ord) { + write(b, v, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Short.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Short.java new file mode 100644 index 0000000..ce760dc --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Short.java @@ -0,0 +1,72 @@ +/** + * 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.types; + +import static java.lang.Short.MAX_VALUE; +import static java.lang.Short.MIN_VALUE; +import static java.lang.Short.valueOf; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Short extends HDataType { + + public static final Short SHORT = new Short(); + + protected Short() {} + + @Override + public boolean isCoercibleTo(HDataType that, java.lang.Short v) { + // TODO Auto-generated method stub + return false; + } + + /** + * Read a short from buffer b. + */ + public short readShort(ByteBuffer b) { + long val = OrderedBytes.decodeInt(b); + if (val < MIN_VALUE || val > MAX_VALUE) + throw new ArithmeticException("Overflow"); + return (short) val; + } + + @Override + public java.lang.Short read(ByteBuffer b) { + return valueOf(readShort(b)); + } + + /** + * Write a short to buffer b respecting + * {@link Order} ord. + */ + public void write(ByteBuffer b, short v, Order ord) { + OrderedBytes.encodeInt(b, v, ord); + } + + @Override + public void write(ByteBuffer b, java.lang.Short v, Order ord) { + write(b, v, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Struct.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Struct.java new file mode 100644 index 0000000..11c9776 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Struct.java @@ -0,0 +1,113 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; +import java.util.Iterator; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +/** + * The Struct family of {@link HDataType} represent a sequence of + * values encoded into the same {@link ByteBuffer}. The order of the encoded + * values are preserved in the buffer, making Struct + * an appropriate object for managing the compound rowkey schema + * design pattern. It also provides a convenience {@link Iterator} for + * consuming the sequence of values. + */ +@InterfaceAudience.Public +@InterfaceStability.Evolving +public abstract class Struct extends HDataType { + + /** + * An {@link Iterator} over encoded values. + */ + protected static class StructIterator implements Iterator { + + protected final ByteBuffer b; + + /** + * Construct StructIterator over the values encoded in + * b. + */ + public StructIterator(final ByteBuffer b) { this.b = b; } + + @Override + public boolean hasNext() { + return b.position() != b.limit(); + } + + @Override + public Object next() { + return OrderedBytes.decode(b); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + /** + * Bypass the next encoded value. + */ + public void skip() { + OrderedBytes.skip(b); + } + } + + @Override + public boolean isCoercibleTo(HDataType that, T v) { + return isCoercibleTo(that); + } + + @Override + public void write(ByteBuffer b, T v, Order ord) { + OrderedBytes.encode(b, v, ord); + } + + /** + * Write instance v to buffer b, respecting + * per-element ordering as described by ord. + */ + public void write(ByteBuffer b, Object[] v, Order[] ord) { + OrderedBytes.encode(b, v, ord); + } + + /** + * A helper function for decoding entries from b. Intended for + * use by subclasses for the implementation of {@link #read(ByteBuffer)}. + */ + protected Object[] readMembers(ByteBuffer b) { + return OrderedBytes.decode(b); + } + + /** + * Retrieve an {@link Iterator} over the values encoded in b. + * The byte[] backing b is not modified by use of + * the Iterator, however the state of b is. To + * create multiple Iterators over the same backing + * ByteBuffer, construct the Iterators over + * duplicates ( {@link ByteBuffer#duplicate()} ) of b. + */ + protected StructIterator iterator(final ByteBuffer b) { + return new StructIterator(b); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union2.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union2.java new file mode 100644 index 0000000..5a74ac4 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union2.java @@ -0,0 +1,79 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +/** + * The Union family of {@link HDataType}s encode one of a fixed + * set of Objects. They provide convenience methods which handle + * type casting on your behalf. + */ +@SuppressWarnings("unchecked") +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Union2 extends HDataType { + + protected final HDataType typeA; + protected final HDataType typeB; + + /** + * Create an instance of Union2 over the set of specified + * types. + */ + public Union2(HDataType typeA, HDataType typeB) { + this.typeA = typeA; + this.typeB = typeB; + } + + @Override + public boolean isCoercibleTo(HDataType that, Object v) { + if (typeA.isCoercibleTo(that)) return typeA.isCoercibleTo(that, (A) v); + else if (typeB.isCoercibleTo(that)) return typeB.isCoercibleTo(that, (B) v); + return false; + } + + @Override + public Object read(ByteBuffer b) { + return OrderedBytes.decode(b); + } + + /** + * Read an instance of the first type parameter from buffer b. + */ + public A readA(ByteBuffer b) { + return (A) read(b); + } + + /** + * Read an instance of the second type parameter from buffer b. + */ + public B readB(ByteBuffer b) { + return (B) read(b); + } + + @Override + public void write(ByteBuffer b, Object v, Order ord) { + OrderedBytes.encode(b, v, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union3.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union3.java new file mode 100644 index 0000000..4779274 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union3.java @@ -0,0 +1,58 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * The Union family of {@link HDataType}s encode one of a fixed + * collection of Objects. They provide convenience methods which handle type + * casting on your behalf. + */ +@SuppressWarnings("unchecked") +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Union3 extends Union2 { + + protected final HDataType typeC; + + /** + * Create an instance of Union3 over the set of specified + * types. + */ + public Union3(HDataType typeA, HDataType typeB, HDataType typeC) { + super(typeA, typeB); + this.typeC = typeC; + } + + @Override + public boolean isCoercibleTo(HDataType that, Object v) { + if (typeC.isCoercibleTo(that)) return typeC.isCoercibleTo(that, (C) v); + else return super.isCoercibleTo(that, v); + } + + /** + * Read an instance of the third type parameter from buffer b. + */ + public C readC(ByteBuffer b) { + return (C) super.read(b); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union4.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union4.java new file mode 100644 index 0000000..aae5ac9 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Union4.java @@ -0,0 +1,58 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * The Union family of {@link HDataType}s encode one of a fixed + * collection of Objects. They provide convenience methods which handle type + * casting on your behalf. + */ +@SuppressWarnings("unchecked") +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Union4 extends Union3 { + + protected final HDataType typeD; + + /** + * Create an instance of Union4 over the set of specified + * types. + */ + public Union4(HDataType typeA, HDataType typeB, HDataType typeC, HDataType typeD) { + super(typeA, typeB, typeC); + this.typeD = typeD; + } + + @Override + public boolean isCoercibleTo(HDataType that, Object v) { + if (typeD.isCoercibleTo(that)) return typeD.isCoercibleTo(that, (D) v); + else return super.isCoercibleTo(that, v); + } + + /** + * Read an instance of the fourth type parameter from buffer b. + */ + public D readD(ByteBuffer b) { + return (D) super.read(b); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varbinary.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varbinary.java new file mode 100644 index 0000000..b8e318a --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varbinary.java @@ -0,0 +1,57 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Varbinary extends HDataType { + + public static final Varbinary VARBINARY = new Varbinary(); + + protected Varbinary() {} + + @Override + public boolean isCoercibleTo(HDataType that, byte[] v) { + // TODO Auto-generated method stub + return false; + } + + @Override + public byte[] read(ByteBuffer b) { + return OrderedBytes.decodeBlobLast(b); + } + + @Override + public void write(ByteBuffer b, byte[] v, Order ord) { + OrderedBytes.encodeBlobLast(b, v, ord); + } + + /** + * Write a subset of v to b. + */ + public void write(ByteBuffer b, byte[] v, int length, int offset, Order ord) { + OrderedBytes.encodeBlobLast(b, v, offset, length, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varchar.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varchar.java new file mode 100644 index 0000000..8f95f12 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varchar.java @@ -0,0 +1,50 @@ +/** + * 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.types; + +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Varchar extends HDataType { + + public static final Varchar VARCHAR = new Varchar(); + + protected Varchar() {} + + @Override + public boolean isCoercibleTo(HDataType that, String v) { + // TODO Auto-generated method stub + return false; + } + + @Override + public String read(ByteBuffer b) { + return OrderedBytes.decodeString(b); + } + + @Override + public void write(ByteBuffer b, String v, Order ord) { + OrderedBytes.encodeString(b, v, ord); + } +} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varint.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varint.java new file mode 100644 index 0000000..5186ba7 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/types/Varint.java @@ -0,0 +1,52 @@ +/** + * 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.types; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.util.OrderedBytes; +import org.apache.hadoop.hbase.util.OrderedBytes.Order; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class Varint extends HDataType { + + public static final Varint VARINT = new Varint(); + + protected Varint() {} + + @Override + public boolean isCoercibleTo(HDataType that, BigInteger v) { + // TODO Auto-generated method stub + return false; + } + + @Override + public BigInteger read(ByteBuffer b) { + return BigInteger.valueOf(OrderedBytes.decodeInt(b)); + } + + @Override + public void write(ByteBuffer b, BigInteger v, Order ord) { + OrderedBytes.encodeReal(b, new BigDecimal(v), ord); + } +} -- 1.8.1