Mercurial Hosting > luan
diff src/luan/modules/lucene/LuceneIndex.java @ 1397:0dc9837c16be
fix lucene issues
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 11 Sep 2019 01:31:21 -0600 |
parents | 9dfff82dfc59 |
children | 67c0e47b5be3 |
line wrap: on
line diff
--- a/src/luan/modules/lucene/LuceneIndex.java Tue Sep 10 13:41:22 2019 -0600 +++ b/src/luan/modules/lucene/LuceneIndex.java Wed Sep 11 01:31:21 2019 -0600 @@ -5,6 +5,8 @@ import java.io.FileOutputStream; import java.io.FileInputStream; import java.io.IOException; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.sql.SQLException; import java.util.Arrays; import java.util.Iterator; @@ -83,59 +85,25 @@ import luan.lib.logging.LoggerFactory; -public final class LuceneIndex { +public final class LuceneIndex implements Closeable { private static final Logger sysLogger = LoggerFactory.getLogger(LuceneIndex.class); - private static final class Closer implements Closeable { - final LuceneIndex li; - boolean isClosed = false; - private final Exception created = new Exception("created"); - - Closer(Luan luan,LuceneIndex li) { - this.li = li; - luan.onClose(this); - } + private static Map<String,Reference<LuceneIndex>> indexes = new HashMap<String,Reference<LuceneIndex>>(); - public void close() throws IOException { - if( !isClosed ) { - try { - li.close(); - } catch(SQLException e) { - throw new RuntimeException(e); - } - isClosed = true; - } - } - - protected void finalize() throws Throwable { - if( !isClosed ) { - sysLogger.error("not closed",created); - close(); - } - super.finalize(); - } - } - - private static Map<String,LuceneIndex> indexes = new HashMap<String,LuceneIndex>(); - - public static Object[] getLuceneIndex(Luan luan,File indexDir,FieldParser defaultFieldParser,String[] defaultFields,LuanFunction completer,LuanTable postgresSpec) + public static LuceneIndex getLuceneIndex(Luan luan,File indexDir,LuanTable options) throws LuanException, IOException, ClassNotFoundException, SQLException { String key = indexDir.getCanonicalPath(); synchronized(indexes) { - LuceneIndex li = indexes.get(key); - if( li == null ) { - li = new LuceneIndex(luan,indexDir,defaultFieldParser,defaultFields,key,completer,postgresSpec); - li.openCount = 1; - indexes.put(key,li); - } else { - if( defaultFieldParser != li.defaultFieldParser ) - throw new LuanException("default_type doesn't match previous use"); - if( !Arrays.equals(defaultFields,li.defaultFields) ) - throw new LuanException("default_fields don't match previous use"); - li.openCount++; + Reference<LuceneIndex> ref = indexes.get(key); + if( ref != null ) { + LuceneIndex li = ref.get(); + if( li != null ) + li.closeWriter(); } - return new Object[]{li,new Closer(luan,li)}; + LuceneIndex li = new LuceneIndex(luan,indexDir,options); + indexes.put(key, new WeakReference<LuceneIndex>(li)); + return li; } } @@ -162,18 +130,26 @@ private Set<String> indexOnly = new HashSet<String>(); - private int openCount; - private final String key; + private boolean isClosed = false; + private final Exception created = new Exception("created"); private final FieldParser defaultFieldParser; private final String[] defaultFields; private final PostgresBackup postgresBackup; + private boolean wasCreated; - private LuceneIndex(Luan luan,File indexDir,FieldParser defaultFieldParser,String[] defaultFields,String key,LuanFunction completer,LuanTable postgresSpec) + private LuceneIndex(Luan luan,File indexDir,LuanTable options) throws LuanException, IOException, ClassNotFoundException, SQLException { + Map map = options.asMap(); + FieldParser defaultFieldParser = (FieldParser)map.remove("default_type"); + LuanTable defaultFieldsTbl = Utils.removeTable(map,"default_fields"); + String[] defaultFields = defaultFieldsTbl==null ? null : (String[])defaultFieldsTbl.asList().toArray(new String[0]); + LuanFunction completer = Utils.removeFunction(map,"completer"); + LuanTable postgresSpec = Utils.removeTable(map,"postgres_spec"); + Utils.checkEmpty(map); + this.luanLogger = luan.getLogger(LuceneIndex.class); - this.key = key; this.defaultFieldParser = defaultFieldParser; this.defaultFields = defaultFields; mfp = defaultFieldParser==null ? new MultiFieldParser() : new MultiFieldParser(defaultFieldParser,defaultFields); @@ -186,7 +162,7 @@ analyzer = sfp.analyzer; } this.analyzer = analyzer; - boolean wasCreated = reopen(); + wasCreated = reopen(); if( postgresSpec == null ) { postgresBackup = null; } else { @@ -194,16 +170,25 @@ throw new LuanException("completer is required for postgres_spec"); Map spec = postgresSpec.asMap(); postgresBackup = new PostgresBackup(luan,spec); - if( postgresBackup != null ) { - if( !wasCreated && postgresBackup.wasCreated ) { - luanLogger.error("rebuilding postgres backup"); - rebuild_postgres_backup(completer); - } else if( wasCreated && !postgresBackup.wasCreated ) { - luanLogger.error("restoring from postgres"); - restore_from_postgres(); - } + if( !wasCreated && postgresBackup.wasCreated ) { + luanLogger.error("rebuilding postgres backup"); + rebuild_postgres_backup(completer); +/* + } else if( wasCreated && !postgresBackup.wasCreated ) { + luanLogger.error("restoring from postgres"); + restore_from_postgres(); +*/ } } + luan.onClose(this); + } + + protected void finalize() throws Throwable { + if( !isClosed ) { + sysLogger.error("not closed",created); + close(); + } + super.finalize(); } public boolean reopen() throws IOException { @@ -449,15 +434,13 @@ return writer.getDirectory().toString(); } - private synchronized void close() throws IOException, SQLException { - if( openCount > 0 ) { - if( --openCount == 0 ) { - doClose(); - synchronized(indexes) { - indexes.remove(key); - } - } + public synchronized void close() throws IOException { + try { + doClose(); + } catch(SQLException e) { + throw new RuntimeException(e); } + isClosed = true; } public void doClose() throws IOException, SQLException { @@ -467,6 +450,15 @@ postgresBackup.close(); } + private void closeWriter() throws IOException { + writeLock.lock(); + try { + writer.close(); + } finally { + writeLock.unlock(); + } + } + private static class DocFn extends LuanFunction { final IndexSearcher searcher; @@ -865,6 +857,16 @@ public void restore_from_postgres() throws IOException, LuanException, SQLException { + if( postgresBackup!=null && wasCreated && !postgresBackup.wasCreated ) { + luanLogger.error("restoring from postgres"); + force_restore_from_postgres(); + wasCreated = false; + } + } + + public void force_restore_from_postgres() + throws IOException, LuanException, SQLException + { luanLogger.warn("start restore_from_postgres"); if( postgresBackup==null ) throw new NullPointerException();