blob: 130b37581b43b7dc6ca97e6eda58140fc7572c7a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.ignite.internal.binary;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.ignite.binary.BinaryObjectBuilder;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.util.GridConcurrentHashSet;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
/**
* Unit tests for serialized field comparer.
*/
public class BinarySerialiedFieldComparatorSelfTest extends GridCommonAbstractTest {
/** Type counter. */
private static final AtomicInteger TYPE_CTR = new AtomicInteger();
/** Single field name. */
private static final String FIELD_SINGLE = "single";
/** Pointers to release. */
private final Set<Long> ptrs = new GridConcurrentHashSet<>();
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();
startGrid();
}
/** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
super.beforeTest();
TYPE_CTR.incrementAndGet();
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
for (Long ptr : ptrs)
GridUnsafe.freeMemory(ptr);
super.afterTest();
}
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
cfg.setMarshaller(new BinaryMarshaller());
return cfg;
}
/**
* Test byte fields.
*
* @throws Exception If failed.
*/
@Test
public void testByte() throws Exception {
checkTwoValues((byte)1, (byte)2);
}
/**
* Test boolean fields.
*
* @throws Exception If failed.
*/
@Test
public void testBoolean() throws Exception {
checkTwoValues(true, false);
}
/**
* Test short fields.
*
* @throws Exception If failed.
*/
@Test
public void testShort() throws Exception {
checkTwoValues((short)1, (short)2);
}
/**
* Test char fields.
*
* @throws Exception If failed.
*/
@Test
public void testChar() throws Exception {
checkTwoValues('a', 'b');
}
/**
* Test int fields.
*
* @throws Exception If failed.
*/
@Test
public void testInt() throws Exception {
checkTwoValues(1, 2);
}
/**
* Test long fields.
*
* @throws Exception If failed.
*/
@Test
public void testLong() throws Exception {
checkTwoValues(1L, 2L);
}
/**
* Test float fields.
*
* @throws Exception If failed.
*/
@Test
public void testFloat() throws Exception {
checkTwoValues(1.0f, 2.0f);
}
/**
* Test double fields.
*
* @throws Exception If failed.
*/
@Test
public void testDouble() throws Exception {
checkTwoValues(1.0d, 2.0d);
}
/**
* Test string fields.
*
* @throws Exception If failed.
*/
@Test
public void testString() throws Exception {
checkTwoValues("str1", "str2");
}
/**
* Test date fields.
*
* @throws Exception If failed.
*/
@Test
public void testDate() throws Exception {
long time = System.currentTimeMillis();
checkTwoValues(new Date(time), new Date(time + 100));
}
/**
* Test date fields.
*
* @throws Exception If failed.
*/
@Test
public void testTimestamp() throws Exception {
long time = System.currentTimeMillis();
checkTwoValues(new Timestamp(time), new Timestamp(time + 100));
}
/**
* Test UUID fields.
*
* @throws Exception If failed.
*/
@Test
public void testUuid() throws Exception {
checkTwoValues(UUID.randomUUID(), UUID.randomUUID());
}
/**
* Test decimal fields.
*
* @throws Exception If failed.
*/
@Test
public void testDecimal() throws Exception {
checkTwoValues(new BigDecimal("12.3E+7"), new BigDecimal("12.4E+7"));
checkTwoValues(new BigDecimal("12.3E+7"), new BigDecimal("12.3E+8"));
}
/**
* Test object fields.
*
* @throws Exception If failed.
*/
@Test
public void testInnerObject() throws Exception {
checkTwoValues(new InnerClass(1), new InnerClass(2));
}
/**
* Test byte array fields.
*
* @throws Exception If failed.
*/
@Test
public void testByteArray() throws Exception {
checkTwoValues(new byte[] { 1, 2 }, new byte[] { 1, 3 });
checkTwoValues(new byte[] { 1, 2 }, new byte[] { 1 });
checkTwoValues(new byte[] { 1, 2 }, new byte[] { 3 });
checkTwoValues(new byte[] { 1, 2 }, new byte[] { 1, 2, 3 });
}
/**
* Test boolean array fields.
*
* @throws Exception If failed.
*/
@Test
public void testBooleanArray() throws Exception {
checkTwoValues(new boolean[] { true, false }, new boolean[] { false, true });
checkTwoValues(new boolean[] { true, false }, new boolean[] { true });
checkTwoValues(new boolean[] { true, false }, new boolean[] { false });
checkTwoValues(new boolean[] { true, false }, new boolean[] { true, false, true });
}
/**
* Test short array fields.
*
* @throws Exception If failed.
*/
@Test
public void testShortArray() throws Exception {
checkTwoValues(new short[] { 1, 2 }, new short[] { 1, 3 });
checkTwoValues(new short[] { 1, 2 }, new short[] { 1 });
checkTwoValues(new short[] { 1, 2 }, new short[] { 3 });
checkTwoValues(new short[] { 1, 2 }, new short[] { 1, 2, 3 });
}
/**
* Test char array fields.
*
* @throws Exception If failed.
*/
@Test
public void testCharArray() throws Exception {
checkTwoValues(new char[] { 1, 2 }, new char[] { 1, 3 });
checkTwoValues(new char[] { 1, 2 }, new char[] { 1 });
checkTwoValues(new char[] { 1, 2 }, new char[] { 3 });
checkTwoValues(new char[] { 1, 2 }, new char[] { 1, 2, 3 });
}
/**
* Test int array fields.
*
* @throws Exception If failed.
*/
@Test
public void testIntArray() throws Exception {
checkTwoValues(new int[] { 1, 2 }, new int[] { 1, 3 });
checkTwoValues(new int[] { 1, 2 }, new int[] { 1 });
checkTwoValues(new int[] { 1, 2 }, new int[] { 3 });
checkTwoValues(new int[] { 1, 2 }, new int[] { 1, 2, 3 });
}
/**
* Test long array fields.
*
* @throws Exception If failed.
*/
@Test
public void testLongArray() throws Exception {
checkTwoValues(new long[] { 1, 2 }, new long[] { 1, 3 });
checkTwoValues(new long[] { 1, 2 }, new long[] { 1 });
checkTwoValues(new long[] { 1, 2 }, new long[] { 3 });
checkTwoValues(new long[] { 1, 2 }, new long[] { 1, 2, 3 });
}
/**
* Test float array fields.
*
* @throws Exception If failed.
*/
@Test
public void testFloatArray() throws Exception {
checkTwoValues(new float[] { 1.0f, 2.0f }, new float[] { 1.0f, 3.0f });
checkTwoValues(new float[] { 1.0f, 2.0f }, new float[] { 1.0f });
checkTwoValues(new float[] { 1.0f, 2.0f }, new float[] { 3.0f });
checkTwoValues(new float[] { 1.0f, 2.0f }, new float[] { 1.0f, 2.0f, 3.0f });
}
/**
* Test double array fields.
*
* @throws Exception If failed.
*/
@Test
public void testDoubleArray() throws Exception {
checkTwoValues(new double[] { 1.0d, 2.0d }, new double[] { 1.0d, 3.0d });
checkTwoValues(new double[] { 1.0d, 2.0d }, new double[] { 1.0d });
checkTwoValues(new double[] { 1.0d, 2.0d }, new double[] { 3.0d });
checkTwoValues(new double[] { 1.0d, 2.0d }, new double[] { 1.0d, 2.0d, 3.0d });
}
/**
* Test string array fields.
*
* @throws Exception If failed.
*/
@Test
public void testStringArray() throws Exception {
checkTwoValues(new String[] { "a", "b" }, new String[] { "a", "c" });
checkTwoValues(new String[] { "a", "b" }, new String[] { "a" });
checkTwoValues(new String[] { "a", "b" }, new String[] { "c" });
checkTwoValues(new String[] { "a", "b" }, new String[] { "a", "b", "c" });
}
/**
* Test date array fields.
*
* @throws Exception If failed.
*/
@Test
public void testDateArray() throws Exception {
long curTime = System.currentTimeMillis();
Date v1 = new Date(curTime);
Date v2 = new Date(curTime + 1000);
Date v3 = new Date(curTime + 2000);
checkTwoValues(new Date[] { v1, v2 }, new Date[] { v1, v3 });
checkTwoValues(new Date[] { v1, v2 }, new Date[] { v1 });
checkTwoValues(new Date[] { v1, v2 }, new Date[] { v3 });
checkTwoValues(new Date[] { v1, v2 }, new Date[] { v1, v2, v3 });
}
/**
* Test timestamp array fields.
*
* @throws Exception If failed.
*/
@Test
public void testTimestampArray() throws Exception {
long curTime = System.currentTimeMillis();
Timestamp v1 = new Timestamp(curTime);
Timestamp v2 = new Timestamp(curTime + 1000);
Timestamp v3 = new Timestamp(curTime + 2000);
checkTwoValues(new Timestamp[] { v1, v2 }, new Timestamp[] { v1, v3 });
checkTwoValues(new Timestamp[] { v1, v2 }, new Timestamp[] { v1 });
checkTwoValues(new Timestamp[] { v1, v2 }, new Timestamp[] { v3 });
checkTwoValues(new Timestamp[] { v1, v2 }, new Timestamp[] { v1, v2, v3 });
}
/**
* Test UUID array fields.
*
* @throws Exception If failed.
*/
@Test
public void testUuidArray() throws Exception {
UUID v1 = UUID.randomUUID();
UUID v2 = UUID.randomUUID();
UUID v3 = UUID.randomUUID();
checkTwoValues(new UUID[] { v1, v2 }, new UUID[] { v1, v3 });
checkTwoValues(new UUID[] { v1, v2 }, new UUID[] { v1 });
checkTwoValues(new UUID[] { v1, v2 }, new UUID[] { v3 });
checkTwoValues(new UUID[] { v1, v2 }, new UUID[] { v1, v2, v3 });
}
/**
* Test decimal array fields.
*
* @throws Exception If failed.
*/
@Test
public void testDecimalArray() throws Exception {
BigDecimal v1 = new BigDecimal("12.3E+7");
BigDecimal v2 = new BigDecimal("12.4E+7");
BigDecimal v3 = new BigDecimal("12.5E+7");
checkTwoValues(new BigDecimal[] { v1, v2 }, new BigDecimal[] { v1, v3 });
checkTwoValues(new BigDecimal[] { v1, v2 }, new BigDecimal[] { v1 });
checkTwoValues(new BigDecimal[] { v1, v2 }, new BigDecimal[] { v3 });
checkTwoValues(new BigDecimal[] { v1, v2 }, new BigDecimal[] { v1, v2, v3 });
v2 = new BigDecimal("12.3E+8");
v3 = new BigDecimal("12.3E+9");
checkTwoValues(new BigDecimal[] { v1, v2 }, new BigDecimal[] { v1, v3 });
checkTwoValues(new BigDecimal[] { v1, v2 }, new BigDecimal[] { v1 });
checkTwoValues(new BigDecimal[] { v1, v2 }, new BigDecimal[] { v3 });
checkTwoValues(new BigDecimal[] { v1, v2 }, new BigDecimal[] { v1, v2, v3 });
}
/**
* Test object array fields.
*
* @throws Exception If failed.
*/
@Test
public void testInnerObjectArray() throws Exception {
InnerClass v1 = new InnerClass(1);
InnerClass v2 = new InnerClass(2);
InnerClass v3 = new InnerClass(3);
checkTwoValues(new InnerClass[] { v1, v2 }, new InnerClass[] { v1, v3 });
checkTwoValues(new InnerClass[] { v1, v2 }, new InnerClass[] { v1 });
checkTwoValues(new InnerClass[] { v1, v2 }, new InnerClass[] { v3 });
checkTwoValues(new InnerClass[] { v1, v2 }, new InnerClass[] { v1, v2, v3 });
}
/**
* Check two different not-null values.
*
* @throws Exception If failed.
*/
public void checkTwoValues(Object val1, Object val2) throws Exception {
checkTwoValues(val1, val2, false, false);
checkTwoValues(val1, val2, false, true);
checkTwoValues(val1, val2, true, false);
checkTwoValues(val1, val2, true, true);
}
/**
* Check two different not-null values.
*
* @param val1 Value 1.
* @param val2 Value 2.
* @param offheap1 Offheap flag 1.
* @param offheap2 Offheap flag 2.
* @throws Exception If failed.
*/
public void checkTwoValues(Object val1, Object val2, boolean offheap1, boolean offheap2) throws Exception {
assertNotNull(val1);
assertNotNull(val2);
compareSingle(convert(buildSingle(val1), offheap1), convert(buildSingle(val1), offheap2), true);
compareSingle(convert(buildSingle(val1), offheap1), convert(buildSingle(val2), offheap2), false);
compareSingle(convert(buildSingle(val1), offheap1), convert(buildSingle(null), offheap2), false);
compareSingle(convert(buildSingle(val1), offheap1), convert(buildEmpty(), offheap2), false);
compareSingle(convert(buildSingle(val2), offheap1), convert(buildSingle(val1), offheap2), false);
compareSingle(convert(buildSingle(val2), offheap1), convert(buildSingle(val2), offheap2), true);
compareSingle(convert(buildSingle(val2), offheap1), convert(buildSingle(null), offheap2), false);
compareSingle(convert(buildSingle(val2), offheap1), convert(buildEmpty(), offheap2), false);
compareSingle(convert(buildSingle(null), offheap1), convert(buildSingle(val1), offheap2), false);
compareSingle(convert(buildSingle(null), offheap1), convert(buildSingle(val2), offheap2), false);
compareSingle(convert(buildSingle(null), offheap1), convert(buildSingle(null), offheap2), true);
compareSingle(convert(buildSingle(null), offheap1), convert(buildEmpty(), offheap2), true);
compareSingle(convert(buildEmpty(), offheap1), convert(buildSingle(val1), offheap2), false);
compareSingle(convert(buildEmpty(), offheap1), convert(buildSingle(val2), offheap2), false);
compareSingle(convert(buildEmpty(), offheap1), convert(buildSingle(null), offheap2), true);
compareSingle(convert(buildEmpty(), offheap1), convert(buildEmpty(), offheap2), true);
}
/**
* Compare single field.
*
* @param first First object.
* @param second Second object.
* @param expRes Expected result.
*/
private void compareSingle(BinaryObjectExImpl first, BinaryObjectExImpl second, boolean expRes) {
BinarySerializedFieldComparator firstComp = first.createFieldComparator();
BinarySerializedFieldComparator secondComp = second.createFieldComparator();
// Compare expected result.
firstComp.findField(singleFieldOrder(first));
secondComp.findField(singleFieldOrder(second));
assertEquals(expRes, BinarySerializedFieldComparator.equals(firstComp, secondComp));
}
/**
* Get single field order.
*
* @param obj Object.
* @return Order.
*/
private int singleFieldOrder(BinaryObjectExImpl obj) {
return obj.hasField(FIELD_SINGLE) ? 0 : BinarySchema.ORDER_NOT_FOUND;
}
/**
* Convert binary object to it's final state.
*
* @param obj Object.
* @param offheap Offheap flag.
* @return Result.
*/
private BinaryObjectExImpl convert(BinaryObjectExImpl obj, boolean offheap) {
if (offheap) {
byte[] arr = obj.array();
long ptr = GridUnsafe.allocateMemory(arr.length);
ptrs.add(ptr);
GridUnsafe.copyMemory(arr, GridUnsafe.BYTE_ARR_OFF, null, ptr, arr.length);
obj = new BinaryObjectOffheapImpl(obj.context(), ptr, 0, obj.array().length);
}
return obj;
}
/**
* Build object with a single field.
*
* @param val Value.
* @return Result.
*/
private BinaryObjectImpl buildSingle(Object val) {
return build(FIELD_SINGLE, val);
}
/**
* Build empty object.
*
* @return Empty object.
*/
private BinaryObjectImpl buildEmpty() {
return build();
}
/**
* Build object.
*
* @param parts Parts.
* @return Result.
*/
private BinaryObjectImpl build(Object... parts) {
String typeName = "Type" + TYPE_CTR.get();
BinaryObjectBuilder builder = grid().binary().builder(typeName);
if (!F.isEmpty(parts)) {
for (int i = 0; i < parts.length; )
builder.setField((String)parts[i++], parts[i++]);
}
return (BinaryObjectImpl)builder.build();
}
/**
* Inner class.
*/
@SuppressWarnings("unused")
private static class InnerClass {
/** Value. */
private int val;
/**
* Constructor.
*
* @param val Value.
*/
public InnerClass(int val) {
this.val = val;
}
}
}