org.cloudgraph.rocksdb.service.RocksDBDataConverter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cloudgraph-rocksdb Show documentation
Show all versions of cloudgraph-rocksdb Show documentation
CloudGraph(tm) is a suite of Service Data Object (SDO) 2.1 services designed for relational and big-table style "cloud" databases, such as HBase and others.
The newest version!
/**
* Copyright 2017 TerraMeta Software, Inc.
*
* 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 org.cloudgraph.rocksdb.service;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jena.ext.com.google.common.primitives.Longs;
import org.apache.jena.ext.com.google.common.primitives.UnsignedInteger;
import org.apache.jena.ext.com.google.common.primitives.UnsignedLong;
import org.cloudgraph.common.Bytes;
import org.plasma.sdo.DataType;
import org.plasma.sdo.helper.DataConverter;
import org.apache.jena.ext.com.google.common.primitives.Ints;
import commonj.sdo.Property;
/**
* RocksDB specific data converter, delegates to {@link DataConverter} under
* certain conditions.
*
* @author Scott Cinnamond
* @since 0.5
*/
public class RocksDBDataConverter implements org.cloudgraph.core.DataConverter {
private static Log log = LogFactory.getFactory().getInstance(RocksDBDataConverter.class);
static public volatile RocksDBDataConverter INSTANCE = initializeInstance();
private RocksDBDataConverter() {
}
/**
* Converts the given value to bytes based on data type and cardinality
* information for the given property. For 'many' or multi-valued properties,
* if the SDO Java type for the property is not already String, the value is
* first converted to String using the SDO conversion which uses
* java.util.Arrays formatting.
*
* @param sourceProperty
* the source property
* @param value
* the value
* @return the bytes
* @throws IllegalArgumentException
* if the given property is not a data type property
*/
private static synchronized RocksDBDataConverter initializeInstance() {
if (INSTANCE == null)
INSTANCE = new RocksDBDataConverter();
return INSTANCE;
}
public Object fromBytes(Property targetProperty, byte[] value) {
Object result = null;
if (!targetProperty.getType().isDataType())
throw new IllegalArgumentException("property " + targetProperty.toString()
+ " is not a datatype property");
DataType targetDataType = DataType.valueOf(targetProperty.getType().getName());
switch (targetDataType) {
// Data types stored as String bytes in HBase
case String:
case Strings:
case URI:
case Month:
case MonthDay:
case Day:
case Time:
case Year:
case YearMonth:
case YearMonthDay:
case Duration:
String resultStr = Bytes.toString(value);
result = DataConverter.INSTANCE.fromString(targetProperty, resultStr);
break;
case Date:
resultStr = Bytes.toString(value);
result = DataConverter.INSTANCE.fromString(targetProperty, resultStr);
break;
case DateTime:
// NOTE: remember datetime is a String Java representation in
// SDO 2.1
resultStr = Bytes.toString(value);
result = DataConverter.INSTANCE.fromString(targetProperty, resultStr);
break;
// Data types stored by directly converting from primitive types to
// bytes in HBase.
// FIXME: what to do with variable size types e.g. Decimal, BigInteger,
// Bytes
case Decimal:
if (!targetProperty.isMany())
result = Bytes.toBigDecimal(value);
else
result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
break;
case Bytes:
if (!targetProperty.isMany())
result = value; // already bytes
else
result = value; // already bytes
break;
case Byte:
if (!targetProperty.isMany()) {
// NOTE: no toByte method as would expect as there is
// opposite method, see below
// e.g. Bytes.toByte(value);
if (value != null) {
if (value.length > 2)
log.warn("truncating " + String.valueOf(value.length)
+ " length byte array for target data type 'byte'");
result = value[0];
}
} else {
result = value;
}
break;
case Boolean:
if (!targetProperty.isMany()) {
result = Bytes.toBoolean(value);
} else {
int count = value.length / Bytes.SIZEOF_BOOLEAN;
List list = new ArrayList<>(count);
for (int offset = 0, idx = 0; offset < value.length; offset += Bytes.SIZEOF_BOOLEAN, idx++) {
byte[] buf = new byte[Bytes.SIZEOF_BOOLEAN];
System.arraycopy(value, offset, buf, 0, Bytes.SIZEOF_BOOLEAN);
list.add(new Boolean(Bytes.toBoolean(buf)));
}
result = list;
}
break;
case Character:
if (!targetProperty.isMany())
result = Character.valueOf(Bytes.toString(value).charAt(0));
else
result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
break;
case Double:
if (!targetProperty.isMany()) {
result = Bytes.toDouble(value);
} else {
int count = value.length / Bytes.SIZEOF_DOUBLE;
List list = new ArrayList<>(count);
for (int offset = 0, idx = 0; offset < value.length; offset += Bytes.SIZEOF_DOUBLE, idx++) {
list.add(new Double(Bytes.toDouble(value, offset)));
}
result = list;
}
break;
case Float:
if (!targetProperty.isMany()) {
result = Bytes.toFloat(value);
} else {
int count = value.length / Bytes.SIZEOF_FLOAT;
List list = new ArrayList<>(count);
for (int offset = 0, idx = 0; offset < value.length; offset += Bytes.SIZEOF_FLOAT, idx++) {
list.add(new Float(Bytes.toFloat(value, offset)));
}
result = list;
}
break;
case Int:
if (!targetProperty.isMany()) {
result = Bytes.toInt(value);
} else {
int count = value.length / Bytes.SIZEOF_INT;
List list = new ArrayList<>(count);
for (int offset = 0, idx = 0; offset < value.length; offset += Bytes.SIZEOF_INT, idx++) {
list.add(new Integer(Bytes.toInt(value, offset, Bytes.SIZEOF_INT)));
}
result = list;
}
break;
case UnsignedInt:
if (!targetProperty.isMany()) {
result = UnsignedInteger.fromIntBits(Ints.fromByteArray(value));
} else {
int count = value.length / Bytes.SIZEOF_INT;
List list = new ArrayList<>(count);
for (int offset = 0, idx = 0; offset < value.length; offset += Bytes.SIZEOF_INT, idx++) {
byte[] bytes = new byte[Bytes.SIZEOF_INT];
System.arraycopy(value, offset, bytes, 0, bytes.length);
list.add(UnsignedInteger.fromIntBits(Ints.fromByteArray(bytes)));
}
result = list;
}
break;
case Integer:
if (!targetProperty.isMany())
result = new BigInteger(value);
else
result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
break;
case Long:
if (!targetProperty.isMany()) {
result = Bytes.toLong(value);
} else {
int count = value.length / Bytes.SIZEOF_LONG;
List list = new ArrayList<>(count);
for (int offset = 0, idx = 0; offset < value.length; offset += Bytes.SIZEOF_LONG, idx++) {
list.add(new Long(Bytes.toLong(value, offset, Bytes.SIZEOF_LONG)));
}
result = list;
}
break;
case UnsignedLong:
if (!targetProperty.isMany()) {
result = UnsignedLong.fromLongBits(Longs.fromByteArray(value));
} else {
int count = value.length / Bytes.SIZEOF_LONG;
List list = new ArrayList<>(count);
for (int offset = 0, idx = 0; offset < value.length; offset += Bytes.SIZEOF_LONG, idx++) {
byte[] bytes = new byte[Bytes.SIZEOF_LONG];
System.arraycopy(value, offset, bytes, 0, bytes.length);
list.add(UnsignedLong.fromLongBits(Ints.fromByteArray(bytes)));
}
result = list;
}
break;
case Short:
if (!targetProperty.isMany()) {
result = Bytes.toShort(value);
} else {
int count = value.length / Bytes.SIZEOF_SHORT;
List list = new ArrayList<>(count);
for (int offset = 0, idx = 0; offset < value.length; offset += Bytes.SIZEOF_SHORT, idx++) {
list.add(new Short(Bytes.toShort(value, offset, Bytes.SIZEOF_SHORT)));
}
result = list;
}
break;
case Object:
// FIXME: custom serialization?
default:
result = Bytes.toString(value);
break;
}
return result;
}
/*
* (non-Javadoc)
*
* @see
* org.cloudgraph.aerospike.service.DataConverter#toBytes(commonj.sdo.Property
* , java.lang.Object)
*/
public byte[] toBytes(Property sourceProperty, Object value) {
byte[] result;
if (!sourceProperty.getType().isDataType())
throw new IllegalArgumentException("property " + sourceProperty.toString()
+ " is not a datatype property");
DataType dataType = DataType.valueOf(sourceProperty.getType().getName());
switch (dataType) {
// Data types stored as String bytes in HBase
case String:
case Strings:
case URI:
case Month:
case MonthDay:
case Day:
case Time:
case Year:
case YearMonth:
case YearMonthDay:
case Date:
case Duration:
String resultStr = DataConverter.INSTANCE.toString(sourceProperty, value);
result = Bytes.toBytes(resultStr);
break;
case DateTime:
resultStr = DataConverter.INSTANCE.toString(sourceProperty, value);
result = Bytes.toBytes(resultStr);
break;
// Data types stored by directly converting from primitive types to
// bytes in HBase.
// FIXME: When the given property is a 'many' property and has a variable
// length, the value is first
// converted to String so
// can be delimited.
case Decimal:
if (!sourceProperty.isMany()) {
BigDecimal resultDecimal = DataConverter.INSTANCE
.toDecimal(sourceProperty.getType(), value);
result = Bytes.toBytes(resultDecimal);
} else {
String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
result = Bytes.toBytes(strResult);
}
break;
case Bytes:
if (!sourceProperty.isMany()) {
byte[] resultBytes = DataConverter.INSTANCE.toBytes(sourceProperty.getType(), value);
result = resultBytes;
} else {
String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
result = Bytes.toBytes(strResult);
}
break;
case Byte:
if (!sourceProperty.isMany()) {
byte resultByte = DataConverter.INSTANCE.toByte(sourceProperty.getType(), value);
result = Bytes.toBytes(resultByte);
} else {
result = (byte[]) value;
}
break;
case Boolean:
if (!sourceProperty.isMany()) {
boolean resultBool = DataConverter.INSTANCE.toBoolean(sourceProperty.getType(), value);
result = Bytes.toBytes(resultBool);
} else {
@SuppressWarnings("unchecked")
List list = (List) value;
result = new byte[list.size() * Bytes.SIZEOF_BOOLEAN];
int pos = 0;
for (Boolean val : list) {
byte[] bytesVal = Bytes.toBytes(val);
System.arraycopy(bytesVal, 0, result, pos, Bytes.SIZEOF_BOOLEAN);
pos += Bytes.SIZEOF_BOOLEAN;
}
}
break;
case Character:
if (!sourceProperty.isMany()) {
resultStr = DataConverter.INSTANCE.toString(sourceProperty.getType(), value);
result = Bytes.toBytes(resultStr);
} else {
String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
result = Bytes.toBytes(strResult);
}
break;
case Double:
if (!sourceProperty.isMany()) {
double resultDouble = DataConverter.INSTANCE.toDouble(sourceProperty.getType(), value);
result = Bytes.toBytes(resultDouble);
} else {
@SuppressWarnings("unchecked")
List list = (List) value;
result = new byte[list.size() * Bytes.SIZEOF_LONG];
int pos = 0;
for (Double val : list) {
byte[] bytesVal = Bytes.toBytes(val);
System.arraycopy(bytesVal, 0, result, pos, Bytes.SIZEOF_LONG);
pos += Bytes.SIZEOF_LONG;
}
}
break;
case Float:
if (!sourceProperty.isMany()) {
float resultFloat = DataConverter.INSTANCE.toFloat(sourceProperty.getType(), value);
result = Bytes.toBytes(resultFloat);
} else {
@SuppressWarnings("unchecked")
List list = (List) value;
result = new byte[list.size() * Bytes.SIZEOF_INT];
int pos = 0;
for (Float val : list) {
byte[] bytesVal = Bytes.toBytes(val);
System.arraycopy(bytesVal, 0, result, pos, Bytes.SIZEOF_INT);
pos += Bytes.SIZEOF_INT;
}
}
break;
case Int:
if (!sourceProperty.isMany()) {
int resultInt = DataConverter.INSTANCE.toInt(sourceProperty.getType(), value);
result = Bytes.toBytes(resultInt);
} else {
@SuppressWarnings("unchecked")
List list = (List) value;
result = new byte[list.size() * Bytes.SIZEOF_INT];
int pos = 0;
for (Integer val : list) {
byte[] bytesVal = Bytes.toBytes(val);
System.arraycopy(bytesVal, 0, result, pos, Bytes.SIZEOF_INT);
pos += Bytes.SIZEOF_INT;
}
}
break;
case UnsignedInt:
if (!sourceProperty.isMany()) {
UnsignedInteger resultInt = DataConverter.INSTANCE.toUnsignedInt(sourceProperty.getType(),
value);
result = Ints.toByteArray(resultInt.intValue());
} else {
@SuppressWarnings("unchecked")
List list = (List) value;
result = new byte[list.size() * Bytes.SIZEOF_INT];
int pos = 0;
for (UnsignedInteger val : list) {
byte[] bytesVal = Ints.toByteArray(val.intValue());
System.arraycopy(bytesVal, 0, result, pos, Bytes.SIZEOF_INT);
pos += Bytes.SIZEOF_INT;
}
}
break;
case Integer:
if (!sourceProperty.isMany()) {
BigInteger resultInteger = DataConverter.INSTANCE
.toInteger(sourceProperty.getType(), value);
result = resultInteger.toByteArray();
} else {
String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
result = Bytes.toBytes(strResult);
}
break;
case Long:
if (!sourceProperty.isMany()) {
long resultLong = DataConverter.INSTANCE.toLong(sourceProperty.getType(), value);
result = Bytes.toBytes(resultLong);
} else {
@SuppressWarnings("unchecked")
List list = (List) value;
result = new byte[list.size() * Bytes.SIZEOF_LONG];
int pos = 0;
for (Long val : list) {
byte[] bytesVal = Bytes.toBytes(val);
System.arraycopy(bytesVal, 0, result, pos, Bytes.SIZEOF_LONG);
pos += Bytes.SIZEOF_LONG;
}
}
break;
case UnsignedLong:
if (!sourceProperty.isMany()) {
UnsignedLong resultInt = DataConverter.INSTANCE.toUnsignedLong(sourceProperty.getType(),
value);
result = Longs.toByteArray(resultInt.longValue());
} else {
@SuppressWarnings("unchecked")
List list = (List) value;
result = new byte[list.size() * Bytes.SIZEOF_LONG];
int pos = 0;
for (UnsignedLong val : list) {
byte[] bytesVal = Longs.toByteArray(val.longValue());
System.arraycopy(bytesVal, 0, result, pos, Bytes.SIZEOF_LONG);
pos += Bytes.SIZEOF_LONG;
}
}
break;
case Short:
if (!sourceProperty.isMany()) {
short resultShort = DataConverter.INSTANCE.toShort(sourceProperty.getType(), value);
result = Bytes.toBytes(resultShort);
} else {
@SuppressWarnings("unchecked")
List list = (List) value;
result = new byte[list.size() * Bytes.SIZEOF_SHORT];
int pos = 0;
for (Short val : list) {
byte[] bytesVal = Bytes.toBytes(val);
System.arraycopy(bytesVal, 0, result, pos, Bytes.SIZEOF_SHORT);
pos += Bytes.SIZEOF_SHORT;
}
}
break;
case Object:
// FIXME: do we serialize objects in some custom format for
// hbase
default:
resultStr = DataConverter.INSTANCE.toString(sourceProperty.getType(), value);
result = Bytes.toBytes(resultStr);
break;
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy