]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.indexing/src/org/simantics/db/indexing/MemoryIndexing.java
75c6b79bb51c6a1dc4da3b9c9e1064f3fbb93b25
[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.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
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.eclipse.core.runtime.SubMonitor;
19 import org.simantics.db.RequestProcessor;
20 import org.simantics.db.Resource;
21 import org.simantics.db.Session;
22 import org.simantics.db.common.request.Adapt;
23 import org.simantics.db.indexing.IndexedRelationsSearcherBase.State;
24 import org.simantics.db.layer0.adapter.GenericRelation;
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 HashMap<String,Map<String,List<Map<String, Object>>>>();
38     final Map<String,Map<String,List<Resource>>> persistentCacheResources = new HashMap<String,Map<String,List<Resource>>>();
39         
40     final private Map<String,RAMDirectory> directories = new HashMap<String,RAMDirectory>();
41     
42     final private Map<String,IndexedRelationsSearcherBase> immutableSearchers = new HashMap<String,IndexedRelationsSearcherBase>();
43     final private Map<String,IndexedRelationsSearcher> searchers = new HashMap<String,IndexedRelationsSearcher>();
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     public IndexedRelationsSearcher get(RequestProcessor processor, Resource relation, Resource input) {
54         Path location = getIndexDirectory(relation, input);
55         try {
56             String key = location.toAbsolutePath().toString();
57             IndexedRelationsSearcher searcher = searchers.get(key);
58             if (searcher == null) {
59                 GenericRelation r = processor.sync(new Adapt<GenericRelation>(relation, GenericRelation.class));
60                 searcher = new IndexedRelationsSearcher(processor, relation, input, r);
61                 searchers.put(key, searcher);
62             }
63             return searcher;
64         } catch (Exception e) {
65             LOGGER.error("Could not get searcher for relation {} and input {} in location {}", relation, input, location, e);
66             return null;
67         }
68     }
69
70     public IndexedRelationsSearcherBase getImmutable(RequestProcessor processor, Resource relation, Resource input) {
71         Path location = getIndexDirectory(relation, input);
72         try {
73             String key = location.toAbsolutePath().toString();
74             IndexedRelationsSearcherBase searcher = immutableSearchers.get(key);
75             if (searcher == null) {
76                 searcher = new ImmutableIndexedRelationsSearcher(processor, relation, input);
77                 immutableSearchers.put(key, searcher);
78             }
79             return searcher;
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     public static MemoryIndexing getInstance(Session session) {
87         MemoryIndexing ret = session.peekService(MemoryIndexing.class);
88         if(ret == null) {
89                 ret = new MemoryIndexing(session);
90             session.registerService(MemoryIndexing.class, ret);
91         }
92         return ret;
93     }
94     
95     public synchronized Directory getDirectory(String path, Analyzer analyzer) throws IOException {
96         RAMDirectory directory = directories.get(path);
97         if (directory == null) {
98             synchronized (directories) {
99                 directory = directories.get(path);
100                 if (directory == null) {
101                     directory = new RAMDirectory();
102                     IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_9, analyzer);
103                     new IndexWriter(directory, config.setOpenMode(OpenMode.CREATE)).close();
104                     directories.put(path, directory);
105                 }
106             }
107         }
108         return directory;
109
110     }
111     
112     public void remove(String path) {
113         directories.remove(path);
114     }
115     
116     public void flush(IProgressMonitor progress) throws Exception {
117         
118         SubMonitor monitor = SubMonitor.convert(progress);
119         
120         Set<Map.Entry<String, IndexedRelationsSearcher>> set = searchers.entrySet();
121         Set<Map.Entry<String, IndexedRelationsSearcherBase>> iset = immutableSearchers.entrySet();
122         
123         monitor.setWorkRemaining(set.size()+iset.size());
124
125         for(Map.Entry<String, IndexedRelationsSearcher> entry : set) {
126
127             IndexedRelationsSearcher persistent = entry.getValue();
128             IndexedRelationsMemorySearcher searcher = persistent.cache;
129
130                 if(persistent.isIndexAvailable()) {
131                         List<Object[]> os = searcher.allDocs(monitor, session);
132                         persistent.applyChanges(monitor, session, searcher.r, os);
133                 }
134             
135             monitor.worked(1);
136                 entry.getValue().changeState(monitor, session, State.READY);
137
138         }
139
140         for(Map.Entry<String, IndexedRelationsSearcherBase> entry : iset) {
141                 
142                 entry.getValue().changeState(monitor, session, State.READY);
143             monitor.worked(1);
144             
145         }
146         
147     }
148     
149 }