Package proj.zoie.impl.indexing.internal

Source Code of proj.zoie.impl.indexing.internal.IndexReaderDispenser$InternalIndexReader

package proj.zoie.impl.indexing.internal;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;

import org.apache.log4j.Logger;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.store.Directory;

import proj.zoie.api.ZoieVersion;
import proj.zoie.api.DirectoryManager;
import proj.zoie.api.DocIDMapper;
import proj.zoie.api.ZoieHealth;
import proj.zoie.api.ZoieIndexReader;
import proj.zoie.api.ZoieMultiReader;
import proj.zoie.api.indexing.IndexReaderDecorator;

public class IndexReaderDispenser<R extends IndexReader, V extends ZoieVersion>
{
  private static final Logger log = Logger.getLogger(IndexReaderDispenser.class);
 
  private static final int INDEX_OPEN_NUM_RETRIES=5;
 
//  public static final String  INDEX_DIRECTORY = "index.directory";
 
  static final class InternalIndexReader<R extends IndexReader, V extends ZoieVersion> extends ZoieMultiReader<R>
  {
    //private IndexSignature _sig;
    private final IndexReaderDispenser<R,V> _dispenser;

    InternalIndexReader(IndexReader in,IndexReaderDecorator<R> decorator,IndexReaderDispenser<R,V> dispenser) throws IOException
    {
      super(in, decorator);
      _dispenser = dispenser;
    }

    public InternalIndexReader(IndexReader in, IndexReader[] subReaders, IndexReaderDecorator<R> decorator,IndexReaderDispenser<R,V> dispenser) throws IOException
    {
      super(in, subReaders, decorator);
      _dispenser = dispenser;
    }

    @Override
    protected ZoieMultiReader<R> newInstance(IndexReader inner, IndexReader[] subReaders) throws IOException
    {
      return new InternalIndexReader<R,V>(inner,subReaders,_decorator,_dispenser);
    }
  }

  private volatile InternalIndexReader<R,V> _currentReader;
  private volatile IndexSignature<V> _currentSignature;
  private final IndexReaderDecorator<R> _decorator;
  private final DirectoryManager<V> _dirMgr;
  private DiskSearchIndex<R,V> _idx;
 
  public IndexReaderDispenser(DirectoryManager<V> dirMgr, IndexReaderDecorator<R> decorator,DiskSearchIndex<R,V> idx)
  {
      _idx = idx;
    _dirMgr = dirMgr;
    _decorator = decorator;
    _currentSignature = null;
    try
    {
      IndexSignature<V> sig = new IndexSignature<V>(_dirMgr.getVersion());
      if(sig != null)
      {
        getNewReader();
      }
    }
    catch (IOException e)
    {
      log.error(e);
    }
  }
 
  public V getCurrentVersion()
  {
    return _currentSignature!=null ? _currentSignature.getVersion(): null;
  }
 
  /**
     * constructs a new IndexReader instance
     *
     * @param indexPath
     *            Where the index is.
     * @return Constructed IndexReader instance.
     * @throws IOException
     */
    private InternalIndexReader<R,V> newReader(DirectoryManager<V> dirMgr, IndexReaderDecorator<R> decorator, IndexSignature<V> signature)
        throws IOException
    {
      if (!dirMgr.exists()){
        return null;
      }
     
    Directory dir= dirMgr.getDirectory();
   
    if (!IndexReader.indexExists(dir)){
      return null;
    }
   
      int numTries=INDEX_OPEN_NUM_RETRIES;
      InternalIndexReader<R,V> reader=null;
     
      // try max of 5 times, there might be a case where the segment file is being updated
      while(reader==null)
      {
        if (numTries==0)
        {
          log.error("Problem refreshing disk index, all attempts failed.");
          throw new IOException("problem opening new index");
        }
        numTries--;
       
        try{
          if(log.isDebugEnabled())
          {
            log.debug("opening index reader at: "+dirMgr.getPath());
          }
          IndexReader srcReader = IndexReader.open(dir,true);
         
          try
          {
            reader=new InternalIndexReader<R,V>(srcReader, decorator,this);
            _currentSignature = signature;
          }
          catch(IOException ioe)
          {
            // close the source reader if InternalIndexReader construction fails
            if (srcReader!=null)
            {
              srcReader.close();
            }
            throw ioe;
          }
        }
        catch(IOException ioe)
        {
          try
          {
            Thread.sleep(100);
          }
          catch (InterruptedException e)
          {
            log.warn("thread interrupted.");
            continue;
          }
        }
      }
      return reader;
    }

    /**
     * get a fresh new reader instance
     * @return an IndexReader instance, can be null if index does not yet exit
     * @throws IOException
     */
    public ZoieIndexReader<R> getNewReader() throws IOException
    {
        int numTries=INDEX_OPEN_NUM_RETRIES;  
        InternalIndexReader<R,V> reader=null;
             
        // try it for a few times, there is a case where lucene is swapping the segment file,
        // or a case where the index directory file is updated, both are legitimate,
        // trying again does not block searchers,
        // the extra time it takes to get the reader, and to sync the index, memory index is collecting docs
      
    while(reader==null)
    {
      if (numTries==0)
      {
        break;
      }
      numTries--;
      try{
        IndexSignature<V> sig = new IndexSignature<V>(_dirMgr.getVersion());
 
        if (sig==null)
        {
          throw new IOException("no index exist");
        }
       
        if (_currentReader==null){
          reader = newReader(_dirMgr, _decorator, sig);
            break;
        }
        else{
          reader = (InternalIndexReader<R,V>)_currentReader.reopen(true);
          _currentSignature = sig;
        }
      }
      catch(IOException ioe)
      {
        try
        {
          Thread.sleep(100);
        }
        catch (InterruptedException e)
        {
        log.warn("thread interrupted.");
          continue;
        }
      }
    }

    // swap the internal readers
    if (_currentReader != reader)
    {
      if (reader!=null){
        DocIDMapper mapper = _idx._idxMgr._docIDMapperFactory.getDocIDMapper((ZoieMultiReader<R>)reader);
        reader.setDocIDMapper(mapper);
      }
      // assume that this is the only place that _currentReader gets refreshed
      IndexReader oldReader = _currentReader;
      _currentReader = reader;
      // we release our hold on the old reader so that it will be closed when
      // all the clients release their hold on it, the reader will be closed
      // automatically.
      log.info("swap disk reader and release old one from system");
      if (oldReader !=null) ((ZoieIndexReader)oldReader).decZoieRef();//.decRef();
    }
    return reader;
  }
 
  public ZoieIndexReader<R> getIndexReader()
  {
    if (_currentReader!=null){
      return _currentReader;
    }
    else{
      return null;
    }
  }
     
  /**
   * Closes the factory.
   *
   */
  public void close()
  {
    closeReader();
  }
 
  /**
   * Closes the index reader
   */
  public void closeReader()
  {
    if(_currentReader != null)
    {
      try
      {
        _currentReader.decRef();
        int count = _currentReader.getRefCount();
        log.info("final closeReader in dispenser and current refCount: " + count + " at " + _currentReader.directory());
        if (count > 0)
        {
          log.warn("final closeReader call with reference count == " + count + " greater than 0. Potentially, " +
              "the IndexReaders are not properly return to ZoieSystem.");
        }
      }
      catch(IOException e)
      {
        ZoieHealth.setFatal();
        log.error("problem closing reader", e);
      }
      _currentReader = null;
    }
  }
}
TOP

Related Classes of proj.zoie.impl.indexing.internal.IndexReaderDispenser$InternalIndexReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.