/* * Licensed 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 com.facebook.presto.raptor.systemtables; import com.facebook.presto.spi.type.Type; import com.google.common.primitives.Primitives; import io.airlift.slice.Slice; import javax.annotation.Nullable; import java.util.Objects; import static com.google.common.base.MoreObjects.toStringHelper; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static io.airlift.slice.Slices.utf8Slice; import static io.airlift.slice.Slices.wrappedBuffer; import static java.lang.String.format; import static java.util.Objects.requireNonNull; public class ValueBuffer { private final int columnIndex; private final Type type; private final Object value; private ValueBuffer(int columnIndex, Type type, @Nullable Object value) { checkArgument(columnIndex >= 0, "columnIndex must be > 0"); this.columnIndex = columnIndex; this.type = requireNonNull(type, "type is null"); this.value = value; } public static ValueBuffer create(int columnIndex, Type type, @Nullable Object value) { if (value == null) { return new ValueBuffer(columnIndex, type, null); } return new ValueBuffer(columnIndex, type, normalizeValue(type, value)); } private static Object normalizeValue(Type type, @Nullable Object value) { if (value == null) { return value; } Class<?> javaType = type.getJavaType(); if (javaType.isPrimitive()) { checkArgument(Primitives.wrap(javaType).isInstance(value), "Type %s incompatible with %s", type, value); return value; } if (javaType == Slice.class) { if (value instanceof Slice) { return value; } if (value instanceof String) { return utf8Slice(((String) value)); } if (value instanceof byte[]) { return wrappedBuffer((byte[]) value); } } throw new IllegalArgumentException(format("Type %s incompatible with %s", type, value)); } @Nullable public Object getValue() { checkState(!isNull()); return value; } public int getColumnIndex() { return columnIndex; } public long getLong() { checkState(!isNull()); checkArgument(type.getJavaType() == long.class, "Type %s cannot be read as long", type); return (Long) value; } public double getDouble() { checkState(!isNull()); checkArgument(type.getJavaType() == double.class, "Type %s cannot be read as double", type); return (Double) value; } public boolean getBoolean() { checkState(!isNull()); checkArgument(type.getJavaType() == boolean.class, "Type %s cannot be read as boolean", type); return (Boolean) value; } public Slice getSlice() { checkState(!isNull()); checkArgument(type.getJavaType() == Slice.class, "Type %s cannot be read as Slice", type); return (Slice) value; } public Type getType() { return type; } public boolean isNull() { return value == null; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } ValueBuffer that = (ValueBuffer) o; return Objects.equals(columnIndex, that.columnIndex) && Objects.equals(type, that.type) && Objects.equals(value, that.value); } @Override public int hashCode() { return Objects.hash(columnIndex, type, value); } @Override public String toString() { return toStringHelper(this) .add("columnIndex", columnIndex) .add("type", type) .add("value", value) .toString(); } }