Repository: incubator-ignite Updated Branches: refs/heads/ignite-950 680ffa0b1 -> d9bceb562
IGNITE-950 - Introduced IgniteObject Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/d9bceb56 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/d9bceb56 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/d9bceb56 Branch: refs/heads/ignite-950 Commit: d9bceb562a8ec1d026e47ed1c076afc43a3cc35a Parents: 680ffa0 Author: Alexey Goncharuk <agoncha...@gridgain.com> Authored: Tue Jul 21 18:29:39 2015 -0700 Committer: Alexey Goncharuk <agoncha...@gridgain.com> Committed: Tue Jul 21 18:29:39 2015 -0700 ---------------------------------------------------------------------- .../java/org/apache/ignite/IgniteCache.java | 8 +++ .../java/org/apache/ignite/IgniteObject.java | 55 +++++++++++++++++++ .../processors/cache/CacheIndexedObject.java | 32 +---------- .../cache/CacheIndexedObjectImpl.java | 50 ++++++++++++++--- .../processors/cache/CacheOperationContext.java | 24 ++++----- .../processors/cache/GridCacheAdapter.java | 18 +++---- .../processors/cache/GridCacheContext.java | 4 +- .../processors/cache/GridCacheProxyImpl.java | 6 +-- .../processors/cache/IgniteCacheProxy.java | 35 ++++++++++-- .../processors/cache/IgniteInternalCache.java | 10 ++-- .../cache/KeyCacheIndexedObjectImpl.java | 38 +------------ .../distributed/dht/GridDhtCacheAdapter.java | 4 +- .../cache/query/GridCacheQueryManager.java | 2 +- .../store/GridCacheStoreManagerAdapter.java | 12 ++--- .../transactions/IgniteTxLocalAdapter.java | 6 +-- .../IgniteCacheObjectProcessorImpl.java | 4 +- .../processors/query/GridQueryProcessor.java | 4 +- .../optimized/OptimizedClassDescriptor.java | 2 + .../optimized/OptimizedMarshaller.java | 2 +- .../optimized/OptimizedMarshallerUtils.java | 22 -------- .../optimized/OptimizedObjectInputStream.java | 43 ++++++--------- .../optimized/OptimizedObjectMetadata.java | 9 ++-- .../optimized/OptimizedObjectOutputStream.java | 50 +++++++++++++++-- .../OptimizedMarshallerExtSelfTest.java | 57 ++++++++++++++++++-- .../multijvm/IgniteCacheProcessProxy.java | 5 ++ .../processors/query/h2/IgniteH2Indexing.java | 2 +- 26 files changed, 314 insertions(+), 190 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/IgniteCache.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java index 4938ab1..fce2777 100644 --- a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java +++ b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java @@ -106,6 +106,14 @@ public interface IgniteCache<K, V> extends javax.cache.Cache<K, V>, IgniteAsyncS public IgniteCache<K, V> withSkipStore(); /** + * Returns an instance of cache that will keep binary form of objects on all cache operations when + * optimized field marshaller is used. + * + * @return Instance of Ignite cache preserving binary object format. + */ + public IgniteCache<K, V> withIgniteObject(); + + /** * @return Cache with no-retries behavior enabled. */ public IgniteCache<K, V> withNoRetries(); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/IgniteObject.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteObject.java b/modules/core/src/main/java/org/apache/ignite/IgniteObject.java new file mode 100644 index 0000000..c9e1160 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/IgniteObject.java @@ -0,0 +1,55 @@ +/* + * 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; + +import org.jetbrains.annotations.*; + +/** + * Abstracted binary representation of objects. + */ +public interface IgniteObject { + /** + * Gets portable object type ID. + * + * @return Type ID. + */ + public int typeId(); + + /** + * Gets fully deserialized instance of portable object. + * + * @return Fully deserialized instance of portable object. + */ + @Nullable public <T> T deserialize() throws IgniteException; + + /** + * Gets field value. + * + * @param fieldName Field name. + * @return Field value. + */ + @Nullable public <T> T field(String fieldName); + + /** + * Checks whether field is set. + * + * @param fieldName Field name. + * @return {@code true} if field is set. + */ + public boolean hasField(String fieldName); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObject.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObject.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObject.java index de931a2..0cf0dee 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObject.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObject.java @@ -23,34 +23,6 @@ import org.jetbrains.annotations.*; /** * */ -public interface CacheIndexedObject extends CacheObject { - /** - * Gets portable object type ID. - * - * @return Type ID. - */ - public int typeId(); - - /** - * Gets fully deserialized instance of portable object. - * - * @return Fully deserialized instance of portable object. - */ - @Nullable public <T> T deserialize() throws IgniteException; - - /** - * Gets field value. - * - * @param fieldName Field name. - * @return Field value. - */ - @Nullable public <T> T field(String fieldName); - - /** - * Checks whether field is set. - * - * @param fieldName Field name. - * @return {@code true} if field is set. - */ - public boolean hasField(String fieldName); +public interface CacheIndexedObject extends CacheObject, IgniteObject { + // All required method are declared in IgniteObject. } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java index 852f9df..c85e2c9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheIndexedObjectImpl.java @@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache; import org.apache.ignite.*; import org.apache.ignite.internal.util.*; +import org.apache.ignite.internal.util.typedef.*; import org.apache.ignite.marshaller.optimized.*; import org.apache.ignite.plugin.extensions.communication.*; import org.jetbrains.annotations.*; @@ -27,6 +28,8 @@ import sun.misc.*; import java.io.*; import java.nio.*; +import static org.apache.ignite.marshaller.optimized.OptimizedObjectOutputStream.*; + /** * Cache object implementation for classes that support footer injection is their serialized form thus enabling fields * search and extraction without necessity to fully deserialize an object. @@ -108,7 +111,7 @@ public class CacheIndexedObjectImpl extends CacheObjectAdapter implements CacheI /** {@inheritDoc} */ @Override public byte[] valueBytes(CacheObjectContext ctx) throws IgniteCheckedException { - toMarshaledFormIfNeeded(ctx); + toMarshaledFormIfNeeded(); return valBytes; } @@ -130,7 +133,7 @@ public class CacheIndexedObjectImpl extends CacheObjectAdapter implements CacheI /** {@inheritDoc} */ @Override public void prepareMarshal(CacheObjectContext ctx) throws IgniteCheckedException { - toMarshaledFormIfNeeded(ctx); + toMarshaledFormIfNeeded(); } /** {@inheritDoc} */ @@ -309,25 +312,56 @@ public class CacheIndexedObjectImpl extends CacheObjectAdapter implements CacheI /** {@inheritDoc} */ @Override public int hashCode() { - assert false; + if (val != null) + return val.hashCode(); + else { + assert valBytes != null; - return super.hashCode(); + return UNSAFE.getInt(valBytes, BYTE_ARR_OFF + start + len - + FOOTER_LENGTH_FIELD_SIZE - FOOTER_HANDLES_FIELD_SIZE - FOOTER_OBJECT_HASH_CODE_FIELD_SIZE); + } } /** {@inheritDoc} */ @Override public boolean equals(Object obj) { - assert false; + if (obj == this) + return true; + + if (!(obj instanceof CacheIndexedObjectImpl)) + return false; + + CacheIndexedObjectImpl other = (CacheIndexedObjectImpl)obj; + + try { + if (val != null && other.val != null) + return F.eq(val, other.val); + else { + toMarshaledFormIfNeeded(); - return super.equals(obj); + other.toMarshaledFormIfNeeded(); + + if (len != other.len) + return false; + + for (int i = 0; i < len; i++) { + if (valBytes[start + i] != other.valBytes[other.start + i]) + return false; + } + + return true; + } + } + catch (IgniteCheckedException e) { + throw new IgniteException(e); + } } /** * Marshals {@link #val} to {@link #valBytes} if needed. * - * @param ctx Cache object context. * @throws IgniteCheckedException In case of error. */ - protected void toMarshaledFormIfNeeded(CacheObjectContext ctx) throws IgniteCheckedException { + protected void toMarshaledFormIfNeeded() throws IgniteCheckedException { if (valBytes == null) { assert val != null; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOperationContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOperationContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOperationContext.java index 343a2f0..0f9935d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOperationContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOperationContext.java @@ -44,7 +44,7 @@ public class CacheOperationContext implements Serializable { private final UUID subjId; /** Keep portable flag. */ - private final boolean keepPortable; + private final boolean keepIgniteObject; /** Expiry policy. */ private final ExpiryPolicy expiryPlc; @@ -57,7 +57,7 @@ public class CacheOperationContext implements Serializable { subjId = null; - keepPortable = false; + keepIgniteObject = false; expiryPlc = null; @@ -67,20 +67,20 @@ public class CacheOperationContext implements Serializable { /** * @param skipStore Skip store flag. * @param subjId Subject ID. - * @param keepPortable Keep portable flag. + * @param keepIgniteObject Keep portable flag. * @param expiryPlc Expiry policy. */ public CacheOperationContext( boolean skipStore, @Nullable UUID subjId, - boolean keepPortable, + boolean keepIgniteObject, @Nullable ExpiryPolicy expiryPlc, boolean noRetries) { this.skipStore = skipStore; this.subjId = subjId; - this.keepPortable = keepPortable; + this.keepIgniteObject = keepIgniteObject; this.expiryPlc = expiryPlc; @@ -90,16 +90,16 @@ public class CacheOperationContext implements Serializable { /** * @return Keep portable flag. */ - public boolean isKeepPortable() { - return keepPortable; + public boolean isKeepIgniteObject() { + return keepIgniteObject; } /** - * See {@link IgniteInternalCache#keepPortable()}. + * See {@link IgniteInternalCache#keepIgniteObject()}. * * @return New instance of CacheOperationContext with keep portable flag. */ - public CacheOperationContext keepPortable() { + public CacheOperationContext keepIgniteObject() { return new CacheOperationContext( skipStore, subjId, @@ -127,7 +127,7 @@ public class CacheOperationContext implements Serializable { return new CacheOperationContext( skipStore, subjId, - keepPortable, + keepIgniteObject, expiryPlc, noRetries); } @@ -149,7 +149,7 @@ public class CacheOperationContext implements Serializable { return new CacheOperationContext( skipStore, subjId, - keepPortable, + keepIgniteObject, expiryPlc, noRetries); } @@ -184,7 +184,7 @@ public class CacheOperationContext implements Serializable { return new CacheOperationContext( skipStore, subjId, - keepPortable, + keepIgniteObject, expiryPlc, noRetries ); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java index eded9bf..76e8156 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java @@ -384,7 +384,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V } /** {@inheritDoc} */ - @Override public <K1, V1> GridCacheProxyImpl<K1, V1> keepPortable() { + @Override public <K1, V1> GridCacheProxyImpl<K1, V1> keepIgniteObject() { CacheOperationContext opCtx = new CacheOperationContext(false, null, true, null, false); return new GridCacheProxyImpl<>((GridCacheContext<K1, V1>)ctx, (GridCacheAdapter<K1, V1>)this, opCtx); @@ -593,7 +593,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V modes.backup = true; if (modes.heap) - its.add(iterator(map.entries0().iterator(), !ctx.keepPortable())); + its.add(iterator(map.entries0().iterator(), !ctx.keepIgniteObject())); } else if (modes.heap) { if (modes.near && ctx.isNear()) @@ -727,7 +727,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V Object val = CU.value(cacheVal, ctx, true); - val = ctx.unwrapIfNeeded(val, ctx.keepPortable()); + val = ctx.unwrapIfNeeded(val, ctx.keepIgniteObject()); return (V)val; } @@ -1241,7 +1241,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V null, null, taskName, - !ctx.keepPortable(), + !ctx.keepIgniteObject(), false); } @@ -1445,7 +1445,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V long start = statsEnabled ? System.nanoTime() : 0L; - V val = get(key, !ctx.keepPortable()); + V val = get(key, !ctx.keepIgniteObject()); if (ctx.config().getInterceptor() != null) val = (V)ctx.config().getInterceptor().onGet(key, val); @@ -1464,7 +1464,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V final long start = statsEnabled ? System.nanoTime() : 0L; - IgniteInternalFuture<V> fut = getAsync(key, !ctx.keepPortable()); + IgniteInternalFuture<V> fut = getAsync(key, !ctx.keepIgniteObject()); if (ctx.config().getInterceptor() != null) fut = fut.chain(new CX1<IgniteInternalFuture<V>, V>() { @@ -1487,7 +1487,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V long start = statsEnabled ? System.nanoTime() : 0L; - Map<K, V> map = getAll(keys, !ctx.keepPortable()); + Map<K, V> map = getAll(keys, !ctx.keepIgniteObject()); if (ctx.config().getInterceptor() != null) map = interceptGet(keys, map); @@ -1506,7 +1506,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V final long start = statsEnabled ? System.nanoTime() : 0L; - IgniteInternalFuture<Map<K, V>> fut = getAllAsync(keys, !ctx.keepPortable()); + IgniteInternalFuture<Map<K, V>> fut = getAllAsync(keys, !ctx.keepIgniteObject()); if (ctx.config().getInterceptor() != null) return fut.chain(new CX1<IgniteInternalFuture<Map<K, V>>, Map<K, V>>() { @@ -3720,7 +3720,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V if (!ctx0.isSwapOrOffheapEnabled() && ctx0.kernalContext().discovery().size() == 1) return localIteratorHonorExpirePolicy(opCtx); - CacheQueryFuture<Map.Entry<K, V>> fut = ctx0.queries().createScanQuery(null, null, ctx.keepPortable()) + CacheQueryFuture<Map.Entry<K, V>> fut = ctx0.queries().createScanQuery(null, null, ctx.keepIgniteObject()) .keepAll(false) .execute(); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java index c317b79..8189afd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java @@ -1680,10 +1680,10 @@ public class GridCacheContext<K, V> implements Externalizable { /** * @return Keep portable flag. */ - public boolean keepPortable() { + public boolean keepIgniteObject() { CacheOperationContext opCtx = operationContextPerCall(); - return opCtx != null && opCtx.isKeepPortable(); + return opCtx != null && opCtx.isKeepIgniteObject(); } /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProxyImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProxyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProxyImpl.java index cec8c53..4818675 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProxyImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProxyImpl.java @@ -218,13 +218,13 @@ public class GridCacheProxyImpl<K, V> implements IgniteInternalCache<K, V>, Exte } /** {@inheritDoc} */ - @Override public <K1, V1> GridCacheProxyImpl<K1, V1> keepPortable() { - if (opCtx != null && opCtx.isKeepPortable()) + @Override public <K1, V1> GridCacheProxyImpl<K1, V1> keepIgniteObject() { + if (opCtx != null && opCtx.isKeepIgniteObject()) return (GridCacheProxyImpl<K1, V1>)this; return new GridCacheProxyImpl<>((GridCacheContext<K1, V1>)ctx, (GridCacheAdapter<K1, V1>)delegate, - opCtx != null ? opCtx.keepPortable() : new CacheOperationContext(false, null, true, null, false)); + opCtx != null ? opCtx.keepIgniteObject() : new CacheOperationContext(false, null, true, null, false)); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java index 0b2eba0..2867443 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java @@ -272,6 +272,33 @@ public class IgniteCacheProxy<K, V> extends AsyncSupportAdapter<IgniteCache<K, V } /** {@inheritDoc} */ + @Override public IgniteCache<K, V> withIgniteObject() { + GridCacheGateway<K, V> gate = this.gate; + + CacheOperationContext prev = onEnter(gate, opCtx); + + try { + boolean obj = opCtx != null && opCtx.isKeepIgniteObject(); + + if (obj) + return this; + + CacheOperationContext opCtx0 = opCtx == null ? + new CacheOperationContext(false, null, true, null, false) : + opCtx.keepIgniteObject(); + + return new IgniteCacheProxy<>(ctx, + delegate, + opCtx0, + isAsync(), + lock); + } + finally { + onLeave(gate, prev); + } + } + + /** {@inheritDoc} */ @Override public IgniteCache<K, V> withNoRetries() { GridCacheGateway<K, V> gate = this.gate; @@ -400,7 +427,7 @@ public class IgniteCacheProxy<K, V> extends AsyncSupportAdapter<IgniteCache<K, V final CacheQuery<Map.Entry<K,V>> qry; final CacheQueryFuture<Map.Entry<K,V>> fut; - boolean isKeepPortable = opCtx != null && opCtx.isKeepPortable(); + boolean isKeepPortable = opCtx != null && opCtx.isKeepIgniteObject(); if (filter instanceof ScanQuery) { IgniteBiPredicate<K, V> p = ((ScanQuery)filter).getFilter(); @@ -1612,7 +1639,7 @@ public class IgniteCacheProxy<K, V> extends AsyncSupportAdapter<IgniteCache<K, V * </ul> <p> For example, if you use {@link Integer} as a key and {@code Value} class as a value (which will be * stored in portable format), you should acquire following projection to avoid deserialization: * <pre> - * IgniteInternalCache<Integer, GridPortableObject> prj = cache.keepPortable(); + * IgniteInternalCache<Integer, GridPortableObject> prj = cache.keepIgniteObject(); * * // Value is not deserialized and returned in portable format. * GridPortableObject po = prj.get(1); @@ -1624,7 +1651,7 @@ public class IgniteCacheProxy<K, V> extends AsyncSupportAdapter<IgniteCache<K, V * @return Projection for portable objects. */ @SuppressWarnings("unchecked") - public <K1, V1> IgniteCache<K1, V1> keepPortable() { + public <K1, V1> IgniteCache<K1, V1> keepIgniteObjects() { GridCacheGateway<K, V> gate = this.gate; CacheOperationContext prev = onEnter(gate, opCtx); @@ -1666,7 +1693,7 @@ public class IgniteCacheProxy<K, V> extends AsyncSupportAdapter<IgniteCache<K, V CacheOperationContext opCtx0 = new CacheOperationContext(true, opCtx != null ? opCtx.subjectId() : null, - opCtx != null && opCtx.isKeepPortable(), + opCtx != null && opCtx.isKeepIgniteObject(), opCtx != null ? opCtx.expiry() : null, opCtx != null && opCtx.noRetries()); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteInternalCache.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteInternalCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteInternalCache.java index 9972f92..af9a325 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteInternalCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteInternalCache.java @@ -174,14 +174,14 @@ import java.util.Date; * You won't be able to work with deserialized form if class definition for the {@code Value} is not on * classpath. Even if you have the class definition, you should always avoid full deserialization if it's not * needed for performance reasons. To work with portable format directly you should create special projection - * using {@link #keepPortable()} method: + * using {@link #keepIgniteObject()} method: * <pre> - * IgniteInternalCache<Integer, GridPortableObject> prj = Ignition.grid().cache(null).keepPortable(); + * IgniteInternalCache<Integer, GridPortableObject> prj = Ignition.grid().cache(null).keepIgniteObject(); * * // Value is not deserialized and returned in portable format. * GridPortableObject po = prj.get(1); * </pre> - * See {@link #keepPortable()} method JavaDoc for more details. + * See {@link #keepIgniteObject()} method JavaDoc for more details. */ public interface IgniteInternalCache<K, V> extends Iterable<Cache.Entry<K, V>> { /** @@ -237,7 +237,7 @@ public interface IgniteInternalCache<K, V> extends Iterable<Cache.Entry<K, V>> { * (which will be stored in portable format), you should acquire following projection * to avoid deserialization: * <pre> - * IgniteInternalCache<Integer, GridPortableObject> prj = cache.keepPortable(); + * IgniteInternalCache<Integer, GridPortableObject> prj = cache.keepIgniteObject(); * * // Value is not deserialized and returned in portable format. * GridPortableObject po = prj.get(1); @@ -249,7 +249,7 @@ public interface IgniteInternalCache<K, V> extends Iterable<Cache.Entry<K, V>> { * * @return New internal cache instance for portable objects. */ - public <K1, V1> IgniteInternalCache<K1, V1> keepPortable(); + public <K1, V1> IgniteInternalCache<K1, V1> keepIgniteObject(); /** * Returns {@code true} if this map contains no key-value mappings. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheIndexedObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheIndexedObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheIndexedObjectImpl.java index 2a13f90..02ee988 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheIndexedObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheIndexedObjectImpl.java @@ -17,8 +17,6 @@ package org.apache.ignite.internal.processors.cache; -import org.apache.ignite.*; - /** * Cache object implementation for classes that support footer injection is their serialized form thus enabling fields * search and extraction without necessity to fully deserialize an object. @@ -55,45 +53,13 @@ public class KeyCacheIndexedObjectImpl extends CacheIndexedObjectImpl implements } /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectContext ctx, ClassLoader ldr) throws IgniteCheckedException { - assert val != null || valBytes != null; - - if (val == null) - val = ctx.processor().unmarshal(ctx, valBytes, start, len, ldr); - } - - /** {@inheritDoc} */ @Override public byte directType() { // refer to GridIoMessageFactory. - return 113; + return 114; } /** {@inheritDoc} */ @Override public boolean internal() { - assert val != null; - - return val instanceof GridCacheInternal; - } - - /** {@inheritDoc} */ - @Override public int hashCode() { - assert val != null; - - return val.hashCode(); - } - - /** {@inheritDoc} */ - @Override public boolean equals(Object obj) { - if (!(obj instanceof KeyCacheIndexedObjectImpl)) - return false; - - KeyCacheIndexedObjectImpl other = (KeyCacheIndexedObjectImpl)obj; - - return val.equals(other.val); - } - - /** {@inheritDoc} */ - @Override protected boolean keepDeserialized(CacheObjectContext ctx, boolean checkCls) { - return true; + return false; } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java index 22a5287..2b60c82 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java @@ -967,7 +967,7 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap assert primary || backup; if (primary && backup) - return iterator(map.entries0().iterator(), !ctx.keepPortable()); + return iterator(map.entries0().iterator(), !ctx.keepIgniteObject()); else { final AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion(); @@ -1031,7 +1031,7 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap } }; - return iterator(it, !ctx.keepPortable()); + return iterator(it, !ctx.keepIgniteObject()); } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java index d041bb7..1baf121 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java @@ -755,7 +755,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte IgniteInternalCache<K, V> prj0 = cctx.cache(); if (qry.keepPortable()) - prj0 = prj0.keepPortable(); + prj0 = prj0.keepIgniteObject(); final IgniteInternalCache<K, V> prj = prj0; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java index 8113c4a..1325cb2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java @@ -245,7 +245,7 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt Object storeKey = key.value(cctx.cacheObjectContext(), false); - if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(storeKey) || convertPortable()) + if (convertPortable()) storeKey = cctx.unwrapIfNeeded(storeKey, false); if (log.isDebugEnabled()) @@ -499,9 +499,7 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt if (key instanceof GridCacheInternal) return true; - if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(key) || - OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(val) || - convertPortable()) { + if (convertPortable()) { key = cctx.unwrapIfNeeded(key, false); val = cctx.unwrapIfNeeded(val, false); } @@ -606,7 +604,7 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt if (key instanceof GridCacheInternal) return false; - if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(key) || convertPortable()) + if (convertPortable()) key = cctx.unwrapIfNeeded(key, false); if (log.isDebugEnabled()) @@ -1075,9 +1073,7 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt Object v = locStore ? e.getValue() : e.getValue().get1(); - if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(k) || - OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(v) || - convertPortable()) { + if (convertPortable()) { k = cctx.unwrapIfNeeded(k, false); v = cctx.unwrapIfNeeded(v, false); } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java index 0a61b1a..fdf044a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java @@ -2315,7 +2315,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter /*read through*/cacheCtx.config().isLoadPreviousValue() && !skipStore, /*async*/true, missedForLoad, - deserializePortables(cacheCtx), + deserializeIgniteObject(cacheCtx), /*skip values*/false, new CI2<KeyCacheObject, Object>() { @Override public void apply(KeyCacheObject key, Object val) { @@ -3009,10 +3009,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter * @param cacheCtx Cache context. * @return {@code True} if portables should be deserialized, {@code false} otherwise. */ - private boolean deserializePortables(GridCacheContext cacheCtx) { + private boolean deserializeIgniteObject(GridCacheContext cacheCtx) { CacheOperationContext opCtx = cacheCtx.operationContextPerCall(); - return opCtx == null || !opCtx.isKeepPortable(); + return opCtx == null || !opCtx.isKeepIgniteObject(); } /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java index 2476499..16f7ef8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java @@ -559,7 +559,7 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme /** {@inheritDoc} */ @Override public CacheObject prepareForCache(CacheObjectContext ctx) { try { - toMarshaledFormIfNeeded(ctx); + toMarshaledFormIfNeeded(); if (keepDeserialized(ctx, true)) { ClassLoader ldr = ctx.p2pEnabled() ? @@ -605,7 +605,7 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme @Override public CacheObject prepareForCache(CacheObjectContext ctx) { try { if (!ctx.processor().immutable(val)) { - toMarshaledFormIfNeeded(ctx); + toMarshaledFormIfNeeded(); ClassLoader ldr = ctx.p2pEnabled() ? IgniteUtils.detectClassLoader(IgniteUtils.detectClass(val)) : U.gridClassLoader(); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java index 3b0cea3..9df5acb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java @@ -591,7 +591,7 @@ public class GridQueryProcessor extends GridProcessorAdapter { return idx.queryTwoStep( cctx, qry, - cctx.keepPortable()); + cctx.keepIgniteObject()); } }); } @@ -764,7 +764,7 @@ public class GridQueryProcessor extends GridProcessorAdapter { throw new IllegalStateException("Failed to execute query (grid is stopping)."); try { - final boolean keepPortable = cctx.keepPortable(); + final boolean keepPortable = cctx.keepIgniteObject(); return executeQuery(cctx, new IgniteOutClosureX<QueryCursor<List<?>>>() { @Override public QueryCursor<List<?>> applyx() throws IgniteCheckedException { http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java index 455e4db..da91b96 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java @@ -757,6 +757,8 @@ public class OptimizedClassDescriptor { "set OptimizedMarshaller.setRequireSerializable() to false " + "(note that performance may degrade if object is not Serializable): " + name); + idxHandler.enableFieldsIndexingForClass(obj.getClass()); + writeTypeData(out); out.writeShort(checksum); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java index 4b06a4e..77eb6f3 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java @@ -87,7 +87,7 @@ public class OptimizedMarshaller extends AbstractMarshaller { private OptimizedMarshallerIdMapper mapper; /** */ - private OptimizedMarshallerProtocolVersion protocolVersion = OptimizedMarshallerProtocolVersion.VER_1_1; + private OptimizedMarshallerProtocolVersion protocolVersion = OptimizedMarshallerProtocolVersion.VER_1; /** */ private OptimizedMarshallerIndexingHandler idxHandler; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java index 420da5d..2ef45e9 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java @@ -261,28 +261,6 @@ public class OptimizedMarshallerUtils { } /** - * Checks whether the given object is a wrapper, that contains serialized form of an object with indexed fields, or - * {@link Collection} or {@link Map}. - * - * @param obj Object. - * @return {@code true} if all the conditions are met.. - */ - public static boolean isObjectWithIndexedFieldsOrCollection(Object obj) { - if (obj == null) - return false; - - if (obj instanceof CacheIndexedObjectImpl || - obj instanceof Map.Entry || - obj instanceof Collection || - obj instanceof Map || - obj.getClass() == Object[].class) - return true; - - return false; - } - - - /** * Gets descriptor for provided ID. * * @param clsMap Class descriptors by class map. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java index 40d551c..eabebc6 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java @@ -32,6 +32,7 @@ import java.util.*; import java.util.concurrent.*; import static org.apache.ignite.marshaller.optimized.OptimizedMarshallerUtils.*; +import static org.apache.ignite.marshaller.optimized.OptimizedObjectOutputStream.*; /** * Optimized object input stream. @@ -1290,15 +1291,7 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt if (type != SERIALIZABLE && type != MARSHAL_AWARE) return false; - FieldRange range; - - try { - range = fieldRange(fieldName, start); - } - catch (IgniteFieldNotFoundException e) { - // Ignore - return false; - } + FieldRange range = fieldRange(fieldName, start); return range != null && range.start >= 0; } @@ -1351,9 +1344,8 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt * @param start Object's start offset. * @return positive range or {@code null} if the object doesn't have such a field. * @throws IOException in case of error. - * @throws IgniteFieldNotFoundException In case if there is no such a field. */ - private FieldRange fieldRange(String fieldName, int start) throws IOException, IgniteFieldNotFoundException { + private FieldRange fieldRange(String fieldName, int start) throws IOException { int pos = start + 1; int typeId = in.readInt(pos); @@ -1372,23 +1364,26 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt OptimizedObjectMetadata meta = idxHandler.metaHandler().metadata(typeId); if (meta == null) - // TODO: IGNITE-950 add warning! return null; int end = in.size(); - short footerLen = in.readShort(end - FOOTER_LEN_OFF); + short footerLen = in.readShort(end - FOOTER_LENGTH_FIELD_SIZE); if (footerLen == EMPTY_FOOTER) - throw new IgniteFieldNotFoundException("Object doesn't have a field named: " + fieldName); + return null; if (range == null) range = new FieldRange(); - // Calculating start footer offset. +2 - skipping length at the beginning - pos = (end - footerLen) + 2; + // Calculating start footer offset. Skipping length at the beginning + pos = (end - footerLen) + FOOTER_LENGTH_FIELD_SIZE; int fieldIdx = meta.fieldIndex(fieldName); + + if (fieldIdx < 0) + return null; + int fieldsCnt = meta.size(); if (fieldIdx >= fieldsCnt) @@ -1397,7 +1392,7 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt boolean hasHandles = in.readByte(end - FOOTER_HANDLES_FLAG_OFF) == 1; if (hasHandles) { - long fieldInfo = in.readLong(pos + fieldIdx * 8); + long fieldInfo = in.readLong(pos + fieldIdx * HANDLE_FOOTER_ELEMENT_SIZE); boolean isHandle = ((fieldInfo & FOOTER_BODY_IS_HANDLE_MASK) >> FOOTER_BODY_HANDLE_MASK_BIT) == 1; @@ -1414,11 +1409,12 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt } } else - range.start = in.readInt(pos + fieldIdx * 4) & FOOTER_BODY_OFF_MASK; + range.start = in.readInt(pos + fieldIdx * PLAIN_FOOTER_ELEMENT_SIZE) & FOOTER_BODY_OFF_MASK; if (fieldIdx == 0) { if (fieldsCnt > 1) { - int nextFieldOff = in.readInt(pos + (fieldIdx + 1) * 4); + int nextFieldOff = in.readInt(pos + (fieldIdx + 1) * PLAIN_FOOTER_ELEMENT_SIZE); + range.len = nextFieldOff - range.start; } else @@ -1427,7 +1423,8 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt else if (fieldIdx == fieldsCnt - 1) range.len = (end - footerLen) - range.start; else { - int nextFieldOff = in.readInt(pos + (fieldIdx + 1) * 4); + int nextFieldOff = in.readInt(pos + (fieldIdx + 1) * PLAIN_FOOTER_ELEMENT_SIZE); + range.len = nextFieldOff - range.start; } @@ -1444,12 +1441,6 @@ public class OptimizedObjectInputStream extends ObjectInputStream implements Opt /** */ private int len; - /** - * Constructor. - */ - public FieldRange() { - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(FieldRange.class, this); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java index f55d404..74b6207 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectMetadata.java @@ -56,17 +56,16 @@ public class OptimizedObjectMetadata implements Externalizable { * object's serialized form. * * @param fieldName Field name. - * @return Index. - * @throws IgniteFieldNotFoundException If object doesn't have such a field. + * @return Index or {@code -1} if field index cannot be resolved. */ - public int fieldIndex(String fieldName) throws IgniteFieldNotFoundException { + public int fieldIndex(String fieldName) { if (indexes == null) - throw new IgniteFieldNotFoundException("Object doesn't have field named: " + fieldName); + return -1; FieldInfo info = indexes.get(OptimizedMarshallerUtils.resolveFieldId(fieldName)); if (info == null) - throw new IgniteFieldNotFoundException("Object doesn't have field named: " + fieldName); + return -1; return info.index(); } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java index a23d529..ea0aef1 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java @@ -57,6 +57,24 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O /** */ private static final long longArrOff = UNSAFE.arrayBaseOffset(long[].class); + /** Footer length field size in output format. */ + public static final int FOOTER_LENGTH_FIELD_SIZE = 2; + + /** Object hash code field size in output format. */ + public static final int FOOTER_OBJECT_HASH_CODE_FIELD_SIZE = 4; + + /** Handles indicator field size. */ + public static final int FOOTER_HANDLES_FIELD_SIZE = 1; + + /** Footer plain overhead size. */ + public static final int FOOTER_OVERHEAD = 2 * FOOTER_LENGTH_FIELD_SIZE + FOOTER_OBJECT_HASH_CODE_FIELD_SIZE + + FOOTER_HANDLES_FIELD_SIZE; + + /** Handle footer element size. */ + public static final int HANDLE_FOOTER_ELEMENT_SIZE = 8; + + /** Plain footer element size. */ + public static final int PLAIN_FOOTER_ELEMENT_SIZE = 4; /** */ private final GridDataOutput out; @@ -351,6 +369,8 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O Footer footer = getFooter(); + footer.objectHashCode(obj.hashCode()); + if (marshalAwareFooters == null) marshalAwareFooters = new Stack<>(); @@ -383,8 +403,11 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O out.writeBoolean(hasFooter); - if (hasFooter) + if (hasFooter) { footer = getFooter(); + + footer.objectHashCode(obj.hashCode()); + } } for (int i = 0; i < mtds.size(); i++) { @@ -1242,6 +1265,9 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O private int size; /** */ + private int objHashCode; + + /** */ private boolean hasHandles; @@ -1275,6 +1301,15 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O } /** + * Sets object hash code to write. + * + * @param hashCode Object hash code. + */ + public void objectHashCode(int hashCode) { + objHashCode = hashCode; + } + + /** * Writes footer content to the OutputStream. * * @throws IOException In case of error. @@ -1283,9 +1318,13 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O if (data == null) writeShort(EMPTY_FOOTER); else { - // +5 - 2 bytes for footer len at the beginning, 2 bytes for footer len at the end, 1 byte for handles - // indicator flag. - short footerLen = (short)(size * (hasHandles ? 8 : 4) + 5); + // OVERHEAD = + // footer len at the beginning, + // object hash code, + // handles indicator flag, + // footer len at the end, + short footerLen = (short)(size * (hasHandles ? HANDLE_FOOTER_ELEMENT_SIZE : PLAIN_FOOTER_ELEMENT_SIZE) + + FOOTER_OVERHEAD); writeShort(footerLen); @@ -1298,12 +1337,15 @@ public class OptimizedObjectOutputStream extends ObjectOutputStream implements O writeInt((int)data[i]); } + writeInt(objHashCode); + writeByte(hasHandles ? 1 : 0); writeShort(footerLen); } size = 0; + objHashCode = 0; hasHandles = false; if (footersPool.size() < MAX_FOOTERS_POOL_SIZE) http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java index 22877df..ccf92b9 100644 --- a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerExtSelfTest.java @@ -37,7 +37,7 @@ public class OptimizedMarshallerExtSelfTest extends OptimizedMarshallerSelfTest private static OptimizedMarshallerIndexingHandler idxHandler; /** */ - private CacheObjectContext objCtx; + private transient CacheObjectContext objCtx; /** */ private static final OptimizedMarshallerMetaHandler META_HANDLER = new OptimizedMarshallerMetaHandler() { @@ -115,10 +115,10 @@ public class OptimizedMarshallerExtSelfTest extends OptimizedMarshallerSelfTest assertEquals(testObj.str, text); - // Serializable extraction (doesn't have meta, thus doesn't have footer) - TestObject2 o2 = marsh.readField("o2", arr, 0, arr.length, null, objCtx); + // CacheObject extraction. + CacheIndexedObject o2 = marsh.readField("o2", arr, 0, arr.length, null, objCtx); - assertEquals(testObj.o2, o2); + assertEquals(testObj.o2, o2.deserialize()); // Add metadata for the enclosed object. assertTrue(idxHandler.enableFieldsIndexingForClass(TestObject2.class)); @@ -173,6 +173,37 @@ public class OptimizedMarshallerExtSelfTest extends OptimizedMarshallerSelfTest assertEquals(selfLinkObject, selfLinkObject2); } + /** + * @throws Exception If failed. + */ + public void testHashCode() throws Exception { + OptimizedMarshaller marsh = (OptimizedMarshaller)OptimizedMarshallerExtSelfTest.marsh; + + for (int i = 0; i < 100; i++) { + TestMarshalAware ma = new TestMarshalAware(i, "value" + i); + + byte[] valBytes = marsh.marshal(ma); + + CacheIndexedObject obj = new CacheIndexedObjectImpl(objCtx, valBytes, 0, valBytes.length); + + assertEquals(ma.hashCode(), obj.hashCode()); + + assertEquals(ma.testObject2.hashCode(), obj.<CacheIndexedObject>field("testObject2").hashCode()); + } + + for (int i = 0; i < 100; i++) { + TestObject to = new TestObject("value" + i, i); + + byte[] valBytes = marsh.marshal(to); + + CacheIndexedObject obj = new CacheIndexedObjectImpl(objCtx, valBytes, 0, valBytes.length); + + assertEquals(to.hashCode(), obj.hashCode()); + + assertEquals(to.o2.hashCode(), obj.<CacheIndexedObject>field("o2").hashCode()); + } + } + /** * @throws Exception In case of error. @@ -396,6 +427,24 @@ public class OptimizedMarshallerExtSelfTest extends OptimizedMarshallerSelfTest aware = reader.readObject("aware"); testObject2 = reader.readObject("testObject2"); } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return number * 31 + text.hashCode(); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + TestMarshalAware that = (TestMarshalAware)o; + + return number == that.number && text.equals(that.text); + } } /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteCacheProcessProxy.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteCacheProcessProxy.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteCacheProcessProxy.java index b15b6ef..0b6ce37 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteCacheProcessProxy.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteCacheProcessProxy.java @@ -132,6 +132,11 @@ public class IgniteCacheProcessProxy<K, V> implements IgniteCache<K, V> { throw new UnsupportedOperationException("Method should be supported."); } + /** {@inheritDoc} */ + @Override public IgniteCache<K, V> withIgniteObject() { + throw new UnsupportedOperationException("Method should be supported."); + } + @Override public IgniteCache<K, V> withNoRetries() { throw new UnsupportedOperationException("Method should be supported."); } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d9bceb56/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index 65794da..1c008bb 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -869,7 +869,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { twoStepQry.pageSize(qry.getPageSize()); - QueryCursorImpl<List<?>> cursor = new QueryCursorImpl<>(queryTwoStep(cctx, twoStepQry, cctx.keepPortable())); + QueryCursorImpl<List<?>> cursor = new QueryCursorImpl<>(queryTwoStep(cctx, twoStepQry, cctx.keepIgniteObject())); cursor.fieldsMeta(meta);