lucene-java-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Trejkaz <trej...@trypticon.org>
Subject Re: Is there a way to share IndexReader data sensibly across independent callers?
Date Thu, 25 Feb 2016 23:51:19 GMT
So it turns out I still have problems.

I wanted to return a proxy reader that the caller could close like
normal. I wanted to do this for two reasons:

1. This:

    try (IndexReader reader = sharer.acquireReader(...)) {
        ...
    }

    Looks much nicer than this:

    IndexReader reader = sharer.acquireReader(...));
    try {
        ...
    } finally {
        sharer.releaseReader(reader);
    }

    It isn't entirely clear from ReaderManager's docs whether you
*have* to call release or whether calling close() on the reader is
acceptable. Maybe it's fine to call close(), which removes some (but
not all) wrapping we are doing.

2. There have been bugs in the past where somehow readers got closed
more than once. I was hoping to stomp these out by giving out a
different reader to each caller so that we can track which ones have
already been closed and reject the second attempt. And indeed, since
implementing this, we haven't seen that sort of issue occur.

But supposedly the performance isn't good enough. The main cost
appears to be that creating what I thought should be a lightweight
wrapper is surprisingly expensive, because Lucene is maintaining a map
of which readers use which other reasons, which uses
System.identityHashCode, which is apparently an expensive call. (We
always see it inside this, not inside the other methods in
WeakHashMap. I guess native calls are just expensive?)

    java.lang.Thread.State: RUNNABLE
        at java.lang.System.identityHashCode(Native Method)
        at org.apache.lucene.index.IndexReader.hashCode(IndexReader.java:302)
        at java.util.WeakHashMap.hash(WeakHashMap.java:298)
        at java.util.WeakHashMap.put(WeakHashMap.java:449)
        at java.util.Collections$SetFromMap.add(Collections.java:5461)
        at java.util.Collections$SynchronizedCollection.add(Collections.java:2035)
        - locked <0x0000000084067fe8> (a java.util.Collections$SynchronizedSet)
        at org.apache.lucene.index.IndexReader.registerParentReader(IndexReader.java:138)
        at org.apache.lucene.index.BaseCompositeReader.<init>(BaseCompositeReader.java:77)
        at org.apache.lucene.index.DirectoryReader.<init>(DirectoryReader.java:310)
        at org.apache.lucene.index.FilterDirectoryReader.<init>(FilterDirectoryReader.java:83)
        at IndexReaderSharer$CloseForwardingDirectoryReader.<init>(IndexReaderSharer:184)

So I'm back to another problem where now I want to reduce the number
of times I create this wrapping reader, yet I don't want to give the
same wrapping reader object out to more than one caller because one of
them could close it twice. I guess I could add yet another layer of
wrapping, make my own IndexReader interface and implement a proxy to
that which is actually cheap, but again it's going to involve writing
hard reference counting code so I'm wondering if there is another way
to avoid this whole mess.

TX

---------------------------------------------------------------------
To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-user-help@lucene.apache.org


Mime
View raw message