All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cloudgraph.rocksdb.service.RocksDBDataConverter Maven / Gradle / Ivy

Go to download

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