package de.lmu.ifi.dbs.elki.database.lucene; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures Copyright (C) 2015 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ import java.io.File; import java.io.IOException; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import de.lmu.ifi.dbs.elki.database.AbstractDatabase; import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.ids.DBIDRange; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery; import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery; import de.lmu.ifi.dbs.elki.database.relation.DBIDView; import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter; /** * Database backend using Lucene 3. * * @author Erich Schubert * @since 0.6.0 */ public class LuceneDatabase extends AbstractDatabase { /** * Class logger. */ public static final Logging LOG = Logging.getLogger(LuceneDatabase.class); /** * IDs of this database */ private DBIDRange ids; /** * The DBID representation we use */ private DBIDView idrep; /** * Lucene database directory. */ private Directory directory; /** * Lucene index reader. */ private IndexReader reader; /** * Document representation. */ private LuceneDocumentRelation docrep; /** * Constructor. * * @param directory Lucene directory. */ public LuceneDatabase(Directory directory) { super(); this.directory = directory; } @Override public void initialize() { try { reader = IndexReader.open(directory); ids = DBIDUtil.generateStaticDBIDRange(reader.maxDoc()); // ID relation: idrep = new DBIDView(ids); relations.add(idrep); getHierarchy().add(this, idrep); // Documents relation: docrep = new LuceneDocumentRelation(ids, reader); relations.add(docrep); getHierarchy().add(this, docrep); eventManager.fireObjectsInserted(ids); } catch(CorruptIndexException e) { throw new AbortException("Index is corrupt.", e); } catch(IOException e) { throw new AbortException("I/O error reading index.", e); } } @Override public RangeQuery getRangeQuery(DistanceQuery distanceQuery, Object... hints) { if(distanceQuery.getDistanceFunction() instanceof LuceneDistanceFunction) { @SuppressWarnings("unchecked") final RangeQuery rq = (RangeQuery) new LuceneDistanceRangeQuery((DistanceQuery) distanceQuery, reader, ids); return rq; } return super.getRangeQuery(distanceQuery, hints); } @Override public KNNQuery getKNNQuery(DistanceQuery distanceQuery, Object... hints) { if(distanceQuery.getDistanceFunction() instanceof LuceneDistanceFunction) { @SuppressWarnings("unchecked") final KNNQuery kq = (KNNQuery) new LuceneDistanceKNNQuery((DistanceQuery) distanceQuery, reader, ids); return kq; } return super.getKNNQuery(distanceQuery, hints); } @Override protected Logging getLogger() { return LOG; } /** * Parameterization class. * * @author Erich Schubert */ public static final class Parameterizer extends AbstractParameterizer { /** * Option ID for the index folder. */ public static final OptionID INDEX_DIR_ID = new OptionID("lucene.index", "Lucene index directory."); /** * Index folder. */ File idir; @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); FileParameter fileP = new FileParameter(INDEX_DIR_ID, FileParameter.FileType.INPUT_FILE); if(config.grab(fileP)) { idir = fileP.getValue(); } } @Override protected LuceneDatabase makeInstance() { try { return new LuceneDatabase(FSDirectory.open(idir)); } catch(IOException e) { throw new AbortException("I/O error opening index.", e); } } } }