]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.indexing/src/org/simantics/db/indexing/IndexUtils.java
Added new field TypeId to dependency index for exact type searching
[simantics/platform.git] / bundles / org.simantics.db.indexing / src / org / simantics / db / indexing / IndexUtils.java
index e089deb029897f7c2a63a456c34ccf80aa4cd70a..760acd68c465578b269cdf12e164dafbb65a2516 100644 (file)
-package org.simantics.db.indexing;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.apache.lucene.index.Term;\r
-import org.apache.lucene.util.BytesRef;\r
-import org.apache.lucene.util.NumericUtils;\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.NullProgressMonitor;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.util.Layer0Utils;\r
-import org.simantics.db.service.CollectionSupport;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.operation.Layer0X;\r
-\r
-public class IndexUtils {\r
-\r
-    public static Collection<Map<String, Object>> find(ReadGraph graph, Resource index, String filter) throws DatabaseException {\r
-       \r
-        Collection<Map<String, Object>> indexResult = graph.syncRequest(new QueryIndex(index, filter), TransientCacheListener.<Collection<Map<String, Object>>>instance());\r
-\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        Collection<Resource> linkedRoots = graph.syncRequest(new ObjectsWithType(index, L0.IsLinkedTo, L0.IndexRoot));\r
-        if (linkedRoots.isEmpty())\r
-            return indexResult;\r
-\r
-        Collection<Map<String, Object>> result = indexResult;\r
-        for (Resource dep : linkedRoots) {\r
-            Collection<Map<String, Object>> linkedIndexResults = find(graph, dep, filter);\r
-            if (linkedIndexResults.isEmpty())\r
-                continue;\r
-            if (result == indexResult) {\r
-                result = new ArrayList<Map<String, Object>>(indexResult.size() + linkedIndexResults.size());\r
-                result.addAll(indexResult);\r
-            } else {\r
-            }\r
-            result.addAll(linkedIndexResults);\r
-        }\r
-        \r
-        return result;\r
-        \r
-    }\r
-\r
-    public static List<Resource> findResources(ReadGraph graph, Resource index, String filter) throws DatabaseException {\r
-       \r
-       List<Resource> indexResult = graph.syncRequest(new QueryIndexResources(index, filter), TransientCacheListener.<List<Resource>>instance());\r
-\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        CollectionSupport coll = graph.getService(CollectionSupport.class);\r
-        \r
-        Collection<Resource> linkedRoots = graph.syncRequest(new ObjectsWithType(index, L0.IsLinkedTo, L0.IndexRoot));\r
-        if (linkedRoots.isEmpty())\r
-            return indexResult;\r
-\r
-        List<Resource> result = indexResult;\r
-        for (Resource dep : linkedRoots) {\r
-            Collection<Resource> linkedIndexResults = findResources(graph, dep, filter);\r
-            if (linkedIndexResults.isEmpty())\r
-                continue;\r
-            if (result == indexResult) {\r
-               result = coll.createList();\r
-                result.addAll(indexResult);\r
-            }\r
-            result.addAll(linkedIndexResults);\r
-        }\r
-        \r
-        Layer0Utils.sort(graph, result);\r
-        return result;\r
-        \r
-    }\r
-    \r
-    public static Collection<Resource> findByName(ReadGraph graph, Resource model, String name) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        HashSet<Resource> results = new HashSet<Resource>();\r
-        \r
-               String search = "Name:" + name;\r
-\r
-        for(Map<String, Object> entry : find(graph, model, search)) {\r
-               Resource resource = (Resource)entry.get("Resource");\r
-            if(name.equals(graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING))) results.add(resource);\r
-        }\r
-        return results;\r
-    }\r
-\r
-    public static Collection<Resource> findByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException {\r
-       \r
-        HashSet<Resource> results = new HashSet<Resource>();\r
-        \r
-               String search = "Types:*" + NameUtils.getSafeName(graph, type);\r
-\r
-        for(Map<String, Object> entry : find(graph, model, search)) {\r
-               Resource resource = (Resource)entry.get("Resource");\r
-               if(graph.isInstanceOf(resource, type)) results.add(resource);\r
-        }\r
-        return results;\r
-    }\r
-\r
-    public static Collection<Resource> findByTypeAndName(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {\r
-       \r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        \r
-        HashSet<Resource> results = new HashSet<Resource>();\r
-        \r
-               String search = "Types:*" + type + " AND Name:" + name;\r
-\r
-        for(Map<String, Object> entry : find(graph, model, search)) {\r
-               Resource resource = (Resource)entry.get("Resource");\r
-               if(graph.isInstanceOf(resource, type) && name.equals(graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING))) results.add(resource);\r
-        }\r
-        return results;\r
-    }\r
-    \r
-    public static void flushIndexCaches(IProgressMonitor progress, Session session) throws Exception {\r
-\r
-       MemoryIndexing mem = MemoryIndexing.getInstance(session);\r
-       mem.flush(progress);\r
-       \r
-    }\r
-    \r
-    public static List<Object> list(IProgressMonitor progress, Session session, Resource indexRoot) throws Exception {\r
-       \r
-       if(progress == null) progress = new NullProgressMonitor();\r
-\r
-       MemoryIndexing mem = MemoryIndexing.getInstance(session);\r
-       Layer0X L0X = Layer0X.getInstance(session);\r
-\r
-       mem.flush(progress);\r
-               \r
-       IndexedRelationsSearcher searcher = mem.get(session, L0X.DependenciesRelation, indexRoot);\r
-       return searcher.doList(progress, session);\r
-       \r
-    }\r
-    \r
-    public static Term longTerm(String key, Long value) {\r
-       BytesRef ref = new BytesRef();    \r
-       NumericUtils.longToPrefixCoded( value, 0, ref );\r
-       return new Term(key, ref);\r
-    }\r
-\r
-}\r
+package org.simantics.db.indexing;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.NumericUtils;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.indexing.exception.IndexCorruptedException;
+import org.simantics.db.layer0.genericrelation.Dependencies;
+import org.simantics.db.layer0.genericrelation.IndexQueries;
+import org.simantics.db.layer0.genericrelation.IndexedRelations;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.service.CollectionSupport;
+import org.simantics.layer0.Layer0;
+import org.simantics.operation.Layer0X;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IndexUtils {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(IndexUtils.class);
+
+    public static Collection<Map<String, Object>> find(ReadGraph graph, Resource index, String filter) throws DatabaseException {
+       
+        Collection<Map<String, Object>> indexResult = graph.syncRequest(new QueryIndex(index, filter), TransientCacheListener.<Collection<Map<String, Object>>>instance());
+
+        Layer0 L0 = Layer0.getInstance(graph);
+        Collection<Resource> linkedRoots = graph.syncRequest(new ObjectsWithType(index, L0.IsLinkedTo, L0.IndexRoot));
+        if (linkedRoots.isEmpty())
+            return indexResult;
+
+        Collection<Map<String, Object>> result = indexResult;
+        for (Resource dep : linkedRoots) {
+            Collection<Map<String, Object>> linkedIndexResults = find(graph, dep, filter);
+            if (linkedIndexResults.isEmpty())
+                continue;
+            if (result == indexResult) {
+                result = new ArrayList<Map<String, Object>>(indexResult.size() + linkedIndexResults.size());
+                result.addAll(indexResult);
+            } else {
+            }
+            result.addAll(linkedIndexResults);
+        }
+        
+        return result;
+        
+    }
+
+    public static List<Resource> findResources(ReadGraph graph, Resource index, String filter) throws DatabaseException {
+       
+       List<Resource> indexResult = graph.syncRequest(new QueryIndexResources(index, filter), TransientCacheListener.<List<Resource>>instance());
+
+        Layer0 L0 = Layer0.getInstance(graph);
+        CollectionSupport coll = graph.getService(CollectionSupport.class);
+        
+        Collection<Resource> linkedRoots = graph.syncRequest(new ObjectsWithType(index, L0.IsLinkedTo, L0.IndexRoot));
+        if (linkedRoots.isEmpty())
+            return indexResult;
+
+        List<Resource> result = indexResult;
+        for (Resource dep : linkedRoots) {
+            Collection<Resource> linkedIndexResults = findResources(graph, dep, filter);
+            if (linkedIndexResults.isEmpty())
+                continue;
+            if (result == indexResult) {
+               result = coll.createList();
+                result.addAll(indexResult);
+            }
+            result.addAll(linkedIndexResults);
+        }
+        
+        Layer0Utils.sort(graph, result);
+        return result;
+        
+    }
+    
+    public static Collection<Resource> findByName(ReadGraph graph, Resource model, String name) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        HashSet<Resource> results = new HashSet<Resource>();
+
+        String search = IndexQueries.quoteTerm(Dependencies.FIELD_NAME, name);
+
+        for(Resource resource : findResources(graph, model, search)) {
+            if(name.equals(graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING))) results.add(resource);
+        }
+        return results;
+    }
+
+    public static Collection<Resource> findByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException {
+        HashSet<Resource> results = new HashSet<>();
+        String search = IndexQueries.resourceIdTerm(Dependencies.FIELD_TYPE_RESOURCE, type);
+
+        for(Resource resource : findResources(graph, model, search)) {
+            if(graph.isInstanceOf(resource, type)) results.add(resource);
+        }
+        return results;
+    }
+
+    public static Collection<Resource> findByTypeAndName(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {
+        HashSet<Resource> results = new HashSet<Resource>();
+        String search = IndexQueries.and(IndexQueries.resourceIdTerm(Dependencies.FIELD_TYPE_RESOURCE, type), IndexQueries.quoteTerm(Dependencies.FIELD_NAME, name));
+
+        for(Resource resource : findResources(graph, model, search)) {
+            if(graph.isInstanceOf(resource, type)) results.add(resource);
+        }
+        return results;
+    }
+    
+    public static void flushIndexCaches(IProgressMonitor progress, Session session) throws Exception {
+
+       MemoryIndexing mem = MemoryIndexing.getInstance(session);
+       mem.flush(progress);
+       
+    }
+    
+    public static List<Object> list(IProgressMonitor progress, Session session, Resource indexRoot) throws Exception {
+       
+       if(progress == null) progress = new NullProgressMonitor();
+
+       MemoryIndexing mem = MemoryIndexing.getInstance(session);
+       Layer0X L0X = Layer0X.getInstance(session);
+
+       mem.flush(progress);
+               
+       IndexedRelationsSearcher searcher = mem.get(session, L0X.DependenciesRelation, indexRoot);
+        List<Object> results;
+        try {
+            results = searcher.doList(progress, session);
+        } catch (IndexCorruptedException e) {
+            LOGGER.error("Index is corrupted for indexRoot {}", indexRoot, e);
+            rebuild(session, progress);
+            // if this fails then no can do
+            searcher = mem.get(session, L0X.DependenciesRelation, indexRoot);
+            results = searcher.doList(progress, session);
+        }
+        return results;
+    }
+    
+    private static void rebuild(Session session, IProgressMonitor monitor) throws Exception {
+        LOGGER.error("Trying to rebuild index");
+        DatabaseIndexing.deleteAllIndexes();
+        session.getService(IndexedRelations.class).fullRebuild(SubMonitor.convert(monitor, 100), session);
+    }
+
+    public static Term longTerm(String key, Long value) {
+       BytesRef ref = new BytesRef();    
+       NumericUtils.longToPrefixCoded( value, 0, ref );
+       return new Term(key, ref);
+    }
+
+}