/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.db.indexing; import gnu.trove.map.hash.THashMap; import gnu.trove.set.hash.TLongHashSet; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import org.apache.lucene.document.Document; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexableField; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.eclipse.core.runtime.IProgressMonitor; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.GenericRelation; import org.simantics.utils.datastructures.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Tuukka Lehtonen * @author Antti Villberg */ public class IndexedRelationsMemorySearcher extends IndexedRelationsSearcherBase { private static final Logger LOGGER = LoggerFactory.getLogger(IndexedRelationsMemorySearcher.class); final IndexedRelationsSearcher backend; final GenericRelation r; TLongHashSet changed = new TLongHashSet(); IndexedRelationsMemorySearcher(RequestProcessor session, IndexedRelationsSearcher backend, Resource relation, Resource input, GenericRelation r) throws DatabaseException { super(session, relation, input); this.backend = backend; this.r = r; setReady(); } @Override String getDescriptor() { return "MEM: "; } @Override void insertIndex(IProgressMonitor monitor, GenericRelation r, int boundLength, Collection documentsData) throws CorruptIndexException, IOException, DatabaseException { for(Object[] o : documentsData) { Long resource = (Long)o[1]; changed.add(resource); } super.insertIndex(monitor, r, boundLength, documentsData); } @Override boolean replaceIndex(IProgressMonitor monitor, String key, Collection keyValues, GenericRelation r, int boundLength, Collection documentsData) throws CorruptIndexException, IOException, DatabaseException { for(Object[] o : documentsData) { Long resource = (Long)o[1]; changed.add(resource); } return super.replaceIndex(monitor, key, keyValues, r, boundLength, documentsData); } @Override void removeIndex(IProgressMonitor monitor, GenericRelation r, RequestProcessor processor, String key, Collection keyValues) throws DatabaseException, CorruptIndexException, IOException { for(Object o : keyValues) { Resource resource= (Resource)o; changed.add(resource.getResourceId()); } super.removeIndex(monitor, r, processor, key, keyValues); } public List allDocs(IProgressMonitor monitor, Session session) throws ParseException, IOException, DatabaseException { Query query = new MatchAllDocsQuery(); startAccess(null, session, false); TopDocs td = searcher.search(query, Integer.MAX_VALUE); ScoreDoc[ ] scoreDocs = td.scoreDocs; List result = new ArrayList(scoreDocs.length); final Map classMap = new THashMap(); for (Pair field : r.getFields()) { classMap.put(field.first, field.second); } for(ScoreDoc scoreDoc:scoreDocs) { try { Document doc = reader.document(scoreDoc.doc); List fs = doc.getFields(); Object[] o = new Object[fs.size()]; int index = 0; for (IndexableField f : fs) { String clazz = classMap.get(f.name()); if ("Long".equals(clazz)) { o[index++] = Long.parseLong(f.stringValue()); } else { o[index++] = f.stringValue(); } } result.add(o); } catch (CorruptIndexException e) { throw new DatabaseException(e); } catch (IOException e) { throw new DatabaseException(e); } } changeState(monitor, session, State.READY); // closeInternal(); return result; } public void commit() { try { if(writer != null) writer.commit(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // public static String cacheReport() { // StringBuilder sb = new StringBuilder(); // sb.append("Directories: ").append(directories.size()).append("\n"); // for (String key : directories.keySet()) { // RAMDirectory dir = directories.get(key); // if (dir != null) { // sb.append("\t").append(dir).append("\n"); // } // } // sb.append("Searchers: ").append(searchers.size()).append("\n"); // for (String key : searchers.keySet()) { // IndexedRelationsMemorySearcher s = searchers.get(key); // if (s != null) { // sb.append("\t").append(s.getClass()).append(": ").append(s.getIndexPath()).append("\n"); // } // } // return sb.toString(); // } @Override Directory getDirectory(Session session) throws IOException { MemoryIndexing mem = MemoryIndexing.getInstance(session); String path = indexPath.toAbsolutePath().toString(); return mem.getDirectory(path, Queries.getAnalyzer()); } @Override Throwable bestEffortClear(IProgressMonitor monitor, Session session) { MemoryIndexing mem = MemoryIndexing.getInstance(session); changed.clear(); String path = indexPath.toAbsolutePath().toString(); mem.remove(path); return null; } @Override protected boolean requireChangeInfoOnReplace() { return false; } @Override protected Logger getLogger() { return LOGGER; } }