Package org.hibernate.search.backend.impl.lucene

Source Code of org.hibernate.search.backend.impl.lucene.PerDPQueueProcessor

package org.hibernate.search.backend.impl.lucene;

import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.slf4j.Logger;

import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.search.backend.LuceneWork;
import org.hibernate.search.backend.Workspace;
import org.hibernate.search.backend.impl.lucene.works.LuceneWorkVisitor;
import org.hibernate.search.util.LoggerFactory;

/**
* @author Sanne Grinovero
*/
class PerDPQueueProcessor {
 
  private static final Logger log = LoggerFactory.make();
  private final Workspace workspace;
  private final LuceneWorkVisitor worker;
  private final List<LuceneWork> workOnWriter = new ArrayList<LuceneWork>();
  private final List<LuceneWork> workOnReader= new ArrayList<LuceneWork>();
 
  // if any work passed to addWork needs one, set corresponding flag to true:
  private boolean batchmode = false;
  private boolean needsWriter = false;
  private boolean preferReader = false;
 
  public PerDPQueueProcessor(LuceneWorkVisitor worker) {
    this.worker = worker;
    this.workspace = worker.getWorkspace();
  }

  public void addWork(LuceneWork work) {
    if ( work.isBatch() ) {
      batchmode = true;
      log.debug( "Batch mode enabled" );
    }
    IndexInteractionType type = work.getWorkDelegate( worker ).getIndexInteractionType();
    switch ( type ) {
      case PREFER_INDEXREADER :
        preferReader = true;
        workOnReader.add( work );
        break;
      case NEEDS_INDEXWRITER :
        needsWriter = true;
        //fall through:
      case PREFER_INDEXWRITER :
        workOnWriter.add( work );
        break;
      default :
        throw new AssertionFailure( "Uncovered switch case for type " + type );
    }
  }

  public void performWorks() {
    // skip "resource optimization mode" when in batch to have all tasks use preferred (optimal) mode.
    if ( ! batchmode ) {
      //   see if we can skip using some resource
      if ( ! needsWriter ) { // no specific need:
        if ( preferReader ) {
          useReaderOnly();
        }
        else {
          useWriterOnly();
        }
      }
      else {
        useWriterOnly();
      }
      if ( ! (workOnWriter.isEmpty() || workOnReader.isEmpty() ) ) {
        throw new AssertionFailure(
          "During non-batch mode performWorks tries to use both IndexWriter and IndexReader." );
      }
    }
    // apply changes to index:
    log.trace( "Locking Workspace (or waiting to...)" );
    workspace.lock();
    log.trace( "Workspace lock aquired." );
    try {
      performReaderWorks();
      performWriterWorks();
    }
    finally {
      workspace.unlock();
      log.trace( "Unlocking Workspace" );
    }
  }

  /**
   * Do all workOnWriter on an IndexWriter.
   */
  private void performWriterWorks() {
    if ( workOnWriter.isEmpty() ) {
      return;
    }
    log.debug( "Opening an IndexWriter for update" );
    IndexWriter indexWriter = workspace.getIndexWriter( batchmode );
    try {
      for (LuceneWork lw : workOnWriter) {
        lw.getWorkDelegate( worker ).performWork( lw, indexWriter );
      }
      workspace.commitIndexWriter();
      //TODO next line is assuming the OptimizerStrategy will need an IndexWriter;
      // would be nicer to have the strategy put an OptimizeWork on the queue,
      // or just return "yes please" (true) to some method?
      //FIXME will not have a chance to trigger when no writer activity is done.
      // this is currently ok, until we enable mod.counts for deletions too.
      workspace.optimizerPhase();
    }
    finally {
      workspace.closeIndexWriter();
    }
  }

  /**
   * Do all workOnReader on an IndexReader.
   */
  private void performReaderWorks() {
    if ( workOnReader.isEmpty() ) {
      return;
    }
    log.debug( "Opening an IndexReader for update" );
    IndexReader indexReader = workspace.getIndexReader();
    try {
      for (LuceneWork lw : workOnReader) {
        lw.getWorkDelegate( worker ).performWork( lw, indexReader );
      }
    }
    finally {
      workspace.closeIndexReader();
    }
  }

  /**
   * forces all work to be done using only an IndexReader
   */
  private void useReaderOnly() {
    log.debug( "Skipping usage of an IndexWriter for updates" );
    workOnReader.addAll( workOnWriter );
    workOnWriter.clear();
  }

  /**
   * forces all work to be done using only an IndexWriter
   */
  private void useWriterOnly() {
    log.debug( "Skipping usage of an IndexReader for updates" );
    //position 0 needed to maintain correct ordering of Work: delete operations first.
    workOnWriter.addAll( 0, workOnReader );
    workOnReader.clear();
  }
 
}
TOP

Related Classes of org.hibernate.search.backend.impl.lucene.PerDPQueueProcessor

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.