]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.indexing/src/org/simantics/db/indexing/MemoryIndexing.java
7f86d2bc1635fe762d40c4321632448ab916ff87
[simantics/platform.git] / bundles / org.simantics.db.indexing / src / org / simantics / db / indexing / MemoryIndexing.java
1 package org.simantics.db.indexing;
2
3 import java.io.IOException;
4 import java.nio.file.Path;
5 import java.util.ArrayList;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.concurrent.ConcurrentHashMap;
9
10 import org.apache.lucene.analysis.Analyzer;
11 import org.apache.lucene.index.IndexWriter;
12 import org.apache.lucene.index.IndexWriterConfig;
13 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
14 import org.apache.lucene.store.Directory;
15 import org.apache.lucene.store.RAMDirectory;
16 import org.apache.lucene.util.Version;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.simantics.db.RequestProcessor;
19 import org.simantics.db.Resource;
20 import org.simantics.db.Session;
21 import org.simantics.db.common.SimanticsInternal;
22 import org.simantics.db.common.request.Adapt;
23 import org.simantics.db.layer0.adapter.GenericRelation;
24 import org.simantics.db.layer0.genericrelation.IndexedRelations;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * @author Tuukka Lehtonen
29  * @author Antti Villberg
30  */
31 public class MemoryIndexing {
32
33     private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(MemoryIndexing.class);
34
35     final private Session session;
36
37     final Map<String,Map<String,List<Map<String, Object>>>> persistentCache = new ConcurrentHashMap<>();
38     final Map<String,Map<String,List<Resource>>> persistentCacheResources = new ConcurrentHashMap<>();
39
40     final private ConcurrentHashMap<String,RAMDirectory> directories = new ConcurrentHashMap<>();
41
42     final private ConcurrentHashMap<String,IndexedRelationsSearcherBase> immutableSearchers = new ConcurrentHashMap<>();
43     final private ConcurrentHashMap<String,IndexedRelationsSearcher> searchers = new ConcurrentHashMap<>();
44
45     public MemoryIndexing(Session session) {
46         this.session = session;
47     }
48
49     protected Path getIndexDirectory(Resource relation, Resource input) {
50         return DatabaseIndexing.getIndexLocation(session, relation, input);
51     }
52
53     List<IndexedRelationsSearcherBase> getAllSearchers() {
54         List<IndexedRelationsSearcherBase> r = new ArrayList<>();
55         r.addAll(searchers.values());
56         r.addAll(immutableSearchers.values());
57         return r;
58     }
59
60     public IndexedRelationsSearcher get(RequestProcessor processor, Resource relation, Resource input) {
61         Path location = getIndexDirectory(relation, input);
62         String key = location.toAbsolutePath().toString();
63         return searchers.computeIfAbsent(key, t -> {
64             try {
65                 GenericRelation r = processor.sync(new Adapt<GenericRelation>(relation, GenericRelation.class));
66                 return new IndexedRelationsSearcher(processor, relation, input, r);
67             } catch (Exception e) {
68                 LOGGER.error("Could not get searcher for relation {} and input {} in location {}", relation, input, location, e);
69                 return null;
70             }
71         });
72     }
73
74     public IndexedRelationsSearcherBase getImmutable(RequestProcessor processor, Resource relation, Resource input) {
75         Path location = getIndexDirectory(relation, input);
76         String key = location.toAbsolutePath().toString();
77         return immutableSearchers.computeIfAbsent(key, t -> {
78             try {
79                 return new ImmutableIndexedRelationsSearcher(processor, relation, input);
80             } catch (Exception e) {
81                 LOGGER.error("Could not get searcher base for relation {} and input {} in location {}", relation, input, location, e);
82                 return null;
83             }
84         });
85     }
86     
87     public static MemoryIndexing getInstance(Session session) {
88         MemoryIndexing ret = session.peekService(MemoryIndexing.class);
89         if(ret == null) {
90             ret = new MemoryIndexing(session);
91             session.registerService(MemoryIndexing.class, ret);
92         }
93         return ret;
94     }
95     
96     public Directory getDirectory(String path, Analyzer analyzer) throws IOException {
97         try {
98             return directories.computeIfAbsent(path, t -> {
99                 try {
100                     RAMDirectory directory = new RAMDirectory();
101                     IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_9, analyzer);
102                     new IndexWriter(directory, config.setOpenMode(OpenMode.CREATE)).close();
103                     return directory;
104                 } catch (IOException e) {
105                     throw new RuntimeException(e);
106                 }
107             });
108         } catch (RuntimeException e) {
109             throw (IOException) e.getCause();
110         }
111     }
112
113     public void remove(String path) {
114         directories.remove(path);
115     }
116
117     /**
118      * @param progress
119      * @throws Exception
120      * @deprecated Use {@link IndexUtils#flushIndexCaches(IProgressMonitor, Session)} instead
121      */
122     @Deprecated
123     public void flush(IProgressMonitor progress) throws Exception {
124         Session s = SimanticsInternal.getSession();
125         s.getService(IndexedRelations.class).flush(progress, s);
126     }
127
128 }