package org.simantics.db.indexing; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.util.Version; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.common.request.Adapt; import org.simantics.db.common.utils.Logger; import org.simantics.db.indexing.IndexedRelationsSearcherBase.State; import org.simantics.db.layer0.adapter.GenericRelation; /** * @author Tuukka Lehtonen * @author Antti Villberg */ public class MemoryIndexing { final private Session session; final Map>>> persistentCache = new HashMap>>>(); final Map>> persistentCacheResources = new HashMap>>(); final private Map directories = new HashMap(); final private Map immutableSearchers = new HashMap(); final private Map searchers = new HashMap(); public MemoryIndexing(Session session) { this.session = session; } protected File getIndexDirectory(Resource relation, Resource input) { return DatabaseIndexing.getIndexLocation(session, relation, input); } public IndexedRelationsSearcher get(RequestProcessor processor, Resource relation, Resource input) { try { File location = getIndexDirectory(relation, input); String key = location.getAbsolutePath(); IndexedRelationsSearcher searcher = searchers.get(key); if (searcher == null) { GenericRelation r = processor.sync(new Adapt(relation, GenericRelation.class)); searcher = new IndexedRelationsSearcher(processor, relation, input, r); searchers.put(key, searcher); } return searcher; } catch (Exception e) { Logger.defaultLogError(e); return null; } } public IndexedRelationsSearcherBase getImmutable(RequestProcessor processor, Resource relation, Resource input) { try { File location = getIndexDirectory(relation, input); String key = location.getAbsolutePath(); IndexedRelationsSearcherBase searcher = immutableSearchers.get(key); if (searcher == null) { searcher = new ImmutableIndexedRelationsSearcher(processor, relation, input); immutableSearchers.put(key, searcher); } return searcher; } catch (Exception e) { Logger.defaultLogError(e); return null; } } public static MemoryIndexing getInstance(Session session) { MemoryIndexing ret = session.peekService(MemoryIndexing.class); if(ret == null) { ret = new MemoryIndexing(session); session.registerService(MemoryIndexing.class, ret); } return ret; } public synchronized Directory getDirectory(String path, Analyzer analyzer) throws IOException { RAMDirectory directory = directories.get(path); if (directory == null) { synchronized (directories) { directory = directories.get(path); if (directory == null) { directory = new RAMDirectory(); IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_9, analyzer); new IndexWriter(directory, config.setOpenMode(OpenMode.CREATE)).close(); directories.put(path, directory); } } } return directory; } public void remove(String path) { directories.remove(path); } public void flush(IProgressMonitor progress) throws Exception { SubMonitor monitor = SubMonitor.convert(progress); Set> set = searchers.entrySet(); Set> iset = immutableSearchers.entrySet(); monitor.setWorkRemaining(set.size()+iset.size()); for(Map.Entry entry : set) { IndexedRelationsSearcher persistent = entry.getValue(); IndexedRelationsMemorySearcher searcher = persistent.cache; if(persistent.isIndexAvailable()) { List os = searcher.allDocs(monitor, session); persistent.applyChanges(monitor, session, searcher.r, os); } monitor.worked(1); entry.getValue().changeState(monitor, session, State.READY); } for(Map.Entry entry : iset) { entry.getValue().changeState(monitor, session, State.READY); monitor.worked(1); } } }