public void CloseReader(IndexReader reader)
 {
     try
     {
         reader.Dispose();
     }
     catch (System.IO.IOException ex)
     {
         //TODO: extract subReaders and close each one individually
         ReaderProviderHelper.Clean(reader);
         new SearchException("Unable to close multiReader", ex);
     }
 }
        public IndexReader OpenReader(IDirectoryProvider[] directoryProviders)
        {
            int length = directoryProviders.Length;

            IndexReader[] readers = new IndexReader[length];
            try
            {
                for (int index = 0; index < length; index++)
                {
                    readers[index] = IndexReader.Open(directoryProviders[index].Directory);
                }
            }
            catch (System.IO.IOException ex)
            {
                // TODO: more contextual info
                ReaderProviderHelper.Clean(readers);
                throw new SearchException("Unable to open one of the Lucene indexes", ex);
            }

            return(ReaderProviderHelper.BuildMultiReader(length, readers));
        }
        private IndexReader ReplaceActiveReader(IndexReader outOfDateReader, object directoryProviderLock,
                                                IDirectoryProvider directoryProvider, IndexReader[] readers)
        {
            bool        trace = log.IsInfoEnabled;
            IndexReader oldReader;
            bool        closeOldReader       = false;
            bool        closeOutOfDateReader = false;
            IndexReader reader;

            /**
             * Since out of lock protection, can have multiple readers created in //
             * not worse than NotShared and limit the locking time, hence scalability
             */
            try
            {
                reader = IndexReader.Open(directoryProvider.Directory);
            }
            catch (IOException e)
            {
                throw new SearchException("Unable to open Lucene IndexReader", e);
            }
            lock (directoryProviderLock)
            {
                // Since not protected by a lock, other ones can have been added
                oldReader = activeSearchIndexReaders[directoryProvider] = reader;
                lock (semaphoreIndexReaderLock)
                {
                    searchIndexReaderSemaphores[reader] = new ReaderData(1, directoryProvider);
                    if (trace)
                    {
                        log.Info("Semaphore: 1 for " + reader);
                    }
                    if (outOfDateReader != null)
                    {
                        ReaderData readerData;
                        searchIndexReaderSemaphores.TryGetValue(outOfDateReader, out readerData);
                        if (readerData == null)
                        {
                            closeOutOfDateReader = false; //already removed by another prevous thread
                        }
                        else if (readerData.Semaphore == 0)
                        {
                            searchIndexReaderSemaphores.Remove(outOfDateReader);
                            closeOutOfDateReader = true;
                        }
                        else
                        {
                            closeOutOfDateReader = false;
                        }
                    }

                    if (oldReader != null && oldReader != outOfDateReader)
                    {
                        ReaderData readerData = searchIndexReaderSemaphores[oldReader];
                        if (readerData == null)
                        {
                            log.Warn("Semaphore should not be null");
                            closeOldReader = true; //TODO should be true or false?
                        }
                        else if (readerData.Semaphore == 0)
                        {
                            searchIndexReaderSemaphores.Remove(oldReader);
                            closeOldReader = true;
                        }
                        else
                        {
                            closeOldReader = false;
                        }
                    }
                }
            }

            if (closeOutOfDateReader)
            {
                if (trace)
                {
                    log.Info("Closing out of date IndexReader " + outOfDateReader);
                }
                try
                {
                    outOfDateReader.Close();
                }
                catch (IOException e)
                {
                    ReaderProviderHelper.Clean(readers);
                    throw new SearchException("Unable to close Lucene IndexReader", e);
                }
            }
            if (closeOldReader)
            {
                if (trace)
                {
                    log.Info("Closing old IndexReader " + oldReader);
                }
                try
                {
                    oldReader.Close();
                }
                catch (IOException e)
                {
                    ReaderProviderHelper.Clean(readers);
                    throw new SearchException("Unable to close Lucene IndexReader", e);
                }
            }
            return(reader);
        }
        public IndexReader OpenReader(IDirectoryProvider[] directoryProviders)
        {
            bool trace  = log.IsInfoEnabled;
            int  length = directoryProviders.Length;

            IndexReader[] readers = new IndexReader[length];

            if (trace)
            {
                log.Info("Opening IndexReader for directoryProviders: " + length);
            }

            for (int index = 0; index < length; index++)
            {
                IDirectoryProvider directoryProvider = directoryProviders[index];
                IndexReader        reader;
                object             directoryProviderLock = perDirectoryProviderManipulationLocks[directoryProvider];
                if (trace)
                {
                    log.Info("Opening IndexReader from " + directoryProvider.Directory);
                }
                lock (directoryProviderLock)
                {
                    activeSearchIndexReaders.TryGetValue(directoryProvider, out reader);
                }
                if (reader == null)
                {
                    if (trace)
                    {
                        log.Info("No shared IndexReader, opening a new one: " + directoryProvider.Directory);
                    }
                    reader = ReplaceActiveReader(null, directoryProviderLock, directoryProvider, readers);
                }
                else
                {
                    bool isCurrent;
                    try
                    {
                        isCurrent = reader.IsCurrent();
                    }
                    catch (IOException e)
                    {
                        throw new SearchException("Unable to read current status of Lucene IndexReader", e);
                    }

                    if (!isCurrent)
                    {
                        if (trace)
                        {
                            log.Info("Out of date shared IndexReader found, opening a new one: " +
                                     directoryProvider.Directory);
                        }
                        IndexReader outOfDateReader = reader;
                        reader = ReplaceActiveReader(outOfDateReader, directoryProviderLock, directoryProvider, readers);
                    }
                    else
                    {
                        if (trace)
                        {
                            log.Info("Valid shared IndexReader: " + directoryProvider.Directory);
                        }

                        lock (directoryProviderLock)
                        {
                            //read the latest active one, the current one could be out of date and closed already
                            //the latest active is guaranteed to be active because it's protected by the dp lock
                            reader = activeSearchIndexReaders[directoryProvider];
                            lock (semaphoreIndexReaderLock)
                            {
                                ReaderData readerData = searchIndexReaderSemaphores[reader];
                                //TODO if readerData is null????
                                readerData.Semaphore++;
                                searchIndexReaderSemaphores[reader] = readerData; //not necessary
                                if (trace)
                                {
                                    log.Info("Semaphore increased: " + readerData.Semaphore + " for " + reader);
                                }
                            }
                        }
                    }
                }
                readers[index] = reader;
            }

            return(ReaderProviderHelper.BuildMultiReader(length, readers));
        }