/** Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Created on Oct 29, 2015 */ package com.bigdata.rdf.internal.impl.literal; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; import org.openrdf.model.Literal; import org.openrdf.model.URI; import org.openrdf.model.impl.URIImpl; import com.bigdata.io.LongPacker; import com.bigdata.rdf.internal.DTE; import com.bigdata.rdf.internal.DTEExtension; import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.lexicon.LexiconRelation; import com.bigdata.rdf.model.BigdataLiteral; /** * Internal value representing a packed long in the range [0;72057594037927935L]. * Note that this is not the full range of long (negative values are not * supported and positive long values in [72057594037927936L;Long.MAX] * are not supported), the reason being that the compression technique * we're using is order preserving only for the valid range. */ public class PackedLongIV<V extends BigdataLiteral> extends AbstractLiteralIV<V, Long> implements Serializable, Literal { private static final long serialVersionUID = 925868533758851987L; // private static final transient Logger log = Logger.getLogger(CompressedTimestampIV.class); public static final URI PACKED_LONG = new URIImpl("http://www.bigdata.com/rdf/datatype#packedLong"); /** * The {@link PackedLongIV} uses the {@link LongPacker} to compress values. * {@link LongPacker#packLong(long, byte[], com.bigdata.io.LongPacker.IByteBuffer)} * is order preserving whenever the first byte is 0. Since the IV relies on an * order preserving encoding, we restrict the supported range to values in * [0;MAX_POS_LONG_WITH_LEADING_ZERO_BYTE], where MAX_POS_LONG_WITH_LEADING_ZERO_BYTE * corresponds to the 64bit string 00000000111111111111111..., which equals * 72057594037927935L. The value was (statically) verified as follows: * <code> long v1 = 72057594037927935L; long v2 = 72057594037927936L; System.out.println(( ( v1 >> 56 ) != 0 )); // condition used in LongPacker System.out.println(( ( v2 >> 56 ) != 0 )); // condition used in LongPacker </code> * outputs "false" followed by "true". */ public static final long MAX_POS_LONG_WITH_LEADING_ZERO_BYTE = 72057594037927935L; /** * The represented value */ private final long value; /** * The cached materialized BigdataValue for this InetAddress. */ private transient V literal; @Override public IV<V, Long> clone(final boolean clearCache) { final PackedLongIV<V> tmp = new PackedLongIV<V>(value); if (!clearCache) { tmp.setValue(getValueCache()); } return tmp; } /** * Ctor with string value specified. */ public PackedLongIV(final String value) { this(Long.valueOf(value)); } /** * Ctor with internal value specified. */ public PackedLongIV(final long value) { super(DTE.Extension); if (value<0 || value>MAX_POS_LONG_WITH_LEADING_ZERO_BYTE) { throw new IllegalArgumentException("long value out of range: " + value); } this.value = value; } /** * Returns the inline value. */ @Override public Long getInlineValue() throws UnsupportedOperationException { return value; } /** * Returns the Literal representation of this IV. */ @SuppressWarnings("unchecked") public V asValue(final LexiconRelation lex) { if (literal == null) { literal = (V) lex.getValueFactory().createLiteral(getLabel(), PACKED_LONG); literal.setIV(this); } return literal; } /** * Return the byte length for the byte[] encoded representation of this * internal value. Depends on the byte length of the encoded inline value. */ @Override public int byteLength() { return 1 /* flags */ + 1 /* DTEExtension */ + LongPacker.getByteLength(value); } @Override public String toString() { return String.valueOf(value); } @Override public int hashCode() { return (int)value; } @Override public String getLabel() { return String.valueOf(value); } /** * Two {@link PackedLongIV} are equal if their InetAddresses are equal. */ @Override public boolean equals(final Object o) { if (this == o) return true; if (o instanceof PackedLongIV) { return value==((PackedLongIV<?>) o).value; } return false; } @Override @SuppressWarnings("rawtypes") public int _compareTo(IV o) { if (value < ((PackedLongIV<?>)o).value) { return -1; } else if (value>((PackedLongIV<?>)o).value) { return 1; } else { return 0; } } @Override public DTEExtension getDTEX() { return DTEExtension.PACKED_LONG; } /** * Implement {@link Literal#booleanValue()}. */ @Override public boolean booleanValue() { return value>0; } /** * Implement {@link Literal#shortValue()}. */ @Override public short shortValue() { return (short)value; } /** * Implement {@link Literal#intValue()}. */ @Override public int intValue() { return (int)value; } /** * Implement {@link Literal#longValue()}. */ @Override public long longValue() { return value; } /** * Implement {@link Literal#floatValue()}. */ @Override public float floatValue() { return (float)value; } /** * Implement {@link Literal#doubleValue()}. */ @Override public double doubleValue() { return (double)value; } /** * Implement {@link Literal#integerValue()}. */ @Override public BigInteger integerValue() { return BigInteger.valueOf(value); } /** * Implement {@link Literal#decimalValue()}. */ @Override public BigDecimal decimalValue() { return BigDecimal.valueOf(value); } }