lucene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Earwin Burrfoot <>
Subject Re: IndexReader plugins
Date Mon, 13 Apr 2009 13:44:02 GMT
On Mon, Apr 13, 2009 at 17:14, Michael McCandless
<> wrote:
> On Mon, Apr 13, 2009 at 9:02 AM, Earwin Burrfoot <> wrote:
>>> I think I'd lean towards only at construction.  Seems dangerous to
>>> allow swap in/out at some later time.
>> I have several points pro-runtime:
>> 1. We have a lot of static factory methods, it's gonna be a problem
>> passing plugins everywhere on creation.
> "We" is who here?  Couldn't "they refactor their code to callback into
> those static factory methods?
"We" as in "(un)fortunate users of Lucene". is littered with the likes of:
public static IndexReader open(final Directory directory,
IndexDeletionPolicy deletionPolicy) throws CorruptIndexException,

> Presumably you'd pass into Lucene a "CreatesXYZComponent" instance
> which given a SegmentInfo (or a public'd version of it, with
> extensibility, etc) returns an XYZComponent.
I want to pass a component into toplevel reader, it will be
consequently notified of subreader creation/deletion and given a
chance to reuse its instance for them, or provide a new one.

>> 2. public <T extends IRP> void bindPlugin(Class<? super T> type, T
>> instance) is typesafer than passing Map<Class, IRP> in
>> constructor.
> Can you make this more concrete?  (I'm having trouble following... the
> generics).
Let's define the following:
interface Plugin {}
interface Service1 {}
interface Service2 {}
class Impl implements Plugin, Service1, Service2 {}

IndexReader: public <T extends Plugin> void bindPlugin(Class<? super
T> type, T instance);

Now we can invoke bindPlugin like this:
indexReader.bindPlugin(Service1.class, new Impl());
indexReader.bindPlugin(Service2.class, new Impl());

Nice points:
It won't compile if Impl doesn't implement Plugin (which we need for
attach/detach notifications).
It won't compile if Impl doesn't implement the service interface we're
binding it to.
Service interface doesn't have to extend Plugin, so attach/detach
methods that are a contract between a plugin and its host won't be
visible to service consumers that will get an instance through:
IndexReader: public <T> T getPlugin(Class<T> type);
Service1 srv = indexReader.getPlugin(Service1.class);

If you're passing all plugins as a bunch during creation, you have to
use wither Map, or a List of Pairs.
Map<Class, Plugin> plugins;
new SegmentReader(somestuff, plugins);
That way you're able to do less type checking than in previous example.

>> 3. Plugins support attachment/detachment and they don't need to know
>> exact reason they were attached/detached for - there should be no
>> difference between closing a reader and removing plugin from it.
> But what's the use case here?  Why would a SegmentReader need to
> detach/attach a new XYZComponent?
We already have it for free. A component should receive notification
when SegmentReader is created. A component should also receive
notification when SegmentReader is close()d. Nobody prevents us from
using these notifications at a different point in time.

> And... why not simply open a new SegmentReader?  With this change,
> opening a new reader can be an extremely low-cost operation since you
> could share already opened XYZComponents.  A SegmentReader simply
> becomes a set of components held together.
I lean to post-construction attach/detach vs passing plugins in ctor
not because I want to abuse it for inflight indexReader
reconfiguration, it's just simpler to use with the way IndexReaders
are created.

Kirill Zakharenko/Кирилл Захаренко (
Home / Mobile: +7 (495) 683-567-4 / +7 (903) 5-888-423
ICQ: 104465785

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message