lucenenet icon indicating copy to clipboard operation
lucenenet copied to clipboard

Fix initialization issue with DirectoryTaxonomyWriter

Open NightOwl888 opened this issue 3 years ago • 0 comments

In this test scenario, an alternate IndexWriter is being setup to be returned from the OpenIndexWriter method. However, since the constructor of the class calls OpenIndexWriter there is an issue where it cannot be extended directly as it was intended in Java. A constructor of a base class always runs before the subclass, so there is a chicken and egg problem with overriding OpenIndexWriter.

The current "solution" uses a static variable to set the iw variable before instantiating the class.

        private class DirectoryTaxonomyWriterAnonymousInnerClassHelper2 : DirectoryTaxonomyWriter
        {
            internal static IndexWriter iw = null;

            public DirectoryTaxonomyWriterAnonymousInnerClassHelper2(Directory dir) 
                : base(dir)
            {
            }

            protected override IndexWriter OpenIndexWriter(Directory directory, IndexWriterConfig config) 
            {   
                return iw;
            }
        }

While this makes the test pass, it clearly is going to be an issue for concurrent environments to do it this way.

We need to find a solution that allows using instance variables throughout, even if it means diverging a little from the original Lucene design.

Potential Fix

One possible solution would be to add constructor overloads to DirectoryTaxonomyReader to allow the OpenIndexWriter method to be passed in as a Func<IndexWriter, Directory, IndexWriterConfig> and to disallow it to be overridden by base classes.

private readonly Func<IndexWriter, Directory, IndexWriterConfig) openIndexWriter;

public DirectoryTaxonomyReader(Directory directory, Func<IndexWriter, Directory, IndexWriterConfig> openIndexWriter)
{
    this.dir = directory;
    this.openIndexWriter = openIndexWriter;
 
    // Implementation....

    var x = OpenIndexWriter(y, z); // Call to OpenIndexWriter within constructor

    // Implementation....
}

// Remove "virtual" from the method so it cannot be overridden
protected IndexWriter OpenIndexWriter(Directory directory, IndexWriterConfig config)
{
    if (openIndexWriter != null)
    {
        return openIndexWriter(directory, config);
    }
    else
    {
        // Original implementation...
    }
}

This corresponds closely to how it is done in Java.

NightOwl888 avatar Feb 04 '21 04:02 NightOwl888