Mercurial Hosting > luan
diff lucene/src/luan/modules/lucene/LuceneIndex.java @ 230:4438cb2e04d0
start lucene
git-svn-id: https://luan-java.googlecode.com/svn/trunk@231 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Tue, 30 Sep 2014 20:03:56 +0000 |
parents | |
children | 9ce18106f95a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lucene/src/luan/modules/lucene/LuceneIndex.java Tue Sep 30 20:03:56 2014 +0000 @@ -0,0 +1,198 @@ +package luan.modules.lucene; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.zip.ZipOutputStream; +import java.util.zip.ZipEntry; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.Term; +import org.apache.lucene.index.SnapshotDeletionPolicy; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.util.Version; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.TopDocs; +import luan.modules.Utils; +import luan.Luan; +import luan.LuanState; +import luan.LuanTable; +import luan.LuanFunction; +import luan.LuanJavaFunction; +import luan.LuanException; + + +public final class LuceneIndex { + private static final String FLD_TYPE = LuceneWriter.FLD_TYPE; + private static final String FLD_NEXT_ID = "nextId"; + + final Lock writeLock = new ReentrantLock(); + private final File indexDir; + final SnapshotDeletionPolicy snapshotDeletionPolicy; + final IndexWriter writer; + private DirectoryReader reader; + private LuceneSearcher searcher; + + public LuceneIndex(String indexDirStr) { + try { + File indexDir = new File(indexDirStr); + this.indexDir = indexDir; + Directory dir = FSDirectory.open(indexDir); + Version version = Version.LUCENE_4_9; + Analyzer analyzer = new StandardAnalyzer(version); + IndexWriterConfig conf = new IndexWriterConfig(version,analyzer); + snapshotDeletionPolicy = new SnapshotDeletionPolicy(conf.getIndexDeletionPolicy()); + conf.setIndexDeletionPolicy(snapshotDeletionPolicy); + writer = new IndexWriter(dir,conf); + writer.commit(); // commit index creation + reader = DirectoryReader.open(dir); + searcher = new LuceneSearcher(reader); + initId(); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + + public LuceneWriter openWriter() { + return new LuceneWriter(this); + } + + public synchronized LuceneSearcher openSearcher() { + try { + DirectoryReader newReader = DirectoryReader.openIfChanged(reader); + if( newReader != null ) { + reader.decRef(); + reader = newReader; + searcher = new LuceneSearcher(reader); + } + reader.incRef(); + return searcher; + } catch(IOException e) { + throw new RuntimeException(e); + } + } + + public LuceneSnapshot openSnapshot() { + return new LuceneSnapshot(this); + } + + + private long id = 0; + private long idLim = 0; + private final int idBatch = 10; + + private void initId() { + TopDocs td = searcher.search(new TermQuery(new Term(FLD_TYPE,"next_id")),1); + switch(td.totalHits) { + case 0: + break; // do nothing + case 1: + LuanTable doc = searcher.doc(td.scoreDocs[0].doc); + idLim = (Long)doc.get(FLD_NEXT_ID); + id = idLim; + break; + default: + throw new RuntimeException(); + } + } + + synchronized String nextId() { + try { + String rtn = Long.toString(++id); + if( id > idLim ) { + idLim += idBatch; + LuanTable doc = Luan.newTable(); + doc.put( FLD_TYPE, "next_id" ); + doc.put( FLD_NEXT_ID, idLim ); + writer.updateDocument(new Term(FLD_TYPE,"next_id"),LuceneDocument.toLucene(doc)); + } + return rtn; + } catch(IOException e) { + throw new RuntimeException(e); + } + } + + public LuanTable getDocument(String id) { + return getDocument(new Term(LuceneWriter.FLD_ID,id)); + } + + public LuanTable getDocument(Term term) { + LuceneSearcher searcher = openSearcher(); + try { + TopDocs td = searcher.search(new TermQuery(term),1); + switch(td.totalHits) { + case 0: + return null; + case 1: + return searcher.doc(td.scoreDocs[0].doc); + default: + throw new RuntimeException(); + } + } finally { + searcher.close(); + } + } + + + public void backup(String zipFile) { + if( !zipFile.endsWith(".zip") ) + throw new RuntimeException("file "+zipFile+" doesn't end with '.zip'"); + LuceneSnapshot snapshot = openSnapshot(); + try { + ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile)); + for( String fileName : snapshot.getFileNames() ) { + out.putNextEntry(new ZipEntry(fileName)); + FileInputStream in = new FileInputStream(new File(indexDir,fileName)); + Utils.copyAll(in,out); + in.close(); + out.closeEntry(); + } + out.close(); + } catch(IOException e) { + throw new RuntimeException(e); + } finally { + snapshot.close(); + } + } + + + + // luan + + public String to_string() { + return writer.getDirectory().toString(); + } + + public void Writer(LuanState luan,LuanFunction fn) throws LuanException, IOException { + LuceneWriter writer = openWriter(); + try { + luan.call( fn, new Object[]{writer.table()} ); + writer.commit(); + } finally { + writer.close(); + } + } + + private void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { + t.put( method, new LuanJavaFunction(LuceneIndex.class.getMethod(method,parameterTypes),this) ); + } + + public LuanTable table() { + LuanTable tbl = Luan.newTable(); + try { + add( tbl, "to_string" ); + add( tbl, "backup", String.class ); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + return tbl; + } + +}