Hello, I'll put my comments inline...
--- petite_abeille <[EMAIL PROTECTED]> wrote: > Hello again, > > attached is the source code of the only class interacting directly > with > Lucene in my app. Sorry for not providing a complete test case as > it's > hard for me to come up with something self contained. Maybe there is > something that's obviously wrong in what I'm doing. > > Thanks for any help. > > PA > > > // > // > =========================================================================== > // > // Title: SZIndex.java > // Description: [Description] > // Author: Raphael Szwarc <[EMAIL PROTECTED]> > // Creation Date: Wed Sep 12 2001 > // Legal: Copyright (C) 2001 Raphael Szwarc. All Rights Reserved. > // > // > --------------------------------------------------------------------------- > // > > package alt.dev.szobject; > > import com.lucene.store.Directory; > import com.lucene.store.FSDirectory; > import com.lucene.store.RAMDirectory; > import com.lucene.document.Field; > import com.lucene.document.DateField; > import com.lucene.document.Document; > import com.lucene.analysis.Analyzer; > import com.lucene.analysis.standard.StandardAnalyzer; > import com.lucene.index.IndexWriter; > import com.lucene.index.IndexReader; > import com.lucene.index.Term; > import com.lucene.search.IndexSearcher; > import com.lucene.search.MultiSearcher; > import com.lucene.search.Searcher; > import com.lucene.search.Query; > import com.lucene.search.Hits; > > import java.io.FilenameFilter; > import java.io.File; > import java.io.IOException; > > import java.util.Map; > import java.util.Collection; > import java.util.Date; > import java.util.Iterator; > > import alt.dev.szfoundation.SZHexCoder; > import alt.dev.szfoundation.SZDate; > import alt.dev.szfoundation.SZSystem; > import alt.dev.szfoundation.SZLog; > > final class SZIndex extends Object > { > > // > =========================================================================== > // Constant(s) > // > --------------------------------------------------------------------------- > > private static final String Extension = ".index"; > > // > =========================================================================== > // Class variable(s) > // > --------------------------------------------------------------------------- > > private static final Filter _filter = new Filter(); > > // > =========================================================================== > // Instance variable(s) > // > --------------------------------------------------------------------------- > > private String _path = null; > private transient File _directory = null; > private transient Directory _indexDirectory = null; > private transient IndexWriter _writer = null; > > private transient IndexReader _reader = null; > private transient Searcher _searcher = null; > > private transient Directory _ramDirectory = null; > private transient IndexWriter _ramWriter = null; > private transient int _counter = 0; > > // > =========================================================================== > // Constructor method(s) > // > --------------------------------------------------------------------------- > > private SZIndex() > { > super(); > } > > // > =========================================================================== > // Class method(s) > // > --------------------------------------------------------------------------- > > static FilenameFilter filter() > { > return _filter; > } > > static String stringByDeletingPathExtension(String aPath) > { > if ( aPath != null ) > { > int anIndex = aPath.lastIndexOf( SZIndex.Extension ); > > if ( anIndex > 0 ) > { > aPath = aPath.substring( 0, anIndex ); > } > > return aPath; > } > > throw new IllegalArgumentException( > "SZIndex.stringByDeletingPathExtension: null path." ); > } > > static SZIndex indexWithNameInDirectory(String aName, File > aDirectory) > { > if ( aName != null ) > { > if ( aDirectory != null ) > { > String anEncodedName = SZHexCoder.encode( >aName.getBytes() ); > //String aPath = aDirectory.getPath() + >File.separator + > anEncodedName + SZIndex.Extension + File.separator; > String aPath = aDirectory.getPath() + File.separator >+ aName + > SZIndex.Extension + File.separator; > SZIndex anIndex = new SZIndex(); > > anIndex.setPath( aPath ); > > return anIndex; > } > > throw new IllegalArgumentException( > "SZIndex.indexWithNameInDirectory: null directory." ); > } > > throw new IllegalArgumentException( > "SZIndex.indexWithNameInDirectory: null name." ); > } > > static String stringForValue(Object aValue ) > { > if ( aValue != null ) > { > String aStringValue = null; > > if ( ( aValue instanceof SZDate ) == true ) > { > aValue = ( (SZDate) aValue ).internalDate(); > } > else > if ( ( aValue instanceof SZPersistent ) == true ) > { > aValue = ( (SZPersistent) aValue ).id(); > } > > if ( ( aValue instanceof Date ) == true ) > { > aStringValue = DateField.dateToString( (Date) aValue ); > } > else > if ( ( aValue instanceof SZID ) == true ) > { > aStringValue = ( (SZID) aValue ).uuidString(); > } > else > { > aStringValue = aValue.toString(); > } > > return aStringValue; > } > > throw new IllegalArgumentException( "SZIndex.stringForValue: null > value." ); > } > > // > =========================================================================== > // Instance method(s) > // > --------------------------------------------------------------------------- > > private String path() > { > return _path; > } > > private void setPath(String aValue) > { > _path = aValue; > } > > private File directory() > { > if ( _directory == null ) > { > String aPath = this.path(); > > if ( aPath != null ) > { > _directory = new File( aPath ); > > if ( _directory.exists() == false ) > { > _directory.mkdirs(); > } > } > else > { > throw new IllegalStateException( "SZIndex.directory: >null path." > ); > } > } > > return _directory; > } > > private boolean shouldCreate() > { > File aDirectory = this.directory(); > String[] aList = aDirectory.list(); > > if ( ( aList == null ) || ( aList.length == 0 ) ) > { > return true; > } > > return false; > } > > boolean exists() OG: one may think this method checks for existence of an index, but it only checks for existence of a directory. Perhaps directoryExists() would be a better name. > { > File aFile = this.directory(); > > if ( aFile != null ) > { > return aFile.exists(); > } > > return false; > } > > private SZDate lastModifiedDate() > { > if ( this.exists() == true ) > { > File aDirectory = this.directory(); > Date aDate = new Date( aDirectory.lastModified() ); > SZDate aCalendarDate = SZDate.dateWithDate( aDate ); > > return aCalendarDate; > } > > return null; > } > > public int hashCode() > { > return this.path().hashCode(); > } > > public boolean equals(Object anObject) > { > if ( this == anObject ) > { > return true; > } > > return this.path().equals( ( (SZIndex) anObject ).path() ); > } > > protected void finalize() throws Throwable > { > if ( _writer != null ) > { > this.optimize(); OG: perhaps you want to close some stuff here, although I'm not sure about doing that in finalize()... > } > > super.finalize(); > } > > // > =========================================================================== > // Index method(s) > // > --------------------------------------------------------------------------- > > synchronized void optimize() > { > try > { > this.flush(); > > if ( _writer != null ) > { > _writer.optimize(); OG: optimize can throw IOException. In that case your close() will not get executed. Maybe you can use a finally block. > _writer.close(); > > } > > _writer = null; > _indexDirectory = null; > } > catch(Exception anException) > { > anException.printStackTrace(); > > SZLog.warning( anException ); > > _writer = null; > _indexDirectory = null; OG: duplicate assignments, suitable for finally block. > SZSystem.gc(); > } > } > > > private Directory indexDirectory() throws IOException > { > if ( _indexDirectory == null ) > { > File aFile = this.directory(); > boolean shouldCreate = this.shouldCreate(); > > //_indexDirectory = FSDirectory.getDirectory( aFile, >shouldCreate > ); > _indexDirectory = new FSDirectory( aFile, shouldCreate ); > } > > return _indexDirectory; > } > > private IndexWriter writer() throws IOException > { > if ( _writer == null ) > { > Directory aDirectory = this.indexDirectory(); > Analyzer anAnalyzer = new StandardAnalyzer(); > boolean shouldCreate = this.shouldCreate(); > > _writer = new IndexWriter( aDirectory, anAnalyzer, >shouldCreate ); > _writer.mergeFactor = 2; > } > > return _writer; > } > > private IndexReader reader() throws IOException > { > if ( _reader == null ) > { > System.gc(); > > _reader = IndexReader.open( this.indexDirectory() ); > } OG: you are opening an IndexReader, but I don't think I saw it being closed anywhere. > return _reader; > } > > private Searcher searcher() throws IOException > { > if ( _searcher == null ) > { > System.gc(); > > _searcher = new IndexSearcher( this.reader() ); > } > > if ( _ramDirectory != null ) > { > Searcher aRamSearcher = new IndexSearcher( >IndexReader.open( > _ramDirectory ) ); OG: another open... > return new MultiSearcher( new Searcher[] { aRamSearcher, >_searcher > } ); > } > > return _searcher; > } > > // > =========================================================================== > // RAM method(s) > // > --------------------------------------------------------------------------- > > private Directory ramDirectory() throws IOException > { > if ( _ramDirectory == null ) > { > _ramDirectory = new RAMDirectory(); > } > > return _ramDirectory; > } > > private IndexWriter ramWriter() throws IOException > { > if ( _ramWriter == null ) > { > Directory aDirectory = this.ramDirectory(); > Analyzer anAnalyzer = new StandardAnalyzer(); > > _ramWriter = new IndexWriter( aDirectory, anAnalyzer, true ); > } > > return _ramWriter; > } > > private void flush() throws IOException > { > if ( ( _ramDirectory != null ) && > ( _ramDirectory.list() != null ) && > ( _ramDirectory.list().length > 0 ) && > ( _ramWriter != null ) ) > { > _ramWriter.optimize(); > _ramWriter.close(); > > this.writer().addIndexes( new Directory[] { _ramDirectory } ); > > _ramWriter = null; > _ramDirectory = null; > > _reader = null; > _searcher = null; OG: both IndexReader and IndexSearcher have a close() method. Have you tried calling them here? Does it help? You can still assign nulls later to help GC. > } > } > > // > =========================================================================== > // Indexing method(s) > // > --------------------------------------------------------------------------- > > synchronized Hits search(Query aQuery) throws IOException > { > if ( aQuery != null ) > { > if ( this.shouldCreate() == false ) > { > return this.searcher().search( aQuery ); > } > > return null; > } > > throw new IllegalArgumentException( "SZIndex.search: null query." > ); > } > > synchronized void deleteIndexWithID(SZID anID) throws IOException > { > if ( anID != null ) > { > if ( this.shouldCreate() == false ) > { > String aValue = SZIndex.stringForValue( anID >); > Term aTerm = new Term( SZDescription.IDKey, >aValue ); > IndexReader aReader = this.reader(); > > aReader.delete( aTerm ); > } > > return; > } > > throw new IllegalArgumentException( "SZIndex.deleteIndexWithID: > null id." ); > } > > synchronized void indexValuesWithID(Map someValues, SZID anID) > throws IOException > { > if ( someValues != null ) > { > if ( anID != null ) > { > Class aClass = anID.entity(); > SZDescription aDescription = >SZDescription.descriptionForClass( > aClass ); > Collection someUniqueKeys = >aDescription.uniqueKeys(); > String anIdentifier = SZIndex.stringForValue( >anID ); > Field anIdentifierField = Field.Keyword( >SZDescription.IDKey, > anIdentifier ); > String aClassName = anID.entity().getName(); > Field aClassField = Field.Keyword( >SZDescription.ClassKey, > aClassName ); > Document aDocument = new Document(); > IndexWriter aWriter = this.ramWriter(); > > aDocument.add( anIdentifierField ); > aDocument.add( aClassField ); > > for( Iterator anIterator = >someValues.keySet().iterator(); > anIterator.hasNext(); ) > { > Object aKey = anIterator.next(); > Object aValue = someValues.get( aKey ); > String aKeyName = aKey.toString(); > String aStringValue = SZIndex.stringForValue( >aValue ); > Field aField = null; > > if ( ( ( aValue instanceof SZPersistent ) == >true ) || > ( ( someUniqueKeys != null ) && ( >someUniqueKeys.contains( > aKeyName ) == true ) ) ) > { > aField = new Field( aKeyName, >aStringValue, false, true, false) > ; > } > else > { > aField = Field.UnStored( aKeyName, >aStringValue ); > } > > aDocument.add( aField ); > } > > aWriter.addDocument( aDocument ); > aWriter.optimize(); > > _counter += 1; > > if ( _counter > 100 ) > { > this.flush(); > _counter = 0; > } > > return; > } > > throw new IllegalArgumentException( "SZIndex.indexValues: null > id." ); > } > > throw new IllegalArgumentException( "SZIndex.indexValues: null > values." ); > } > > // > =========================================================================== > // FilenameFilter method(s) > // > --------------------------------------------------------------------------- > > private static final class Filter extends Object implements > FilenameFilter > { > > private Filter() > { > super(); > } > > public boolean accept(File aDirectory, String aName) > { > if ( aName.endsWith( SZIndex.Extension ) == true ) > { > File aFile = new File( aDirectory, aName ); > > if ( aFile.isDirectory() == true ) > { > return true; > } > } > > return false; > } > } > > } That's all I can see. Otis __________________________________________________ Do You Yahoo!? Yahoo! Health - your guide to health and wellness http://health.yahoo.com -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>