Page memory WIP.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ddfe632e Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ddfe632e Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ddfe632e Branch: refs/heads/sql-store-cmp Commit: ddfe632e20c9b13fb0e06490088d007abe1bac1b Parents: 500bd3a Author: Alexey Goncharuk <alexey.goncha...@gmail.com> Authored: Tue Jan 19 18:58:36 2016 +0300 Committer: Alexey Goncharuk <alexey.goncha...@gmail.com> Committed: Wed Feb 3 17:13:40 2016 +0300 ---------------------------------------------------------------------- .../ignite/internal/binary/BinaryContext.java | 2 +- .../ignite/internal/binary/BinaryFieldEx.java | 45 +++ .../ignite/internal/binary/BinaryFieldImpl.java | 173 ++++++++++- .../internal/binary/BinaryObjectExImpl.java | 10 + .../internal/binary/BinaryObjectImpl.java | 116 ++++++++ .../binary/BinaryObjectOffheapImpl.java | 5 + .../streams/BinaryByteBufferInputStream.java | 291 +++++++++++++++++++ .../binary/BinaryFieldExtractionSelfTest.java | 161 ++++++++++ 8 files changed, 800 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ddfe632e/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java index cf19bdf..35723df 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java @@ -1010,7 +1010,7 @@ public class BinaryContext { int fieldId = mapper.fieldId(typeId, fieldName); - return new BinaryFieldImpl(typeId, schemaReg, fieldName, fieldId); + return new BinaryFieldImpl(this, typeId, schemaReg, fieldName, fieldId); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/ddfe632e/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldEx.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldEx.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldEx.java new file mode 100644 index 0000000..42aa282 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldEx.java @@ -0,0 +1,45 @@ +/* + * 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.nio.ByteBuffer; +import org.apache.ignite.binary.BinaryField; +import org.apache.ignite.binary.BinaryObject; + +/** + * + */ +public interface BinaryFieldEx extends BinaryField { + /** + * Writes field value to the given byte buffer. + * + * @param obj Object from which the field should be extracted. + * @param buf Buffer to write the field value to. + * @return {@code True} if the value was successfully written, {@code false} if there is not enough space + * for the field in the buffer. + */ + public boolean writeField(BinaryObject obj, ByteBuffer buf); + + /** + * Reads field value from the given byte buffer. + * + * @param buf Buffer to read value from. + * @return Field value. + */ + public <F> F readField(ByteBuffer buf); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ddfe632e/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java index 78ed17a..4b59904 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldImpl.java @@ -17,16 +17,29 @@ package org.apache.ignite.internal.binary; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.sql.Timestamp; +import java.util.Date; +import java.util.UUID; import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.internal.binary.streams.BinaryByteBufferInputStream; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.binary.BinaryField; +import static java.nio.charset.StandardCharsets.UTF_8; + /** * Implementation of binary field descriptor. */ -public class BinaryFieldImpl implements BinaryField { +public class BinaryFieldImpl implements BinaryFieldEx { + /** Binary context that created this field. */ + private final BinaryContext ctx; + /** Type ID. */ private final int typeId; @@ -47,12 +60,20 @@ public class BinaryFieldImpl implements BinaryField { * @param fieldName Field name. * @param fieldId Field ID. */ - public BinaryFieldImpl(int typeId, BinarySchemaRegistry schemas, String fieldName, int fieldId) { + public BinaryFieldImpl( + BinaryContext ctx, + int typeId, + BinarySchemaRegistry schemas, + String fieldName, + int fieldId + ) { + assert ctx != null; assert typeId != 0; assert schemas != null; assert fieldName != null; assert fieldId != 0; + this.ctx = ctx; this.typeId = typeId; this.schemas = schemas; this.fieldName = fieldName; @@ -81,6 +102,154 @@ public class BinaryFieldImpl implements BinaryField { return order != BinarySchema.ORDER_NOT_FOUND ? (T)obj0.fieldByOrder(order) : null; } + /** {@inheritDoc} */ + @Override public boolean writeField(BinaryObject obj, ByteBuffer buf) { + BinaryObjectExImpl obj0 = (BinaryObjectExImpl)obj; + + int order = fieldOrder(obj0); + + return obj0.writeFieldByOrder(order, buf); + } + + /** {@inheritDoc} */ + @Override public <F> F readField(ByteBuffer buf) { + ByteOrder oldOrder = buf.order(); + + try { + buf.order(ByteOrder.LITTLE_ENDIAN); + + int pos = buf.position(); + + byte hdr = buf.get(); + + Object val; + + switch (hdr) { + case GridBinaryMarshaller.INT: + val = buf.getInt(); + + break; + + case GridBinaryMarshaller.LONG: + val = buf.getLong(); + + break; + + case GridBinaryMarshaller.BOOLEAN: + val = buf.get() != 0; + + break; + + case GridBinaryMarshaller.SHORT: + val = buf.getShort(); + + break; + + case GridBinaryMarshaller.BYTE: + val = buf.get(); + + break; + + case GridBinaryMarshaller.CHAR: + val = buf.getChar(); + + break; + + case GridBinaryMarshaller.FLOAT: + val = buf.getFloat(); + + break; + + case GridBinaryMarshaller.DOUBLE: + val = buf.getDouble(); + + break; + + case GridBinaryMarshaller.STRING: { + int dataLen = buf.getInt(); + + byte[] data = new byte[dataLen]; + + buf.get(data); + + val = new String(data, 0, dataLen, UTF_8); + + break; + } + + case GridBinaryMarshaller.DATE: { + long time = buf.getLong(); + + val = new Date(time); + + break; + } + + case GridBinaryMarshaller.TIMESTAMP: { + long time = buf.getLong(); + int nanos = buf.getInt(); + + Timestamp ts = new Timestamp(time); + + ts.setNanos(ts.getNanos() + nanos); + + val = ts; + + break; + } + + case GridBinaryMarshaller.UUID: { + long most = buf.getLong(); + long least = buf.getLong(); + + val = new UUID(most, least); + + break; + } + + case GridBinaryMarshaller.DECIMAL: { + int scale = buf.getInt(); + + int dataLen = buf.getInt(); + + byte[] data = new byte[dataLen]; + + buf.get(data); + + BigInteger intVal = new BigInteger(data); + + if (scale < 0) { + scale &= 0x7FFFFFFF; + + intVal = intVal.negate(); + } + + val = new BigDecimal(intVal, scale); + + break; + } + + case GridBinaryMarshaller.NULL: + val = null; + + break; + + default: + // Restore buffer position. + buf.position(pos); + + val = BinaryUtils.unmarshal(BinaryByteBufferInputStream.create(buf), ctx, null); + + break; + } + + return (F)val; + } + finally { + buf.order(oldOrder); + } + } + /** * Get relative field offset. * http://git-wip-us.apache.org/repos/asf/ignite/blob/ddfe632e/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java index ddf17f0..4ea5935 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.binary; import java.math.BigDecimal; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.IdentityHashMap; import org.apache.ignite.IgniteException; @@ -82,6 +83,15 @@ public abstract class BinaryObjectExImpl implements BinaryObjectEx { @Nullable protected abstract <F> F fieldByOrder(int fieldOffset); /** + * Writes field value defined by the given field offset to the given byte buffer. + * + * @param fieldOffset Field offset. + * @return Boolean flag indicating whether the field was successfully written to the buffer, {@code false} + * if there is no enough space for the field in the buffer. + */ + protected abstract boolean writeFieldByOrder(int fieldOffset, ByteBuffer buf); + + /** * @param ctx Reader context. * @param fieldName Field name. * @return Field value. http://git-wip-us.apache.org/repos/asf/ignite/blob/ddfe632e/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java index 44c7a08..a500ceb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java @@ -385,6 +385,122 @@ public final class BinaryObjectImpl extends BinaryObjectExImpl implements Extern } /** {@inheritDoc} */ + @SuppressWarnings("IfMayBeConditional") + @Override public boolean writeFieldByOrder(int order, ByteBuffer buf) { + // Calculate field position. + int schemaOffset = BinaryPrimitives.readInt(arr, start + GridBinaryMarshaller.SCHEMA_OR_RAW_OFF_POS); + + short flags = BinaryPrimitives.readShort(arr, start + GridBinaryMarshaller.FLAGS_POS); + + int fieldIdLen = BinaryUtils.isCompactFooter(flags) ? 0 : BinaryUtils.FIELD_ID_LEN; + int fieldOffsetLen = BinaryUtils.fieldOffsetLength(flags); + + int fieldOffsetPos = start + schemaOffset + order * (fieldIdLen + fieldOffsetLen) + fieldIdLen; + + int fieldPos; + + if (fieldOffsetLen == BinaryUtils.OFFSET_1) + fieldPos = start + ((int)BinaryPrimitives.readByte(arr, fieldOffsetPos) & 0xFF); + else if (fieldOffsetLen == BinaryUtils.OFFSET_2) + fieldPos = start + ((int)BinaryPrimitives.readShort(arr, fieldOffsetPos) & 0xFFFF); + else + fieldPos = start + BinaryPrimitives.readInt(arr, fieldOffsetPos); + + // Read header and try performing fast lookup for well-known types (the most common types go first). + byte hdr = BinaryPrimitives.readByte(arr, fieldPos); + + int totalLen; + + switch (hdr) { + case GridBinaryMarshaller.NULL: + totalLen = 1; + + break; + + case GridBinaryMarshaller.INT: + case GridBinaryMarshaller.FLOAT: + totalLen = 5; + + break; + + case GridBinaryMarshaller.LONG: + case GridBinaryMarshaller.DOUBLE: + case GridBinaryMarshaller.DATE: + totalLen = 9; + + break; + + case GridBinaryMarshaller.BOOLEAN: + totalLen = 2; + + break; + + case GridBinaryMarshaller.SHORT: + totalLen = 3; + + break; + + case GridBinaryMarshaller.BYTE: + totalLen = 2; + + break; + + case GridBinaryMarshaller.CHAR: + totalLen = 3; + + break; + + case GridBinaryMarshaller.STRING: { + int dataLen = BinaryPrimitives.readInt(arr, fieldPos + 1); + + totalLen = dataLen + 5; + + break; + } + + case GridBinaryMarshaller.TIMESTAMP: + totalLen = 13; + + break; + + case GridBinaryMarshaller.UUID: + totalLen = 17; + + break; + + case GridBinaryMarshaller.DECIMAL: { + int dataLen = BinaryPrimitives.readInt(arr, fieldPos + 5); + + totalLen = dataLen + 9; + + break; + } + + case GridBinaryMarshaller.OBJ: + totalLen = BinaryPrimitives.readInt(arr, fieldPos + GridBinaryMarshaller.TOTAL_LEN_POS); + + break; + + case GridBinaryMarshaller.OPTM_MARSH: + totalLen = BinaryPrimitives.readInt(arr, fieldPos + 1); + + break; + + default: + throw new UnsupportedOperationException("Failed to write field of the given type " + + "(field type is not supported): " + hdr); + + } + + if (buf.remaining() < totalLen) + return false; + + buf.put(arr, fieldPos, totalLen); + + return true; + } + + /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Nullable @Override protected <F> F field(BinaryReaderHandles rCtx, String fieldName) { return (F)reader(rCtx).unmarshalField(fieldName); http://git-wip-us.apache.org/repos/asf/ignite/blob/ddfe632e/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java index 07ab4d3..ef6dac8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java @@ -299,6 +299,11 @@ public class BinaryObjectOffheapImpl extends BinaryObjectExImpl implements Exter } /** {@inheritDoc} */ + @Override protected boolean writeFieldByOrder(int fieldOffset, ByteBuffer buf) { + return false; + } + + /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Nullable @Override protected <F> F field(BinaryReaderHandles rCtx, String fieldName) { return (F)reader(rCtx).unmarshalField(fieldName); http://git-wip-us.apache.org/repos/asf/ignite/blob/ddfe632e/modules/core/src/main/java/org/apache/ignite/internal/binary/streams/BinaryByteBufferInputStream.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/streams/BinaryByteBufferInputStream.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/streams/BinaryByteBufferInputStream.java new file mode 100644 index 0000000..d4eba83 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/streams/BinaryByteBufferInputStream.java @@ -0,0 +1,291 @@ +/* + * 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.streams; + +import java.nio.ByteBuffer; +import org.apache.ignite.binary.BinaryObjectException; + +/** + * + */ +public class BinaryByteBufferInputStream implements BinaryInputStream { + /** */ + private ByteBuffer buf; + + /** + * @param buf Buffer to wrap. + * @return Stream. + */ + public static BinaryByteBufferInputStream create(ByteBuffer buf) { + return new BinaryByteBufferInputStream(buf); + } + + /** + * @param buf Buffer to get data from. + */ + BinaryByteBufferInputStream(ByteBuffer buf) { + this.buf = buf; + } + + /** {@inheritDoc} */ + @Override public byte readByte() { + ensureHasData(1); + + return buf.get(); + } + + /** {@inheritDoc} */ + @Override public byte[] readByteArray(int cnt) { + ensureHasData(cnt); + + byte[] data = new byte[cnt]; + + buf.get(data); + + return data; + } + + /** {@inheritDoc} */ + @Override public int read(byte[] arr, int off, int cnt) { + ensureHasData(cnt); + + return 0; + } + + /** {@inheritDoc} */ + @Override public boolean readBoolean() { + ensureHasData(1); + + return false; + } + + /** {@inheritDoc} */ + @Override public boolean[] readBooleanArray(int cnt) { + ensureHasData(cnt); + + boolean[] res = new boolean[cnt]; + + for (int i = 0; i < cnt; i++) + res[i] = buf.get() != 0; + + return res; + } + + /** {@inheritDoc} */ + @Override public short readShort() { + ensureHasData(2); + + return buf.getShort(); + } + + /** {@inheritDoc} */ + @Override public short[] readShortArray(int cnt) { + ensureHasData(2 * cnt); + + short[] res = new short[cnt]; + + for (int i = 0; i < cnt; i++) + res[i] = buf.getShort(); + + return res; + } + + /** {@inheritDoc} */ + @Override public char readChar() { + ensureHasData(2); + + return buf.getChar(); + } + + /** {@inheritDoc} */ + @Override public char[] readCharArray(int cnt) { + ensureHasData(2 * cnt); + + char[] res = new char[cnt]; + + for (int i = 0; i < cnt; i++) + res[i] = buf.getChar(); + + return res; + } + + /** {@inheritDoc} */ + @Override public int readInt() { + ensureHasData(4); + + return buf.getInt(); + } + + /** {@inheritDoc} */ + @Override public int[] readIntArray(int cnt) { + ensureHasData(4 * cnt); + + int[] res = new int[cnt]; + + for (int i = 0; i < cnt; i++) + res[i] = buf.getInt(); + + return res; + } + + /** {@inheritDoc} */ + @Override public float readFloat() { + ensureHasData(4); + + return buf.getFloat(); + } + + /** {@inheritDoc} */ + @Override public float[] readFloatArray(int cnt) { + ensureHasData(4 * cnt); + + float[] res = new float[cnt]; + + for (int i = 0; i < cnt; i++) + res[i] = buf.getFloat(); + + return res; + } + + /** {@inheritDoc} */ + @Override public long readLong() { + ensureHasData(8); + + return buf.getLong(); + } + + /** {@inheritDoc} */ + @Override public long[] readLongArray(int cnt) { + ensureHasData(8 * cnt); + + long[] res = new long[cnt]; + + for (int i = 0; i < cnt; i++) + res[i] = buf.getLong(); + + return res; + } + + /** {@inheritDoc} */ + @Override public double readDouble() { + ensureHasData(8); + + return buf.getDouble(); + } + + /** {@inheritDoc} */ + @Override public double[] readDoubleArray(int cnt) { + ensureHasData(8 * cnt); + + double[] res = new double[cnt]; + + for (int i = 0; i < cnt; i++) + res[i] = buf.getDouble(); + + return res; + } + + /** {@inheritDoc} */ + @Override public int remaining() { + return buf.remaining(); + } + + /** {@inheritDoc} */ + @Override public byte readBytePositioned(int pos) { + int oldPos = buf.position(); + + buf.position(pos); + + ensureHasData(1); + + byte res = buf.get(); + + buf.position(oldPos); + + return res; + } + + /** {@inheritDoc} */ + @Override public short readShortPositioned(int pos) { + int oldPos = buf.position(); + + buf.position(pos); + + ensureHasData(2); + + short res = buf.getShort(); + + buf.position(oldPos); + + return res; + } + + /** {@inheritDoc} */ + @Override public int readIntPositioned(int pos) { + int oldPos = buf.position(); + + buf.position(pos); + + ensureHasData(4); + + byte res = buf.get(); + + buf.position(oldPos); + + return res; + } + + /** {@inheritDoc} */ + @Override public int position() { + return buf.position(); + } + + /** {@inheritDoc} */ + @Override public void position(int pos) { + buf.position(pos); + } + + /** {@inheritDoc} */ + @Override public byte[] array() { + return buf.array(); + } + + /** {@inheritDoc} */ + @Override public byte[] arrayCopy() { + return buf.array(); + } + + /** {@inheritDoc} */ + @Override public long offheapPointer() { + return 0; + } + + /** {@inheritDoc} */ + @Override public boolean hasArray() { + return false; + } + + /** + * @param cnt Remaining bytes. + */ + private void ensureHasData(int cnt) { + if (buf.remaining() < cnt) + throw new BinaryObjectException("Not enough data to read the value " + + "[requiredBytes=" + cnt + ", remainingBytes=" + buf.remaining() + ']'); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ddfe632e/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryFieldExtractionSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryFieldExtractionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryFieldExtractionSelfTest.java new file mode 100644 index 0000000..5721128 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryFieldExtractionSelfTest.java @@ -0,0 +1,161 @@ +/* + * 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.nio.ByteBuffer; +import java.util.concurrent.ThreadLocalRandom; +import org.apache.ignite.configuration.BinaryConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.util.IgniteUtils; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.MarshallerContextTestImpl; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * + */ +public class BinaryFieldExtractionSelfTest extends GridCommonAbstractTest { + /** + * Create marshaller. + * + * @return Binary marshaller. + * @throws Exception If failed. + */ + protected BinaryMarshaller createMarshaller() throws Exception { + BinaryContext ctx = new BinaryContext(BinaryCachingMetadataHandler.create(), new IgniteConfiguration(), + log()); + + BinaryMarshaller marsh = new BinaryMarshaller(); + + BinaryConfiguration bCfg = new BinaryConfiguration(); + + IgniteConfiguration iCfg = new IgniteConfiguration(); + + iCfg.setBinaryConfiguration(bCfg); + + marsh.setContext(new MarshallerContextTestImpl(null)); + + IgniteUtils.invoke(BinaryMarshaller.class, marsh, "setBinaryContext", ctx, iCfg); + + return marsh; + } + + /** + * @throws Exception If failed. + */ + public void testPrimitiveMarshalling() throws Exception { + BinaryMarshaller marsh = createMarshaller(); + + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + + TestObject obj = new TestObject(0); + + BinaryObjectImpl binObj = toBinary(obj, marsh); + + BinaryFieldEx[] fields = new BinaryFieldEx[] { + (BinaryFieldEx)binObj.type().field("bVal"), + (BinaryFieldEx)binObj.type().field("cVal"), + (BinaryFieldEx)binObj.type().field("sVal"), + (BinaryFieldEx)binObj.type().field("iVal"), + (BinaryFieldEx)binObj.type().field("lVal"), + (BinaryFieldEx)binObj.type().field("fVal"), + (BinaryFieldEx)binObj.type().field("dVal") + }; + + ByteBuffer buf = ByteBuffer.allocate(1024 * 1024); + + for (int i = 0; i < 100; i++) { + TestObject to = new TestObject(rnd.nextLong()); + + BinaryObjectImpl bObj = toBinary(to, marsh); + + for (BinaryFieldEx field : fields) + field.writeField(bObj, buf); + + buf.flip(); + + for (BinaryFieldEx field : fields) + assertEquals(field.value(bObj), field.readField(buf)); + + buf.flip(); + } + } + + /** + * @param obj Object to transform to a binary object. + * @param marsh Binary marshaller. + * @return Binary object. + */ + protected BinaryObjectImpl toBinary(Object obj, BinaryMarshaller marsh) throws Exception { + byte[] bytes = marsh.marshal(obj); + + return new BinaryObjectImpl(binaryContext(marsh), bytes, 0); + } + + /** + * Get binary context for the current marshaller. + * + * @param marsh Marshaller. + * @return Binary context. + */ + protected static BinaryContext binaryContext(BinaryMarshaller marsh) { + GridBinaryMarshaller impl = U.field(marsh, "impl"); + + return impl.context(); + } + + /** + * + */ + @SuppressWarnings("UnusedDeclaration") + private static class TestObject { + /** */ + private byte bVal; + + /** */ + private char cVal; + + /** */ + private short sVal; + + /** */ + private int iVal; + + /** */ + private long lVal; + + /** */ + private float fVal; + + /** */ + private double dVal; + + /** + * @param seed Seed. + */ + private TestObject(long seed) { + bVal = (byte)seed; + cVal = (char)seed; + sVal = (short)seed; + iVal = (int)seed; + lVal = seed; + fVal = seed; + dVal = seed; + } + } +}