It's not nearly this complex (we don't need two ref counts). If we
follow the simple rule that "every time reader X wants to use reader
Y, it increfs it" and "whenver reader X is done using reader Y, it
decrefs it", all should work correctly.
Also we should think of "close()" as the way that the external user
does the decref of their reader. We just special-case this call, by
setting isOpen=false, to make sure we don't double decref on a double
Let's walk through your example...
I'm assuming in your example you meant for reader2 and reader3 to also
be SegmentReaders? Ie, the changes that are happening to the
single-segment index1 are just changes to norms and/or deletes. If
not, the example is less interesting because reader1 will be closed
Also in your example let's insert missing "reader1.close()" as the
very first close? (Else it will never be closed because it's RC never
When reader1 is created it has RC 1.
When multiReader1 is created, reader1 now has RC 2.
When multiReader2 is created, reader1 now has RC 3.
When reader2 is created (by reader1.reopen()), it incref's reader1
because it's sharing the sub-readers in reader1. So reader1 now has
When reader3 was created (by reader2.reopen()), it incref's reader2
because it's sharing the sub-readers reader2 contains. So reader1 is
still at RC 4 and reader2 is now at RC 2.
Now, we close.
After reader1.close() is called, reader1 sets isOpen=false (to prevent
double close by the user) and RC drops to 3.
With multiReader1.close(), multiReader1 is not at RC 0, and so it
decrefs all readers it was using, and so reader1 RC is now 2.
With multiReader2.close(), likewise it is now at RC 0 and so it
decrefs all readers it was using, and so reader1 RC is now 1.
With reader2.close(), it decrefs its own RC, however that brings its
RC to 1 (reader3 is still referring to it) and so it does not decref
the reader1 that it's referring to.
Finally, with reader3.close(), it is now at RC 0 and so it decrefs the
reader2 it refers to. This brings reader2's RC to 0, and so reader2
decrefs the reader1 that it's referring to. Which brings reader1's RC
to 0, and so reader1 finally closes all its internal sub-readers.