Repository: incubator-pirk Updated Branches: refs/heads/master c7fc6ec87 -> 712e25359
[PIRK-49] PrimitivePartioner does not account for locale settings - closes apache/incubator-pirk#57 Project: http://git-wip-us.apache.org/repos/asf/incubator-pirk/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-pirk/commit/712e2535 Tree: http://git-wip-us.apache.org/repos/asf/incubator-pirk/tree/712e2535 Diff: http://git-wip-us.apache.org/repos/asf/incubator-pirk/diff/712e2535 Branch: refs/heads/master Commit: 712e2535949390e1f4d3c81a64b34408af009913 Parents: c7fc6ec Author: tellison <[email protected]> Authored: Fri Aug 12 13:09:28 2016 -0400 Committer: eawilliams <[email protected]> Committed: Fri Aug 12 13:09:28 2016 -0400 ---------------------------------------------------------------------- .../data/partitioner/IPDataPartitioner.java | 21 +- .../partitioner/ISO8601DatePartitioner.java | 14 +- .../partitioner/PrimitiveTypePartitioner.java | 308 +++++++++---------- .../apache/pirk/general/PartitionUtilsTest.java | 64 +++- 4 files changed, 216 insertions(+), 191 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-pirk/blob/712e2535/src/main/java/org/apache/pirk/schema/data/partitioner/IPDataPartitioner.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pirk/schema/data/partitioner/IPDataPartitioner.java b/src/main/java/org/apache/pirk/schema/data/partitioner/IPDataPartitioner.java index f0c3e2e..84028c3 100644 --- a/src/main/java/org/apache/pirk/schema/data/partitioner/IPDataPartitioner.java +++ b/src/main/java/org/apache/pirk/schema/data/partitioner/IPDataPartitioner.java @@ -20,6 +20,7 @@ package org.apache.pirk.schema.data.partitioner; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.pirk.utils.SystemConfiguration; @@ -34,9 +35,9 @@ public class IPDataPartitioner implements DataPartitioner private static final long serialVersionUID = 1L; @Override - public ArrayList<BigInteger> toPartitions(Object object, String type) + public List<BigInteger> toPartitions(Object object, String type) { - ArrayList<BigInteger> parts = new ArrayList<>(); + List<BigInteger> parts = new ArrayList<>(4); String[] octets = ((String) object).split("\\."); for (String oct : octets) @@ -50,7 +51,7 @@ public class IPDataPartitioner implements DataPartitioner @Override public Object fromPartitions(List<BigInteger> parts, int partsIndex, String type) { - Object element; + String element; element = parts.get(partsIndex).toString() + "." + parts.get(partsIndex + 1).toString() + "." + parts.get(partsIndex + 2).toString() + "." + parts.get(partsIndex + 3).toString(); @@ -65,24 +66,18 @@ public class IPDataPartitioner implements DataPartitioner } @Override - public ArrayList<BigInteger> getPaddedPartitions(String type) + public List<BigInteger> getPaddedPartitions(String type) { - ArrayList<BigInteger> parts = new ArrayList<>(); - - for (int i = 0; i < 4; ++i) - { - parts.add(BigInteger.ZERO); - } - return parts; + return Arrays.asList(BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO); } /** * Create partitions for an array of the same type of elements - used when a data value field is an array and we wish to encode these into the return value */ @Override - public ArrayList<BigInteger> arrayToPartitions(List<?> elementList, String type) + public List<BigInteger> arrayToPartitions(List<?> elementList, String type) { - ArrayList<BigInteger> parts = new ArrayList<>(); + List<BigInteger> parts = new ArrayList<>(); int numArrayElementsToReturn = SystemConfiguration.getIntProperty("pir.numReturnArrayElements", 1); for (int i = 0; i < numArrayElementsToReturn; ++i) http://git-wip-us.apache.org/repos/asf/incubator-pirk/blob/712e2535/src/main/java/org/apache/pirk/schema/data/partitioner/ISO8601DatePartitioner.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pirk/schema/data/partitioner/ISO8601DatePartitioner.java b/src/main/java/org/apache/pirk/schema/data/partitioner/ISO8601DatePartitioner.java index e8d03bf..a2389bb 100644 --- a/src/main/java/org/apache/pirk/schema/data/partitioner/ISO8601DatePartitioner.java +++ b/src/main/java/org/apache/pirk/schema/data/partitioner/ISO8601DatePartitioner.java @@ -20,7 +20,6 @@ package org.apache.pirk.schema.data.partitioner; import java.math.BigInteger; import java.text.ParseException; -import java.util.ArrayList; import java.util.List; import org.apache.pirk.utils.ISO8601DateParser; @@ -35,15 +34,10 @@ public class ISO8601DatePartitioner implements DataPartitioner { private static final long serialVersionUID = 1L; - private PrimitiveTypePartitioner ptp = null; - - public ISO8601DatePartitioner() - { - ptp = new PrimitiveTypePartitioner(); - } + private final PrimitiveTypePartitioner ptp = new PrimitiveTypePartitioner(); @Override - public ArrayList<BigInteger> toPartitions(Object object, String type) throws PIRException + public List<BigInteger> toPartitions(Object object, String type) throws PIRException { long dateLongFormat; try @@ -72,13 +66,13 @@ public class ISO8601DatePartitioner implements DataPartitioner } @Override - public ArrayList<BigInteger> arrayToPartitions(List<?> elementList, String type) throws PIRException + public List<BigInteger> arrayToPartitions(List<?> elementList, String type) throws PIRException { return ptp.arrayToPartitions(elementList, PrimitiveTypePartitioner.LONG); } @Override - public ArrayList<BigInteger> getPaddedPartitions(String type) throws PIRException + public List<BigInteger> getPaddedPartitions(String type) throws PIRException { return ptp.getPaddedPartitions(PrimitiveTypePartitioner.LONG); } http://git-wip-us.apache.org/repos/asf/incubator-pirk/blob/712e2535/src/main/java/org/apache/pirk/schema/data/partitioner/PrimitiveTypePartitioner.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pirk/schema/data/partitioner/PrimitiveTypePartitioner.java b/src/main/java/org/apache/pirk/schema/data/partitioner/PrimitiveTypePartitioner.java index a2ac532..10ebefe 100644 --- a/src/main/java/org/apache/pirk/schema/data/partitioner/PrimitiveTypePartitioner.java +++ b/src/main/java/org/apache/pirk/schema/data/partitioner/PrimitiveTypePartitioner.java @@ -18,12 +18,11 @@ */ package org.apache.pirk.schema.data.partitioner; +import java.io.UnsupportedEncodingException; import java.math.BigInteger; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import org.apache.http.util.ByteArrayBuffer; import org.apache.pirk.utils.PIRException; import org.apache.pirk.utils.SystemConfiguration; import org.slf4j.Logger; @@ -48,22 +47,18 @@ public class PrimitiveTypePartitioner implements DataPartitioner public static final String CHAR = "char"; public static final String STRING = "string"; - // Default constructor - public PrimitiveTypePartitioner() - {} - /** * Splits the given BigInteger into partitions given by the partitionSize * */ - public static ArrayList<BigInteger> partitionBits(BigInteger value, int partitionSize, BigInteger mask) throws Exception + public static List<BigInteger> partitionBits(BigInteger value, int partitionSize, BigInteger mask) throws PIRException { if (mask.bitLength() != partitionSize) { - throw new Exception("mask.bitLength() " + mask.bitLength() + " != partitionSize = " + partitionSize); + throw new PIRException("mask.bitLength() " + mask.bitLength() + " != partitionSize = " + partitionSize); } - ArrayList<BigInteger> partitions = new ArrayList<>(); + List<BigInteger> partitions = new ArrayList<>(); if (value.bitLength() < partitionSize) { partitions.add(value); @@ -73,11 +68,10 @@ public class PrimitiveTypePartitioner implements DataPartitioner int bitLength = value.bitLength(); mask = mask.shiftLeft(bitLength - partitionSize); // shift left for big endian partitioning - BigInteger result; int partNum = 0; for (int i = 0; i < bitLength; i += partitionSize) { - result = value.and(mask); + BigInteger result = value.and(mask); int shiftSize = bitLength - (partNum + 1) * partitionSize; if (shiftSize < 0) // partitionSize does not divide bitLength, the remaining bits do not need shifting @@ -164,67 +158,74 @@ public class PrimitiveTypePartitioner implements DataPartitioner switch (type) { case BYTE: - BigInteger bInt = parts.get(partsIndex); - element = Byte.valueOf(bInt.toString()); + element = parts.get(partsIndex).byteValueExact(); break; case SHORT: { - byte[] bytes = appendBytes(parts, partsIndex, getNumPartitions(type)); - element = ByteBuffer.wrap(bytes).getShort(); + byte[] bytes = partsToBytes(parts, partsIndex, type); + element = bytesToShort(bytes); break; } case INT: { - byte[] bytes = appendBytes(parts, partsIndex, getNumPartitions(type)); - element = ByteBuffer.wrap(bytes).getInt(); + byte[] bytes = partsToBytes(parts, partsIndex, type); + element = bytesToInt(bytes); break; } case LONG: { - byte[] bytes = appendBytes(parts, partsIndex, getNumPartitions(type)); - element = ByteBuffer.wrap(bytes).getLong(); + byte[] bytes = partsToBytes(parts, partsIndex, type); + element = bytesToLong(bytes); break; } case FLOAT: { - byte[] bytes = appendBytes(parts, partsIndex, getNumPartitions(type)); - element = ByteBuffer.wrap(bytes).getFloat(); + byte[] bytes = partsToBytes(parts, partsIndex, type); + element = Float.intBitsToFloat(bytesToInt(bytes)); break; } case DOUBLE: { - byte[] bytes = appendBytes(parts, partsIndex, getNumPartitions(type)); - element = ByteBuffer.wrap(bytes).getDouble(); + byte[] bytes = partsToBytes(parts, partsIndex, type); + element = Double.longBitsToDouble(bytesToLong(bytes)); break; } case CHAR: { - byte[] bytes = appendBytes(parts, partsIndex, getNumPartitions(type)); - element = ByteBuffer.wrap(bytes).getChar(); + byte[] bytes = partsToBytes(parts, partsIndex, type); + element = (char) bytesToShort(bytes); break; } case STRING: { - byte[] bytes = appendBytes(parts, partsIndex, getNumPartitions(type)); - element = new String(bytes).trim(); // this should remove 0 padding added for partitioning underflowing strings + byte[] bytes = partsToBytes(parts, partsIndex, type); + try + { + // This should remove 0 padding added for partitioning underflowing strings. + element = new String(bytes, "UTF-8").trim(); + } catch (UnsupportedEncodingException e) + { + // UTF-8 is a required encoding. + throw new RuntimeException(e); + } break; } default: throw new PIRException("type = " + type + " not recognized!"); } + return element; } - private byte[] appendBytes(List<BigInteger> parts, int partsIndex, int numParts) + private byte[] partsToBytes(List<BigInteger> parts, int partsIndex, String type) throws PIRException { - ByteArrayBuffer buf = new ByteArrayBuffer(numParts); + int numParts = getNumPartitions(type); + byte[] result = new byte[numParts]; for (int i = 0; i < numParts; ++i) { - byte partByte = parts.get(partsIndex + i).byteValue(); - buf.append(partByte); + result[i] = parts.get(partsIndex + i).byteValue(); } - - return buf.buffer(); + return result; } /** @@ -236,107 +237,69 @@ public class PrimitiveTypePartitioner implements DataPartitioner { ArrayList<BigInteger> parts = new ArrayList<>(); - int numParts = getNumPartitions(type); + byte[] bytes = new byte[0]; + switch (type) { case BYTE: - if (obj instanceof String) + byte value = obj instanceof String ? Byte.parseByte((String) obj) : (byte) obj; + bytes = new byte[] {value}; + break; + case CHAR: + char cvalue = obj instanceof String ? ((String) obj).charAt(0) : (char) obj; + bytes = shortToBytes((short) cvalue); + break; + case SHORT: + short svalue = obj instanceof String ? Short.parseShort((String) obj) : (short) obj; + bytes = shortToBytes(svalue); + break; + case INT: + int ivalue = obj instanceof String ? Integer.parseInt((String) obj) : (int) obj; + bytes = intToBytes(ivalue); + break; + case LONG: + long lvalue = obj instanceof String ? Long.parseLong((String) obj) : (long) obj; + bytes = longToBytes(lvalue); + break; + case FLOAT: + float fvalue = obj instanceof String ? Float.parseFloat((String) obj) : (float) obj; + bytes = intToBytes(Float.floatToRawIntBits(fvalue)); + break; + case DOUBLE: + double dvalue = obj instanceof String ? Double.parseDouble((String) obj) : (double) obj; + bytes = longToBytes(Double.doubleToRawLongBits(dvalue)); + break; + case STRING: + byte[] stringBytes; + try { - parts.add(new BigInteger(ByteBuffer.allocate(1).put(Byte.parseByte((String) obj)).array())); - } - else + stringBytes = ((String) obj).getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { - parts.add(new BigInteger(ByteBuffer.allocate(1).put((byte) obj).array())); + // UTF-8 is a required encoding. + throw new RuntimeException(e); } - break; - case STRING: - byte[] stringBytes = ((String) obj).getBytes(); - for (int i = 0; i < numParts; ++i) + for (int i = 0; i < getNumPartitions(STRING); ++i) { if (i < stringBytes.length) { - parts.add(new BigInteger(ByteBuffer.allocate(1).put(stringBytes[i]).array())); + parts.add(BigInteger.valueOf((long) stringBytes[i] & 0xFF)); } else { - parts.add(new BigInteger(ByteBuffer.allocate(1).put(Byte.parseByte("0")).array())); + parts.add(BigInteger.ZERO); } } break; default: - // Extract the byte array - byte[] bytes = new byte[0]; - switch (type) - { - case SHORT: - if (obj instanceof String) - { - bytes = ByteBuffer.allocate(numParts).putShort(Short.parseShort((String) obj)).array(); - } - else - { - bytes = ByteBuffer.allocate(numParts).putShort((short) obj).array(); - } - break; - case INT: - if (obj instanceof String) - { - bytes = ByteBuffer.allocate(numParts).putInt(Integer.parseInt((String) obj)).array(); - } - else - { - bytes = ByteBuffer.allocate(numParts).putInt((int) obj).array(); - } - break; - case LONG: - if (obj instanceof String) - { - bytes = ByteBuffer.allocate(numParts).putLong(Long.parseLong((String) obj)).array(); - } - else - { - bytes = ByteBuffer.allocate(numParts).putLong((long) obj).array(); - } - break; - case FLOAT: - if (obj instanceof String) - { - bytes = ByteBuffer.allocate(numParts).putFloat(Float.parseFloat((String) obj)).array(); - } - else - { - bytes = ByteBuffer.allocate(numParts).putFloat((float) obj).array(); - } - break; - case DOUBLE: - if (obj instanceof String) - { - bytes = ByteBuffer.allocate(numParts).putDouble(Double.parseDouble((String) obj)).array(); - } - else - { - bytes = ByteBuffer.allocate(numParts).putDouble((double) obj).array(); - } - break; - case CHAR: - if (obj instanceof String) - { - bytes = ByteBuffer.allocate(numParts).putChar(((String) obj).charAt(0)).array(); - } - else - { - bytes = ByteBuffer.allocate(numParts).putChar((char) obj).array(); - } - break; - } + throw new PIRException("type = " + type + " not recognized!"); + } - // Add bytes to parts ArrayList - for (byte b : bytes) - { - // Make sure that BigInteger treats the byte as 'unsigned' literal - parts.add(BigInteger.valueOf((long) b & 0xFF)); - } - break; + // Add any bytes to parts list. + for (byte b : bytes) + { + // Make sure that BigInteger treats the byte as 'unsigned' literal + parts.add(BigInteger.valueOf((long) b & 0xFF)); } return parts; @@ -346,53 +309,14 @@ public class PrimitiveTypePartitioner implements DataPartitioner * Method to get an empty set of partitions by data type - used for padding return array values */ @Override - public ArrayList<BigInteger> getPaddedPartitions(String type) throws PIRException + public List<BigInteger> getPaddedPartitions(String type) throws PIRException { - ArrayList<BigInteger> parts = new ArrayList<>(); - int numParts = getNumPartitions(type); - switch (type) - { - case BYTE: - parts.add(new BigInteger(ByteBuffer.allocate(1).put(Byte.parseByte("0")).array())); - break; - case STRING: - for (int i = 0; i < numParts; ++i) - { - parts.add(new BigInteger(ByteBuffer.allocate(1).put(Byte.parseByte("0")).array())); - } - break; - default: - // Extract the byte array - byte[] bytes = new byte[0]; - switch (type) - { - case SHORT: - bytes = ByteBuffer.allocate(numParts).putShort(Short.parseShort("0")).array(); - break; - case INT: - bytes = ByteBuffer.allocate(numParts).putInt(Integer.parseInt("0")).array(); - break; - case LONG: - bytes = ByteBuffer.allocate(numParts).putLong(Long.parseLong("0")).array(); - break; - case FLOAT: - bytes = ByteBuffer.allocate(numParts).putFloat(Float.parseFloat("0")).array(); - break; - case DOUBLE: - bytes = ByteBuffer.allocate(numParts).putDouble(Double.parseDouble("0")).array(); - break; - case CHAR: - bytes = ByteBuffer.allocate(numParts).putChar('0').array(); - break; - } - // Add bytes to parts ArrayList - for (byte b : bytes) - { - parts.add(new BigInteger(ByteBuffer.allocate(1).put(b).array())); - } - break; + List<BigInteger> parts = new ArrayList<>(numParts); + for (int i = 0; i < numParts; i++) + { + parts.add(BigInteger.ZERO); } return parts; } @@ -414,11 +338,71 @@ public class PrimitiveTypePartitioner implements DataPartitioner parts.addAll(toPartitions(elementList.get(i), type)); } else - // pad with encryptions of zero { + // Pad with encryptions of zero. parts.addAll(getPaddedPartitions(type)); } } return parts; } + + // Helpers to return the given numbers in network byte order representation. + + private byte[] shortToBytes(short value) + { + return new byte[] { + (byte) (value >> 8), + (byte) value}; + } + + private short bytesToShort(byte[] bytes) + { + return (short)( + bytes[0] << 8 | + bytes[1] & 0xff); + } + + private byte[] intToBytes(int value) + { + return new byte[] { + (byte) (value >> 24), + (byte) (value >> 16), + (byte) (value >> 8), + (byte) value}; + } + + private int bytesToInt(byte[] bytes) + { + return + (bytes[0] << 24) | + (bytes[1] & 0xff) << 16 | + (bytes[2] & 0xff) << 8 | + (bytes[3] & 0xff); + } + + private byte[] longToBytes(long value) + { + return new byte[] { + (byte) (value >> 56), + (byte) (value >> 48), + (byte) (value >> 40), + (byte) (value >> 32), + (byte) (value >> 24), + (byte) (value >> 16), + (byte) (value >> 8), + (byte) value}; + } + + private long bytesToLong(byte[] bytes) + { + return + (long)bytes[0] << 56 | + ((long)bytes[1] & 0xff) << 48 | + ((long)bytes[2] & 0xff) << 40 | + ((long)bytes[3] & 0xff) << 32 | + ((long)bytes[4] & 0xff) << 24 | + ((long)bytes[5] & 0xff) << 16 | + ((long)bytes[6] & 0xff) << 8 | + (long)bytes[7] & 0xff; + } } http://git-wip-us.apache.org/repos/asf/incubator-pirk/blob/712e2535/src/test/java/org/apache/pirk/general/PartitionUtilsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/pirk/general/PartitionUtilsTest.java b/src/test/java/org/apache/pirk/general/PartitionUtilsTest.java index 4c1495d..45f20bf 100644 --- a/src/test/java/org/apache/pirk/general/PartitionUtilsTest.java +++ b/src/test/java/org/apache/pirk/general/PartitionUtilsTest.java @@ -23,10 +23,13 @@ import static org.junit.Assert.fail; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.apache.pirk.schema.data.partitioner.IPDataPartitioner; import org.apache.pirk.schema.data.partitioner.ISO8601DatePartitioner; import org.apache.pirk.schema.data.partitioner.PrimitiveTypePartitioner; +import org.apache.pirk.utils.PIRException; import org.apache.pirk.utils.SystemConfiguration; import org.junit.Test; import org.slf4j.Logger; @@ -64,7 +67,7 @@ public class PartitionUtilsTest try { - ArrayList<BigInteger> partitions = PrimitiveTypePartitioner.partitionBits(value, 4, mask4); + List<BigInteger> partitions = PrimitiveTypePartitioner.partitionBits(value, 4, mask4); assertEquals(2, partitions.size()); assertEquals(partitions.get(0).intValue(), 15); // 1111 @@ -77,7 +80,7 @@ public class PartitionUtilsTest try { - ArrayList<BigInteger> partitions = PrimitiveTypePartitioner.partitionBits(value2, 4, mask4); + List<BigInteger> partitions = PrimitiveTypePartitioner.partitionBits(value2, 4, mask4); assertEquals(3, partitions.size()); assertEquals(partitions.get(0).intValue(), 15); // 1111 @@ -90,7 +93,7 @@ public class PartitionUtilsTest } try { - ArrayList<BigInteger> partitions = PrimitiveTypePartitioner.partitionBits(value, 8, mask8); + List<BigInteger> partitions = PrimitiveTypePartitioner.partitionBits(value, 8, mask8); assertEquals(1, partitions.size()); assertEquals(partitions.get(0).intValue(), 245); @@ -102,7 +105,7 @@ public class PartitionUtilsTest try { - ArrayList<BigInteger> partitions = PrimitiveTypePartitioner.partitionBits(value, 4, mask8); + List<BigInteger> partitions = PrimitiveTypePartitioner.partitionBits(value, 4, mask8); fail("BitConversionUtils.partitionBits did not throw error for mismatched partitionSize and mask size"); @@ -123,13 +126,13 @@ public class PartitionUtilsTest // Test IP String ipTest = "127.0.0.1"; - ArrayList<BigInteger> partsIP = ipPartitioner.toPartitions(ipTest, PrimitiveTypePartitioner.STRING); + List<BigInteger> partsIP = ipPartitioner.toPartitions(ipTest, PrimitiveTypePartitioner.STRING); assertEquals(4, partsIP.size()); assertEquals(ipTest, ipPartitioner.fromPartitions(partsIP, 0, PrimitiveTypePartitioner.STRING)); // Test Date String dateTest = "2016-02-20T23:29:05.000Z"; - ArrayList<BigInteger> partsDate = datePartitioner.toPartitions(dateTest, null); + List<BigInteger> partsDate = datePartitioner.toPartitions(dateTest, null); assertEquals(8, partsDate.size()); assertEquals(dateTest, datePartitioner.fromPartitions(partsDate, 0, null)); @@ -139,6 +142,10 @@ public class PartitionUtilsTest assertEquals(1, partsByte.size()); assertEquals(bTest, primitivePartitioner.fromPartitions(partsByte, 0, PrimitiveTypePartitioner.BYTE)); + partsByte = primitivePartitioner.toPartitions("12", PrimitiveTypePartitioner.BYTE); + assertEquals(1, partsByte.size()); + assertEquals((byte)12, primitivePartitioner.fromPartitions(partsByte, 0, PrimitiveTypePartitioner.BYTE)); + ArrayList<BigInteger> partsByteMax = primitivePartitioner.toPartitions(Byte.MAX_VALUE, PrimitiveTypePartitioner.BYTE); assertEquals(1, partsByteMax.size()); assertEquals(Byte.MAX_VALUE, primitivePartitioner.fromPartitions(partsByteMax, 0, PrimitiveTypePartitioner.BYTE)); @@ -156,6 +163,14 @@ public class PartitionUtilsTest assertEquals(2, partsShort.size()); assertEquals(shortTest, primitivePartitioner.fromPartitions(partsShort, 0, PrimitiveTypePartitioner.SHORT)); + partsShort = primitivePartitioner.toPartitions("32767", PrimitiveTypePartitioner.SHORT); + assertEquals(2, partsShort.size()); + assertEquals((short)32767, primitivePartitioner.fromPartitions(partsShort, 0, PrimitiveTypePartitioner.SHORT)); + + partsShort = primitivePartitioner.toPartitions((short) -42, PrimitiveTypePartitioner.SHORT); + assertEquals(2, partsShort.size()); + assertEquals((short) -42, primitivePartitioner.fromPartitions(partsShort, 0, PrimitiveTypePartitioner.SHORT)); + ArrayList<BigInteger> partsShortMax = primitivePartitioner.toPartitions(Short.MAX_VALUE, PrimitiveTypePartitioner.SHORT); assertEquals(2, partsShortMax.size()); assertEquals(Short.MAX_VALUE, primitivePartitioner.fromPartitions(partsShortMax, 0, PrimitiveTypePartitioner.SHORT)); @@ -166,6 +181,14 @@ public class PartitionUtilsTest assertEquals(4, partsInt.size()); assertEquals(intTest, primitivePartitioner.fromPartitions(partsInt, 0, PrimitiveTypePartitioner.INT)); + partsInt = primitivePartitioner.toPartitions("2016", PrimitiveTypePartitioner.INT); + assertEquals(4, partsInt.size()); + assertEquals(2016, primitivePartitioner.fromPartitions(partsInt, 0, PrimitiveTypePartitioner.INT)); + + partsInt = primitivePartitioner.toPartitions(1386681237, PrimitiveTypePartitioner.INT); + assertEquals(4, partsInt.size()); + assertEquals(1386681237, primitivePartitioner.fromPartitions(partsInt, 0, PrimitiveTypePartitioner.INT)); + ArrayList<BigInteger> partsIntMax = primitivePartitioner.toPartitions(Integer.MAX_VALUE, PrimitiveTypePartitioner.INT); assertEquals(4, partsIntMax.size()); assertEquals(Integer.MAX_VALUE, primitivePartitioner.fromPartitions(partsIntMax, 0, PrimitiveTypePartitioner.INT)); @@ -186,6 +209,10 @@ public class PartitionUtilsTest assertEquals(4, partsFloat.size()); assertEquals(floatTest, primitivePartitioner.fromPartitions(partsFloat, 0, PrimitiveTypePartitioner.FLOAT)); + partsFloat = primitivePartitioner.toPartitions(-99.99f, PrimitiveTypePartitioner.FLOAT); + assertEquals(4, partsFloat.size()); + assertEquals(-99.99f, primitivePartitioner.fromPartitions(partsFloat, 0, PrimitiveTypePartitioner.FLOAT)); + ArrayList<BigInteger> partsFloatMax = primitivePartitioner.toPartitions(Float.MAX_VALUE, PrimitiveTypePartitioner.FLOAT); assertEquals(4, partsFloatMax.size()); assertEquals(Float.MAX_VALUE, primitivePartitioner.fromPartitions(partsFloatMax, 0, PrimitiveTypePartitioner.FLOAT)); @@ -206,6 +233,17 @@ public class PartitionUtilsTest assertEquals(2, partsChar.size()); assertEquals(charTest, primitivePartitioner.fromPartitions(partsChar, 0, PrimitiveTypePartitioner.CHAR)); + // Ensure Endianness preserved + charTest = '\uFFFE'; + partsChar = primitivePartitioner.toPartitions(charTest, PrimitiveTypePartitioner.CHAR); + assertEquals(2, partsChar.size()); + assertEquals(charTest, primitivePartitioner.fromPartitions(partsChar, 0, PrimitiveTypePartitioner.CHAR)); + + charTest = '\uFEFF'; + partsChar = primitivePartitioner.toPartitions(charTest, PrimitiveTypePartitioner.CHAR); + assertEquals(2, partsChar.size()); + assertEquals(charTest, primitivePartitioner.fromPartitions(partsChar, 0, PrimitiveTypePartitioner.CHAR)); + ArrayList<BigInteger> partsCharMax = primitivePartitioner.toPartitions(Character.MAX_VALUE, PrimitiveTypePartitioner.CHAR); assertEquals(2, partsCharMax.size()); assertEquals(Character.MAX_VALUE, primitivePartitioner.fromPartitions(partsCharMax, 0, PrimitiveTypePartitioner.CHAR)); @@ -213,6 +251,20 @@ public class PartitionUtilsTest logger.info("Sucessfully completed testToPartitions:"); } + @Test + public void testPaddedPartitions() throws PIRException + { + PrimitiveTypePartitioner primitivePartitioner = new PrimitiveTypePartitioner(); + + List<String> primitiveTypes = Arrays.asList(PrimitiveTypePartitioner.BYTE, PrimitiveTypePartitioner.CHAR, PrimitiveTypePartitioner.SHORT, + PrimitiveTypePartitioner.INT, PrimitiveTypePartitioner.LONG, PrimitiveTypePartitioner.FLOAT, PrimitiveTypePartitioner.DOUBLE, + PrimitiveTypePartitioner.STRING); + for (String type : primitiveTypes) + { + assertEquals(primitivePartitioner.getNumPartitions(type), primitivePartitioner.getPaddedPartitions(type).size()); + } + } + private void testString(String testString) throws Exception { PrimitiveTypePartitioner ptp = new PrimitiveTypePartitioner();
