/// <summary> /// Expert: this method is called by <see cref="IndexReader"/>s which wrap other readers /// (e.g. <see cref="CompositeReader"/> or <see cref="FilterAtomicReader"/>) to register the parent /// at the child (this reader) on construction of the parent. When this reader is disposed, /// it will mark all registered parents as disposed, too. The references to parent readers /// are weak only, so they can be GCed once they are no longer in use. /// @lucene.experimental /// </summary> public void RegisterParentReader(IndexReader reader) { EnsureOpen(); // LUCENENET specific - since ConditionalWeakTable doesn't synchronize // on the enumerator, we need to do external synchronization to make them threadsafe. UninterruptableMonitor.Enter(parentReadersLock); try { #if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR // LUCENENET: Since there is a set Add operation (unique) in Lucene, the equivalent // operation in .NET is AddOrUpdate, which effectively does nothing if the key exists. // Null is passed as a value, since it is not used anyway and .NET doesn't have a boolean // reference type. parentReaders.AddOrUpdate(key: reader, value: null); #else if (!parentReaders.TryGetValue(key: reader, out _)) { parentReaders.Add(key: reader, value: null); reader.SubscribeToGetParentReadersEvent(eventAggregator.GetEvent <Events.GetParentReadersEvent>()); } #endif } finally { UninterruptableMonitor.Exit(parentReadersLock); } }