Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-950 99c88b7cb -> 74017faa5


ignite-950: processing CacheTypeMetadata for objects with footer enabled


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/74017faa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/74017faa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/74017faa

Branch: refs/heads/ignite-950
Commit: 74017faa5a1f29e5219e5ddf5faf14af402eb291
Parents: 99c88b7
Author: Denis Magda <dma...@gridgain.com>
Authored: Wed Jun 17 18:28:21 2015 +0300
Committer: Denis Magda <dma...@gridgain.com>
Committed: Wed Jun 17 18:28:21 2015 +0300

----------------------------------------------------------------------
 .../cache/CacheOptimizedObjectImpl.java         |   1 +
 .../cache/KeyCacheOptimizedObjectImpl.java      |   1 +
 .../cacheobject/IgniteCacheObjectProcessor.java |   9 +
 .../IgniteCacheObjectProcessorImpl.java         |   5 +
 .../processors/query/GridQueryProcessor.java    | 172 +++++++++++++++++++
 .../optimized/ext/OptimizedMarshallerExt.java   |  15 +-
 ...acheOptimizedMarshallerExtQuerySelfTest.java | 170 ++++++++++++++++++
 7 files changed, 371 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/74017faa/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 734451e..078b4de 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
@@ -92,6 +92,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 {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/74017faa/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 8da074e..8322e7a 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,6 +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;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/74017faa/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 1afc2fe..0a6a188 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
@@ -110,6 +110,15 @@ public interface IgniteCacheObjectProcessor extends 
GridProcessor {
     public boolean isFieldsIndexingSupported(Class<?> cls);
 
     /**
+     * Tries to enables fields indexing for the object of the given {@code 
cls}.
+     *
+     * @param cls Class.
+     * @return {@code true} if fields indexing is enabled.
+     * @throws IgniteCheckedException In case of error.
+     */
+    public boolean enableFieldsIndexing(Class<?> cls) throws 
IgniteCheckedException;
+
+    /**
      * @param ctx Cache object context.
      * @param val Value.
      * @return Value bytes.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/74017faa/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 fbbc514..6d222dc 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
@@ -366,6 +366,11 @@ public class IgniteCacheObjectProcessorImpl extends 
GridProcessorAdapter impleme
         return optMarshExt != null && optMarshExt.fieldsIndexingEnabled(cls);
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean enableFieldsIndexing(Class<?> cls) throws 
IgniteCheckedException {
+        return optMarshExt != null && optMarshExt.enableFieldsIndexing(cls);
+    }
+
     /**
      * Wraps key provided by user, must be serialized before stored in cache.
      */

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/74017faa/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 718e6ba..fe7c952 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
@@ -140,6 +140,11 @@ public class GridQueryProcessor extends 
GridProcessorAdapter {
 
                         typeId = new TypeId(ccfg.getName(), 
ctx.cacheObjects().typeId(meta.getValueType()));
                     }
+                    else if (ctx.cacheObjects().enableFieldsIndexing(valCls)) {
+                        processIndexedFieldsMeta(meta, desc);
+
+                        typeId = new TypeId(ccfg.getName(), valCls);
+                    }
                     else {
                         processClassMeta(meta, desc);
 
@@ -1302,6 +1307,82 @@ public class GridQueryProcessor extends 
GridProcessorAdapter {
     }
 
     /**
+     * Processes declarative metadata for object that has fields information 
in its serialized form.
+     *
+     * @param meta Declared metadata.
+     * @param d Type descriptor.
+     * @throws IgniteCheckedException If failed.
+     */
+    private void processIndexedFieldsMeta(CacheTypeMetadata meta, 
TypeDescriptor d)
+        throws IgniteCheckedException {
+        //TODO: IGNITE-950, refactor. The code is similar to portable 
properties ones.
+
+        for (Map.Entry<String, Class<?>> entry : 
meta.getAscendingFields().entrySet()) {
+            IndexedFieldsProperty prop = 
buildIndexedFieldsProperty(entry.getKey(), entry.getValue());
+
+            d.addProperty(prop, false);
+
+            String idxName = prop.name() + "_idx";
+
+            d.addIndex(idxName, idx.isGeometryClass(prop.type()) ? GEO_SPATIAL 
: SORTED);
+
+            d.addFieldToIndex(idxName, prop.name(), 0, false);
+        }
+
+        for (Map.Entry<String, Class<?>> entry : 
meta.getDescendingFields().entrySet()) {
+            IndexedFieldsProperty prop = 
buildIndexedFieldsProperty(entry.getKey(), entry.getValue());
+
+            d.addProperty(prop, false);
+
+            String idxName = prop.name() + "_idx";
+
+            d.addIndex(idxName, idx.isGeometryClass(prop.type()) ? GEO_SPATIAL 
: SORTED);
+
+            d.addFieldToIndex(idxName, prop.name(), 0, true);
+        }
+
+        for (String txtIdx : meta.getTextFields()) {
+            IndexedFieldsProperty prop = buildIndexedFieldsProperty(txtIdx, 
String.class);
+
+            d.addProperty(prop, false);
+
+            d.addFieldToTextIndex(prop.name());
+        }
+
+        Map<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> 
grps = meta.getGroups();
+
+        if (grps != null) {
+            for (Map.Entry<String, LinkedHashMap<String, 
IgniteBiTuple<Class<?>, Boolean>>> entry : grps.entrySet()) {
+                String idxName = entry.getKey();
+
+                LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>> 
idxFields = entry.getValue();
+
+                int order = 0;
+
+                for (Map.Entry<String, IgniteBiTuple<Class<?>, Boolean>> 
idxField : idxFields.entrySet()) {
+                    IndexedFieldsProperty prop = 
buildIndexedFieldsProperty(idxField.getKey(),
+                        idxField.getValue().get1());
+
+                    d.addProperty(prop, false);
+
+                    Boolean descending = idxField.getValue().get2();
+
+                    d.addFieldToIndex(idxName, prop.name(), order, descending 
!= null && descending);
+
+                    order++;
+                }
+            }
+        }
+
+        for (Map.Entry<String, Class<?>> entry : 
meta.getQueryFields().entrySet()) {
+            IndexedFieldsProperty prop = 
buildIndexedFieldsProperty(entry.getKey(), entry.getValue());
+
+            if (!d.props.containsKey(prop.name()))
+                d.addProperty(prop, false);
+        }
+    }
+
+    /**
      * Builds portable object property.
      *
      * @param pathStr String representing path to the property. May contains 
dots '.' to identify
@@ -1396,6 +1477,25 @@ public class GridQueryProcessor extends 
GridProcessorAdapter {
     }
 
     /**
+     * Builds property of object that has fields information in its serialized 
form.
+     *
+     * @param pathStr String representing path to the property. May contains 
dots '.' to identify
+     *      nested fields.
+     * @param resType Result type.
+     * @return Portable property.
+     */
+    private IndexedFieldsProperty buildIndexedFieldsProperty(String pathStr, 
Class<?> resType) {
+        String[] path = pathStr.split("\\.");
+
+        IndexedFieldsProperty res = null;
+
+        for (String prop : path)
+            res = new IndexedFieldsProperty(prop, res, resType);
+
+        return res;
+    }
+
+    /**
      * Gets types for space.
      *
      * @param space Space name.
@@ -1690,6 +1790,78 @@ public class GridQueryProcessor extends 
GridProcessorAdapter {
     }
 
     /**
+     *
+     */
+    private class IndexedFieldsProperty extends Property {
+        /** Property name. */
+        private String propName;
+
+        /** Parent property. */
+        private IndexedFieldsProperty parent;
+
+        /** Result class. */
+        private Class<?> type;
+
+        /** */
+        private volatile int isKeyProp;
+
+        /**
+         * Constructor.
+         *
+         * @param propName Property name.
+         * @param parent Parent property.
+         * @param type Result type.
+         */
+        private IndexedFieldsProperty(String propName, IndexedFieldsProperty 
parent, Class<?> type) {
+            this.propName = propName;
+            this.parent = parent;
+            this.type = type;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Object value(Object key, Object val) throws 
IgniteCheckedException {
+            Object obj;
+
+            if (parent != null) {
+                obj = parent.value(key, val);
+
+                if (obj == null)
+                    return null;
+            }
+            else {
+                int isKeyProp0 = isKeyProp;
+
+                if (isKeyProp0 == 0) {
+                    if (ctx.cacheObjects().hasField(key, propName))
+                        isKeyProp = isKeyProp0 = 1;
+                    else if (ctx.cacheObjects().hasField(val, propName))
+                        isKeyProp = isKeyProp0 = -1;
+                    else {
+                        U.warn(log, "Neither key nor value have property " +
+                            "[propName=" + propName + ", key=" + key + ", 
val=" + val + "]");
+
+                        return null;
+                    }
+                }
+
+                obj = isKeyProp0 == 1 ? key : val;
+            }
+
+            return ctx.cacheObjects().field(obj, propName);
+        }
+
+        /** {@inheritDoc} */
+        @Override public String name() {
+            return propName;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Class<?> type() {
+            return type;
+        }
+    }
+
+    /**
      * Descriptor of type.
      */
     private static class TypeDescriptor implements GridQueryTypeDescriptor {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/74017faa/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 ddbb1e5..8e2653b 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
@@ -44,6 +44,15 @@ public class OptimizedMarshallerExt extends 
OptimizedMarshaller {
     private OptimizedMarshallerExtMetaHandler metaHandler;
 
     /**
+     * Creates new marshaller will all defaults.
+     *
+     * @throws IgniteException If this marshaller is not supported on the 
current JVM.
+     */
+    public OptimizedMarshallerExt() {
+        // No-op
+    }
+
+    /**
      * Creates new marshaller providing whether it should
      * require {@link Serializable} interface or not.
      *
@@ -79,8 +88,10 @@ public class OptimizedMarshallerExt extends 
OptimizedMarshaller {
             OptimizedClassDescriptor desc = 
OptimizedMarshallerUtils.classDescriptor(clsMap, cls, ctx, mapper);
 
             if (desc.fields() != null && 
desc.fields().fieldsIndexingSupported()) {
-                if (metaHandler.metadata(desc.typeId()) != null)
-                    return true;
+                //The function is called on kernel startup, calling 
metaHandler.metadata() will hang the grid,
+                //because the underlying cache is not ready.
+                //if (metaHandler.metadata(desc.typeId()) != null)
+                //    return true;
 
                 OptimizedObjectMetadata meta = new OptimizedObjectMetadata();
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/74017faa/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
new file mode 100644
index 0000000..77e48c1
--- /dev/null
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheOptimizedMarshallerExtQuerySelfTest.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.cache.query.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.marshaller.optimized.ext.*;
+
+import javax.cache.*;
+import java.util.*;
+
+import static org.apache.ignite.cache.CacheMode.*;
+
+/**
+ * Tests queries with {@link OptimizedMarshallerExt} enabled.
+ */
+public class IgniteCacheOptimizedMarshallerExtQuerySelfTest extends 
GridCacheAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected int gridCount() {
+        return 3;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        OptimizedMarshallerExt marsh = new OptimizedMarshallerExt(false);
+
+        cfg.setMarshaller(marsh);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration cacheConfiguration(String gridName) 
throws Exception {
+        CacheConfiguration ccfg = super.cacheConfiguration(gridName);
+
+        ccfg.setTypeMetadata(cacheTypeMetadata());
+
+        ccfg.setCacheMode(PARTITIONED);
+        ccfg.setNearConfiguration(null);
+
+        return ccfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        IgniteCache<Object, Object> cache = grid(0).cache(null);
+
+        for (int i = 0; i < 50; i++) {
+            Address addr = new Address();
+
+            addr.street = "Street " + i;
+            addr.zip = i;
+
+            Person p = new Person();
+
+            p.name = "Person " + i;
+            p.salary = (i + 1) * 100;
+            p.address = addr;
+
+            cache.put(i, p);
+        }
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testSimpleQuery() 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")).getAll();
+
+        assertEquals(50, 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);
+        }
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testNestedFieldsQuery() throws Exception {
+
+    }
+
+    /**
+     * @return Cache type metadata.
+     */
+    private Collection<CacheTypeMetadata> cacheTypeMetadata() {
+        CacheTypeMetadata personMeta = new CacheTypeMetadata();
+
+        personMeta.setValueType(Person.class);
+
+        Map<String, Class<?>> personQryFields = new HashMap<>();
+
+        personQryFields.put("name", String.class);
+        personQryFields.put("salary", Integer.class);
+        personQryFields.put("address", Object.class);
+        personQryFields.put("address.zip", Integer.class);
+
+        personMeta.setQueryFields(personQryFields);
+
+
+        CacheTypeMetadata addrMeta = new CacheTypeMetadata();
+
+        addrMeta.setValueType(Address.class);
+
+        Map<String, Class<?>> addrQryFields = new HashMap<>();
+
+        addrQryFields.put("street", String.class);
+        addrQryFields.put("zip", Integer.class);
+
+        addrMeta.setQueryFields(addrQryFields);
+
+        return Arrays.asList(personMeta, addrMeta);
+    }
+
+    /**
+     *
+     */
+    private static class Person {
+        /** */
+        public String name;
+
+        /** */
+        public int salary;
+
+        /** */
+        public Address address;
+    }
+
+    /**
+     *
+     */
+    private static class Address {
+        /** */
+        public String street;
+
+        /** */
+        public int zip;
+    }
+}

Reply via email to