ignite-950: managed to run SQL queries with indexed fields in footer
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/25d0da2d Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/25d0da2d Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/25d0da2d Branch: refs/heads/ignite-950 Commit: 25d0da2d0ed44cbb46904863ab43a22445e0f46d Parents: 74017fa Author: Denis Magda <dma...@gridgain.com> Authored: Thu Jun 18 14:15:43 2015 +0300 Committer: Denis Magda <dma...@gridgain.com> Committed: Thu Jun 18 14:15:43 2015 +0300 ---------------------------------------------------------------------- .../processors/cache/CacheObjectContext.java | 93 ++++++++++++++++++-- .../cache/CacheOptimizedObjectImpl.java | 80 +++++++++++------ .../processors/cache/GridCacheAdapter.java | 10 +-- .../processors/cache/GridCacheContext.java | 24 +++-- .../cache/KeyCacheOptimizedObjectImpl.java | 12 ++- .../distributed/near/GridNearGetFuture.java | 4 +- .../query/GridCacheQueryFutureAdapter.java | 2 +- .../cache/query/GridCacheQueryManager.java | 12 +-- .../store/GridCacheStoreManagerAdapter.java | 31 ++++--- .../cacheobject/IgniteCacheObjectProcessor.java | 11 ++- .../IgniteCacheObjectProcessorImpl.java | 34 ++++--- .../query/GridQueryCacheObjectsIterator.java | 2 +- .../processors/query/GridQueryProcessor.java | 9 +- .../internal/util/io/GridUnsafeDataInput.java | 5 +- .../optimized/OptimizedMarshallerUtils.java | 23 +++++ .../optimized/ext/OptimizedMarshallerExt.java | 9 ++ .../ext/OptimizedObjectInputStreamExt.java | 9 +- ...acheOptimizedMarshallerExtQuerySelfTest.java | 15 ++++ 18 files changed, 278 insertions(+), 107 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java index cf35177..b0e3a0d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java @@ -20,6 +20,9 @@ package org.apache.ignite.internal.processors.cache; import org.apache.ignite.cache.affinity.*; import org.apache.ignite.internal.*; import org.apache.ignite.internal.processors.cacheobject.*; +import org.apache.ignite.internal.util.typedef.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.apache.ignite.marshaller.optimized.*; import java.util.*; @@ -120,24 +123,102 @@ public class CacheObjectContext { } /** - * Unwraps object. + * Unwraps object if needed. * * @param o Object to unwrap. - * @param keepPortable Keep portable flag. + * @param keepPortable Keep portable flag. Used for portable objects only. Ignored in other cases. * @return Unwrapped object. */ - public Object unwrapPortableIfNeeded(Object o, boolean keepPortable) { + public Object unwrapIfNeeded(Object o, boolean keepPortable) { + if (processor().isFieldsIndexingEnabled() && OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(o)) + return unwrapObject(o); + return o; } /** - * Unwraps collection. + * Unwraps collection if needed. * * @param col Collection to unwrap. - * @param keepPortable Keep portable flag. + * @param keepPortable Keep portable flag. Used for portable objects only. Ignored in other cases. * @return Unwrapped collection. */ - public Collection<Object> unwrapPortablesIfNeeded(Collection<Object> col, boolean keepPortable) { + public Collection<Object> unwrapIfNeeded(Collection<Object> col, boolean keepPortable) { + if (processor().isFieldsIndexingEnabled()) + return (Collection<Object>)unwrapObject(col); + return col; } + + /** + * Unwraps object if needed. + * + * @param obj Object to unwrap. + * @return Unwrapped object. + */ + private Object unwrapObject(Object obj) { + if (obj instanceof CacheOptimizedObjectImpl) + return ((CacheOptimizedObjectImpl)obj).deserialize(this); + else if (obj instanceof Map.Entry) { + Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>)obj; + + Object key = entry.getKey(); + + boolean unwrapped = false; + + if (key instanceof CacheOptimizedObjectImpl) { + key = ((CacheOptimizedObjectImpl)key).deserialize(this); + + unwrapped = true; + } + + Object val = entry.getValue(); + + if (val instanceof CacheOptimizedObjectImpl) { + val = ((CacheOptimizedObjectImpl)val).deserialize(this); + + unwrapped = true; + } + + return unwrapped ? F.t(key, val) : obj; + } + else if (obj instanceof Collection) { + Collection<Object> col = (Collection<Object>)obj; + + if (col instanceof ArrayList) { + ArrayList<Object> list = (ArrayList<Object>)col; + + int size = list.size(); + + for (int i = 0; i < size; i++) { + Object old = list.get(i); + + Object unwrapped = unwrapObject(old); + + if (old != unwrapped) + list.set(i, unwrapped); + } + + return list; + } + else { + Collection<Object> col0 = new ArrayList<>(col.size()); + + for (Object obj0 : col) + col0.add(unwrapObject(obj0)); + + return col0; + } + } + else if (obj instanceof Map) { + Map<Object, Object> map = (Map<Object, Object>)obj; + + Map<Object, Object> map0 = U.newHashMap(map.size()); + + for (Map.Entry<Object, Object> e : map.entrySet()) + map0.put(unwrapObject(e.getKey()), unwrapObject(e.getValue())); + } + + return obj; + } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java index 078b4de..fe5a644 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheOptimizedObjectImpl.java @@ -18,10 +18,12 @@ package org.apache.ignite.internal.processors.cache; import org.apache.ignite.*; +import org.apache.ignite.internal.util.*; import org.apache.ignite.internal.util.typedef.internal.*; import org.apache.ignite.marshaller.optimized.ext.*; import org.apache.ignite.plugin.extensions.communication.*; import org.jetbrains.annotations.*; +import sun.misc.*; import java.io.*; import java.nio.*; @@ -35,6 +37,12 @@ public class CacheOptimizedObjectImpl extends CacheObjectAdapter { private static final long serialVersionUID = 0L; /** */ + private static final Unsafe UNSAFE = GridUnsafe.unsafe(); + + /** */ + private static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class); + + /** */ protected int start; /** */ @@ -92,33 +100,7 @@ public class CacheOptimizedObjectImpl extends CacheObjectAdapter { /** {@inheritDoc} */ @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) { - //return (T)this; - cpy = cpy && needCopy(ctx); - - try { - if (cpy) { - toMarshaledFormIfNeeded(ctx); - - return (T)ctx.processor().unmarshal(ctx, valBytes, - val == null ? ctx.kernalContext().config().getClassLoader() : val.getClass().getClassLoader()); - } - - if (val != null) - return (T)val; - - assert valBytes != null; - - Object val = ctx.processor().unmarshal(ctx, valBytes, start, len, - ctx.kernalContext().config().getClassLoader()); - - if (ctx.storeValue()) - this.val = val; - - return (T)val; - } - catch (IgniteCheckedException e) { - throw new IgniteException("Failed to unmarshall object.", e); - } + return (T)this; } /** {@inheritDoc} */ @@ -170,6 +152,22 @@ public class CacheOptimizedObjectImpl extends CacheObjectAdapter { } /** + * Returns object's type ID. + * + * @return Type ID. + */ + public int typeId() { + assert valBytes != null; + + int typeId = UNSAFE.getInt(valBytes, BYTE_ARR_OFF + start + 1); + + if (typeId == 0) + throw new IgniteException("Object's type ID wasn't written to cache."); + + return typeId; + } + + /** * Checks whether a wrapped object has field with name {@code fieldName}. * * @param fieldName Field name. @@ -194,7 +192,33 @@ public class CacheOptimizedObjectImpl extends CacheObjectAdapter { public Object field(String fieldName, OptimizedMarshallerExt marsh) throws IgniteCheckedException { assert valBytes != null; - return marsh.readField(fieldName, valBytes, start, len, val != null ? val.getClass().getClassLoader() : null); + return marsh.readField(fieldName, valBytes, start, len, val != null ? val.getClass().getClassLoader() : null); + } + + /** + * Deserializes wrapped object. + * + * @param ctx Cache context. + * @return Deserialized object. + */ + public Object deserialize(CacheObjectContext ctx) { + if (val != null) + return val; + + try { + assert valBytes != null; + + Object val = ctx.processor().unmarshal(ctx, valBytes, start, len, + ctx.kernalContext().config().getClassLoader()); + + if (ctx.storeValue()) + this.val = val; + + return val; + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshall object.", e); + } } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/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 2ca7687..2709f60 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 @@ -724,7 +724,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V Object val = CU.value(cacheVal, ctx, true); - val = ctx.unwrapPortableIfNeeded(val, ctx.keepPortable()); + val = ctx.unwrapIfNeeded(val, ctx.keepPortable()); return (V)val; } @@ -3775,7 +3775,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V Object val0 = val != null ? val.value(ctx.cacheObjectContext(), true) : null; - return (V)ctx.unwrapPortableIfNeeded(val0, !deserializePortable); + return (V)ctx.unwrapIfNeeded(val0, !deserializePortable); } /** {@inheritDoc} */ @@ -4588,10 +4588,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V Object key0 = key.value(ctx.cacheObjectContext(), true); Object val0 = val.value(ctx.cacheObjectContext(), true); - if (deserializePortable) { - key0 = ctx.unwrapPortableIfNeeded(key0, true); - val0 = ctx.unwrapPortableIfNeeded(val0, true); - } + key0 = ctx.unwrapIfNeeded(key0, !deserializePortable); + val0 = ctx.unwrapIfNeeded(val0, !deserializePortable); return new CacheEntryImpl<>((K)key0, (V)val0); } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/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 8a4e3b9..d7bb295 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 @@ -1678,26 +1678,26 @@ public class GridCacheContext<K, V> implements Externalizable { } /** - * Unwraps collection. + * Unwraps collection if needed. * * @param col Collection to unwrap. - * @param keepPortable Keep portable flag. + * @param keepPortable Keep portable flag. Used for portable objects only. Ignored in other cases. * @return Unwrapped collection. */ - public Collection<Object> unwrapPortablesIfNeeded(Collection<Object> col, boolean keepPortable) { - return cacheObjCtx.unwrapPortablesIfNeeded(col, keepPortable); + public Collection<Object> unwrapIfNeeded(Collection<Object> col, boolean keepPortable) { + return cacheObjCtx.unwrapIfNeeded(col, keepPortable); } /** - * Unwraps object for portables. + * Unwraps object if needed. * * @param o Object to unwrap. - * @param keepPortable Keep portable flag. + * @param keepPortable Keep portable flag. Used for portable objects only. Ignored in other cases. * @return Unwrapped object. */ @SuppressWarnings("IfMayBeConditional") - public Object unwrapPortableIfNeeded(Object o, boolean keepPortable) { - return cacheObjCtx.unwrapPortableIfNeeded(o, keepPortable); + public Object unwrapIfNeeded(Object o, boolean keepPortable) { + return cacheObjCtx.unwrapIfNeeded(o, keepPortable); } /** @@ -1795,12 +1795,10 @@ public class GridCacheContext<K, V> implements Externalizable { Object key0 = key.value(cacheObjCtx, false); Object val0 = skipVals ? true : val.value(cacheObjCtx, cpy); - if (deserializePortable) { - key0 = unwrapPortableIfNeeded(key0, false); + key0 = unwrapIfNeeded(key0, !deserializePortable); - if (!skipVals) - val0 = unwrapPortableIfNeeded(val0, false); - } + if (!skipVals) + val0 = unwrapIfNeeded(val0, !deserializePortable); assert key0 != null : key; assert val0 != null : val; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java index 8322e7a..56e6fe2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheOptimizedObjectImpl.java @@ -57,10 +57,7 @@ public class KeyCacheOptimizedObjectImpl extends CacheOptimizedObjectImpl implem /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) { - //return (T)this; - assert val != null; - - return (T)val; + return (T)this; } /** {@inheritDoc} */ @@ -82,6 +79,13 @@ public class KeyCacheOptimizedObjectImpl extends CacheOptimizedObjectImpl implem } /** {@inheritDoc} */ + @Override public Object deserialize(CacheObjectContext ctx) { + assert val != null; + + return val; + } + + /** {@inheritDoc} */ @Override public int hashCode() { assert val != null; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java index 74438bb..06aae28 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java @@ -499,8 +499,8 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma K key0 = key.value(cctx.cacheObjectContext(), true); V val0 = v.value(cctx.cacheObjectContext(), true); - val0 = (V)cctx.unwrapPortableIfNeeded(val0, !deserializePortable); - key0 = (K)cctx.unwrapPortableIfNeeded(key0, !deserializePortable); + val0 = (V)cctx.unwrapIfNeeded(val0, !deserializePortable); + key0 = (K)cctx.unwrapIfNeeded(key0, !deserializePortable); add(new GridFinishedFuture<>(Collections.singletonMap(key0, val0))); } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java index a8bace0..31d008f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryFutureAdapter.java @@ -380,7 +380,7 @@ public abstract class GridCacheQueryFutureAdapter<K, V, R> extends GridFutureAda data = dedupIfRequired((Collection<Object>)data); - data = cctx.unwrapPortablesIfNeeded((Collection<Object>)data, qry.query().keepPortable()); + data = cctx.unwrapIfNeeded((Collection<Object>)data, qry.query().keepPortable()); synchronized (mux) { enqueue(data); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/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 1317d38..073bf79 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 @@ -894,7 +894,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte private boolean checkPredicate(Map.Entry<K, V> e) { if (keyValFilter != null) { - Map.Entry<K, V> e0 = (Map.Entry<K, V>)cctx.unwrapPortableIfNeeded(e, qry.keepPortable()); + Map.Entry<K, V> e0 = (Map.Entry<K, V>)cctx.unwrapIfNeeded(e, qry.keepPortable()); return keyValFilter.apply(e0.getKey(), e0.getValue()); } @@ -1030,8 +1030,8 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte final LazySwapEntry e = new LazySwapEntry(it.next()); if (filter != null) { - K key = (K)cctx.unwrapPortableIfNeeded(e.key(), keepPortable); - V val = (V)cctx.unwrapPortableIfNeeded(e.value(), keepPortable); + K key = (K)cctx.unwrapIfNeeded(e.key(), keepPortable); + V val = (V)cctx.unwrapIfNeeded(e.value(), keepPortable); if (!filter.apply(key, val)) continue; @@ -1440,7 +1440,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte // Unwrap entry for reducer or transformer only. if (rdc != null || trans != null) - entry = (Map.Entry<K, V>)cctx.unwrapPortableIfNeeded(entry, qry.keepPortable()); + entry = (Map.Entry<K, V>)cctx.unwrapIfNeeded(entry, qry.keepPortable()); // Reduce. if (rdc != null) { @@ -2534,8 +2534,8 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte throws IgniteCheckedException { LazyOffheapEntry e = new LazyOffheapEntry(keyPtr, valPtr); - K key = (K)cctx.unwrapPortableIfNeeded(e.key(), keepPortable); - V val = (V)cctx.unwrapPortableIfNeeded(e.value(), keepPortable); + K key = (K)cctx.unwrapIfNeeded(e.key(), keepPortable); + V val = (V)cctx.unwrapIfNeeded(e.value(), keepPortable); if (!filter.apply(key, val)) return null; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/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 b4a146a..32882ff 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 @@ -31,6 +31,7 @@ import org.apache.ignite.internal.util.typedef.*; import org.apache.ignite.internal.util.typedef.internal.*; import org.apache.ignite.lang.*; import org.apache.ignite.lifecycle.*; +import org.apache.ignite.marshaller.optimized.*; import org.apache.ignite.transactions.*; import org.jetbrains.annotations.*; @@ -244,8 +245,8 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt Object storeKey = key.value(cctx.cacheObjectContext(), false); - if (convertPortable()) - storeKey = cctx.unwrapPortableIfNeeded(storeKey, false); + if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(storeKey) || convertPortable()) + storeKey = cctx.unwrapIfNeeded(storeKey, false); if (log.isDebugEnabled()) log.debug("Loading value from store for key: " + storeKey); @@ -371,10 +372,10 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt Collection<Object> keys0; - if (convertPortable()) { + if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(keys) || convertPortable()) { keys0 = F.viewReadOnly(keys, new C1<KeyCacheObject, Object>() { @Override public Object apply(KeyCacheObject key) { - return cctx.unwrapPortableIfNeeded(key.value(cctx.cacheObjectContext(), false), false); + return cctx.unwrapIfNeeded(key.value(cctx.cacheObjectContext(), false), false); } }); } @@ -505,9 +506,11 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt if (key instanceof GridCacheInternal) return true; - if (convertPortable()) { - key = cctx.unwrapPortableIfNeeded(key, false); - val = cctx.unwrapPortableIfNeeded(val, false); + if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(key) || + OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(val) || + convertPortable()) { + key = cctx.unwrapIfNeeded(key, false); + val = cctx.unwrapIfNeeded(val, false); } if (log.isDebugEnabled()) @@ -610,8 +613,8 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt if (key instanceof GridCacheInternal) return false; - if (convertPortable()) - key = cctx.unwrapPortableIfNeeded(key, false); + if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(key) || convertPortable()) + key = cctx.unwrapIfNeeded(key, false); if (log.isDebugEnabled()) log.debug("Removing value from cache store [key=" + key + ']'); @@ -659,7 +662,7 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt } if (store != null) { - Collection<Object> keys0 = convertPortable() ? cctx.unwrapPortablesIfNeeded(keys, false) : keys; + Collection<Object> keys0 = convertPortable() ? cctx.unwrapIfNeeded(keys, false) : keys; if (log.isDebugEnabled()) log.debug("Removing values from cache store [keys=" + keys0 + ']'); @@ -1076,9 +1079,11 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt Object v = locStore ? e.getValue() : e.getValue().get1(); - if (convertPortable()) { - k = cctx.unwrapPortableIfNeeded(k, false); - v = cctx.unwrapPortableIfNeeded(v, false); + if (OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(k) || + OptimizedMarshallerUtils.isObjectWithIndexedFieldsOrCollection(v) || + convertPortable()) { + k = cctx.unwrapIfNeeded(k, false); + v = cctx.unwrapIfNeeded(v, false); } next = new CacheEntryImpl<>(k, v); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java index 0a6a188..42ccbce 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java @@ -98,6 +98,13 @@ public interface IgniteCacheObjectProcessor extends GridProcessor { public boolean hasField(Object obj, String fieldName); /** + * Checks whether this functionality is globally supported. + * + * @return {@code true} if enabled. + */ + public boolean isFieldsIndexingEnabled(); + + /** * Checks whether fields indexing is supported by footer injection into a serialized form of the object. * Footer contains information about fields location in the serialized form, thus enabling fast queries without * a need to deserialize the object. @@ -105,9 +112,9 @@ public interface IgniteCacheObjectProcessor extends GridProcessor { * Indexing is enabled with {@link OptimizedMarshallerExt#enableFieldsIndexing(Class)}. * * @param cls Class. - * @return {@code true} if the footer is supported. + * @return {@code true} if the footer is enabled. */ - public boolean isFieldsIndexingSupported(Class<?> cls); + public boolean isFieldsIndexingEnabled(Class<?> cls); /** * Tries to enables fields indexing for the object of the given {@code cls}. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/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 6d222dc..64aa064 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 @@ -28,6 +28,7 @@ import org.apache.ignite.internal.util.*; import org.apache.ignite.internal.util.typedef.internal.*; import org.apache.ignite.lang.*; import org.apache.ignite.marshaller.*; +import org.apache.ignite.marshaller.optimized.*; import org.apache.ignite.marshaller.optimized.ext.*; import org.jetbrains.annotations.*; @@ -193,10 +194,10 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme @SuppressWarnings("ExternalizableWithoutPublicNoArgConstructor") protected KeyCacheObject toCacheKeyObject0(Object obj, boolean userObj) { if (!userObj) - return isFieldsIndexingSupported(obj.getClass()) ? new KeyCacheOptimizedObjectImpl(obj, null) : + return isFieldsIndexingEnabled(obj.getClass()) ? new KeyCacheOptimizedObjectImpl(obj, null) : new KeyCacheObjectImpl(obj, null); - return isFieldsIndexingSupported(obj.getClass()) ? new UserKeyCacheOptimizedObjectImpl(obj) : + return isFieldsIndexingEnabled(obj.getClass()) ? new UserKeyCacheOptimizedObjectImpl(obj) : new UserKeyCacheObjectImpl(obj); } @@ -268,10 +269,10 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme } if (!userObj) - return isFieldsIndexingSupported(obj.getClass()) ? new CacheOptimizedObjectImpl(obj) : + return isFieldsIndexingEnabled(obj.getClass()) ? new CacheOptimizedObjectImpl(obj) : new CacheObjectImpl(obj, null); - return isFieldsIndexingSupported(obj.getClass()) ? new UserCacheOptimizedObjectImpl(obj, null) : + return isFieldsIndexingEnabled(obj.getClass()) ? new UserCacheOptimizedObjectImpl(obj, null) : new UserCacheObjectImpl(obj, null); } @@ -305,9 +306,16 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme /** {@inheritDoc} */ @Override public int typeId(String typeName) { - return 0; + return optMarshExt != null ? OptimizedMarshallerUtils.resolveTypeId(typeName, optMarshExt.idMapper()) : 0; } + /** {@inheritDoc} */ + @Override public int typeId(Object obj) { + if (obj instanceof CacheOptimizedObjectImpl) + return ((CacheOptimizedObjectImpl)obj).typeId(); + + return 0; + } /** {@inheritDoc} */ @Override public Object unwrapTemporary(GridCacheContext ctx, Object obj) throws IgniteException { @@ -325,11 +333,6 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme } /** {@inheritDoc} */ - @Override public int typeId(Object obj) { - return 0; - } - - /** {@inheritDoc} */ @Override public Object field(Object obj, String fieldName) { if (obj instanceof CacheOptimizedObjectImpl) { assert optMarshExt != null; @@ -362,7 +365,12 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme } /** {@inheritDoc} */ - @Override public boolean isFieldsIndexingSupported(Class<?> cls) { + @Override public boolean isFieldsIndexingEnabled() { + return optMarshExt != null; + } + + /** {@inheritDoc} */ + @Override public boolean isFieldsIndexingEnabled(Class<?> cls) { return optMarshExt != null && optMarshExt.fieldsIndexingEnabled(cls); } @@ -468,7 +476,7 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme /** * Wraps value provided by user, must be serialized before stored in cache. - * Used by classes that support fields indexing. Refer to {@link #isFieldsIndexingSupported(Class)}. + * Used by classes that support fields indexing. Refer to {@link #isFieldsIndexingEnabled(Class)}. */ private static class UserCacheOptimizedObjectImpl extends CacheOptimizedObjectImpl { /** */ @@ -519,7 +527,7 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme /** * Wraps key provided by user, must be serialized before stored in cache. - * Used by classes that support fields indexing. Refer to {@link #isFieldsIndexingSupported(Class)}. + * Used by classes that support fields indexing. Refer to {@link #isFieldsIndexingEnabled(Class)}. */ private static class UserKeyCacheOptimizedObjectImpl extends KeyCacheOptimizedObjectImpl { /** */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java index 3dc7ddc..ee26609 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryCacheObjectsIterator.java @@ -60,7 +60,7 @@ public class GridQueryCacheObjectsIterator implements Iterator<List<?>>, AutoClo /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public List<?> next() { - return (List<?>)cctx.unwrapPortablesIfNeeded((Collection<Object>)iter.next(), keepPortable); + return (List<?>)cctx.unwrapIfNeeded((Collection<Object>)iter.next(), keepPortable); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/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 fe7c952..3e7948e 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 @@ -143,7 +143,7 @@ public class GridQueryProcessor extends GridProcessorAdapter { else if (ctx.cacheObjects().enableFieldsIndexing(valCls)) { processIndexedFieldsMeta(meta, desc); - typeId = new TypeId(ccfg.getName(), valCls); + typeId = new TypeId(ccfg.getName(), ctx.cacheObjects().typeId(valCls.getName())); } else { processClassMeta(meta, desc); @@ -454,8 +454,9 @@ public class GridQueryProcessor extends GridProcessorAdapter { TypeId id; boolean portableVal = ctx.cacheObjects().isPortableObject(val); + boolean indexedFieldsVal = val instanceof CacheOptimizedObjectImpl; - if (portableVal) { + if (portableVal || indexedFieldsVal) { int typeId = ctx.cacheObjects().typeId(val); id = new TypeId(space, typeId); @@ -471,12 +472,12 @@ public class GridQueryProcessor extends GridProcessorAdapter { if (desc == null || !desc.registered()) return; - if (!portableVal && !desc.valueClass().isAssignableFrom(valCls)) + if (!portableVal && !indexedFieldsVal && !desc.valueClass().isAssignableFrom(valCls)) throw new IgniteCheckedException("Failed to update index due to class name conflict" + "(multiple classes with same simple name are stored in the same cache) " + "[expCls=" + desc.valueClass().getName() + ", actualCls=" + valCls.getName() + ']'); - if (!ctx.cacheObjects().isPortableObject(key)) { + if (!(key instanceof CacheOptimizedObjectImpl) && !ctx.cacheObjects().isPortableObject(key)) { Class<?> keyCls = key.value(coctx, false).getClass(); if (!desc.keyClass().isAssignableFrom(keyCls)) http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java index 6be90c5..d76aac2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java @@ -109,12 +109,10 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { /** {@inheritDoc} */ @Override public void bytes(byte[] bytes, int off, int len) { buf = bytes; - - max = len; + max = len + off; this.off = off; } - /** {@inheritDoc} */ @Override public void inputStream(InputStream in) throws IOException { this.in = in; @@ -122,7 +120,6 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { buf = inBuf; } - /** * Reads from stream to buffer. If stream is {@code null}, this method is no-op. * http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/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 61cbcee..2f42e8d 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 @@ -18,6 +18,7 @@ package org.apache.ignite.marshaller.optimized; import org.apache.ignite.*; +import org.apache.ignite.internal.processors.cache.*; import org.apache.ignite.internal.util.*; import org.apache.ignite.internal.util.typedef.*; import org.apache.ignite.marshaller.*; @@ -237,6 +238,28 @@ 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 CacheOptimizedObjectImpl || + 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/25d0da2d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java index 8e2653b..1a451e1 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedMarshallerExt.java @@ -72,6 +72,15 @@ public class OptimizedMarshallerExt extends OptimizedMarshaller { } /** + * Returns currently set ID mapper. + * + * @return ID mapper. + */ + public OptimizedMarshallerIdMapper idMapper() { + return mapper; + } + + /** * Enables fields indexing for the object of the given {@code cls}. * * If enabled then a footer will be added during marshalling of an object of the given {@code cls} to the end of http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java index 977a988..7ab56a2 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/ext/OptimizedObjectInputStreamExt.java @@ -83,7 +83,7 @@ public class OptimizedObjectInputStreamExt extends OptimizedObjectInputStream { return false; } - FieldRange range = fieldRange(fieldName); + FieldRange range = fieldRange(fieldName, pos); in.position(pos); @@ -108,7 +108,7 @@ public class OptimizedObjectInputStreamExt extends OptimizedObjectInputStream { return null; } - FieldRange range = fieldRange(fieldName); + FieldRange range = fieldRange(fieldName, pos); F field = null; @@ -133,10 +133,11 @@ public class OptimizedObjectInputStreamExt extends OptimizedObjectInputStream { * Returns field offset in the byte stream. * * @param fieldName Field name. + * @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. */ - private FieldRange fieldRange(String fieldName) throws IOException { + private FieldRange fieldRange(String fieldName, int start) throws IOException { int fieldId = resolveFieldId(fieldName); int typeId = readInt(); @@ -177,7 +178,7 @@ public class OptimizedObjectInputStreamExt extends OptimizedObjectInputStream { //object header len: 1 - for type, 4 - for type ID, 2 - for checksum. fieldOff += 1 + 4 + clsNameLen + 2; - return new FieldRange(fieldOff, info.len == VARIABLE_LEN ? in.readShort() : info.len); + return new FieldRange(start + fieldOff, info.len == VARIABLE_LEN ? in.readShort() : info.len); } else fieldOff += info.len == VARIABLE_LEN ? in.readShort() : info.len; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/25d0da2d/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java index 77e48c1..d9f85aa 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java @@ -108,7 +108,22 @@ public class IgniteCacheOptimizedMarshallerExtQuerySelfTest extends GridCacheAbs * @throws Exception In case of error. */ public void testNestedFieldsQuery() throws Exception { + IgniteCache<Integer, Person> cache = grid(0).cache(null); + + Collection<Cache.Entry<Integer, Person>> entries = cache.query(new SqlQuery<Integer, Person>( + "Person", "name is not null AND (zip = 1 OR zip = 2)")).getAll(); + + assertEquals(2, entries.size()); + for (Cache.Entry<Integer, Person> entry : entries) { + int id = entry.getKey(); + Person p = entry.getValue(); + + assertEquals("Person " + id, p.name); + assertEquals((id + 1) * 100, p.salary); + assertEquals("Street " + id, p.address.street); + assertEquals(id, p.address.zip); + } } /**