protected synchronized void start(long curPrimaryGen) throws IOException {
  if (state.equals("init") == false) {
    throw new IllegalStateException("already started");
  }
  message("top: now start");
  try {
    String segmentsFileName=SegmentInfos.getLastCommitSegmentsFileName(dir);
    long maxPendingGen=-1;
    for (    String fileName : dir.listAll()) {
      if (fileName.startsWith(IndexFileNames.PENDING_SEGMENTS)) {
        long gen=Long.parseLong(fileName.substring(IndexFileNames.PENDING_SEGMENTS.length() + 1),Character.MAX_RADIX);
        if (gen > maxPendingGen) {
          maxPendingGen=gen;
        }
      }
    }
    SegmentInfos infos;
    if (segmentsFileName == null) {
      infos=new SegmentInfos();
      message("top: init: no segments in index");
    }
 else {
      message("top: init: read existing segments commit " + segmentsFileName);
      infos=SegmentInfos.readCommit(dir,segmentsFileName);
      message("top: init: segments: " + infos.toString() + " version="+ infos.getVersion());
      Collection<String> indexFiles=infos.files(false);
      lastCommitFiles.add(segmentsFileName);
      lastCommitFiles.addAll(indexFiles);
      deleter.incRef(lastCommitFiles);
      lastNRTFiles.addAll(indexFiles);
      deleter.incRef(lastNRTFiles);
      message("top: commitFiles=" + lastCommitFiles);
      message("top: nrtFiles=" + lastNRTFiles);
    }
    message("top: delete unknown files on init: all files=" + Arrays.toString(dir.listAll()));
    deleter.deleteUnknownFiles(segmentsFileName);
    message("top: done delete unknown files on init: all files=" + Arrays.toString(dir.listAll()));
    String s=infos.getUserData().get(PRIMARY_GEN_KEY);
    long myPrimaryGen;
    if (s == null) {
      assert infos.size() == 0;
      myPrimaryGen=-1;
    }
 else {
      myPrimaryGen=Long.parseLong(s);
    }
    message("top: myPrimaryGen=" + myPrimaryGen);
    boolean doCommit;
    if (infos.size() > 0 && myPrimaryGen != -1 && myPrimaryGen != curPrimaryGen) {
      assert myPrimaryGen < curPrimaryGen;
      final long initSyncStartNS=System.nanoTime();
      message("top: init: primary changed while we were down myPrimaryGen=" + myPrimaryGen + " vs curPrimaryGen="+ curPrimaryGen+ "; sync now before mgr init");
      CopyJob job=null;
      message("top: now delete starting commit point " + segmentsFileName);
      assert deleter.getRefCount(segmentsFileName) == 1;
      deleter.decRef(Collections.singleton(segmentsFileName));
      if (dir instanceof FSDirectory && ((FSDirectory)dir).checkPendingDeletions()) {
        throw new RuntimeException("replica cannot start: existing segments file=" + segmentsFileName + " must be removed in order to start, but the file delete failed");
      }
      boolean didRemove=lastCommitFiles.remove(segmentsFileName);
      assert didRemove;
      while (true) {
        job=newCopyJob("sync on startup replica=" + name() + " myVersion="+ infos.getVersion(),null,null,true,null);
        job.start();
        message("top: init: sync sis.version=" + job.getCopyState().version);
        try {
          job.runBlocking();
          job.finish();
          break;
        }
 catch (        IOException ioe) {
          job.cancel("startup failed",ioe);
          if (ioe.getMessage().contains("checksum mismatch after file copy")) {
            message("top: failed to copy: " + ioe + "; retrying");
          }
 else {
            throw ioe;
          }
        }
      }
      lastPrimaryGen=job.getCopyState().primaryGen;
      byte[] infosBytes=job.getCopyState().infosBytes;
      SegmentInfos syncInfos=SegmentInfos.readCommit(dir,new BufferedChecksumIndexInput(new ByteArrayIndexInput("SegmentInfos",job.getCopyState().infosBytes)),job.getCopyState().gen);
      syncInfos.updateGeneration(infos);
      infos=syncInfos;
      assert infos.getVersion() == job.getCopyState().version;
      message("  version=" + infos.getVersion() + " segments="+ infos.toString());
      message("top: init: incRef nrtFiles=" + job.getFileNames());
      deleter.incRef(job.getFileNames());
      message("top: init: decRef lastNRTFiles=" + lastNRTFiles);
      deleter.decRef(lastNRTFiles);
      lastNRTFiles.clear();
      lastNRTFiles.addAll(job.getFileNames());
      message("top: init: set lastNRTFiles=" + lastNRTFiles);
      lastFileMetaData=job.getCopyState().files;
      message(String.format(Locale.ROOT,"top: %d: start: done sync: took %.3fs for %s, opened NRT reader version=%d",id,(System.nanoTime() - initSyncStartNS) / 1000000000.0,bytesToString(job.getTotalBytesCopied()),job.getCopyState().version));
      doCommit=true;
    }
 else {
      doCommit=false;
      lastPrimaryGen=curPrimaryGen;
      message("top: same primary as before");
    }
    if (infos.getGeneration() < maxPendingGen) {
      message("top: move infos generation from " + infos.getGeneration() + " to "+ maxPendingGen);
      infos.setNextWriteGeneration(maxPendingGen);
    }
    sendNewReplica();
    mgr=new SegmentInfosSearcherManager(dir,this,infos,searcherFactory);
    IndexSearcher searcher=mgr.acquire();
    try {
      int hitCount=searcher.count(new TermQuery(new Term("marker","marker")));
      message("top: marker count=" + hitCount + " version="+ ((DirectoryReader)searcher.getIndexReader()).getVersion());
    }
  finally {
      mgr.release(searcher);
    }
    if (doCommit) {
      commit();
    }
    message("top: done start");
    state="idle";
  }
 catch (  Throwable t) {
    if (t.getMessage().startsWith("replica cannot start") == false) {
      message("exc on start:");
      t.printStackTrace(printStream);
    }
 else {
      dir.close();
    }
    IOUtils.reThrow(t);
  }
}

protected synchronized void start ( long curPrimaryGen ) throws IOException { if ( state . equals ( "init" ) == false ) { throw new IllegalStateException ( "already started" ) ; } message ( "top: now start" ) ; try { String segmentsFileName = SegmentInfos . getLastCommitSegmentsFileName ( dir ) ; long maxPendingGen = - 1 ; for ( String fileName : dir . listAll ( ) ) { if ( fileName . startsWith ( IndexFileNames . PENDING_SEGMENTS ) ) { long gen = Long . parseLong ( fileName . substring ( IndexFileNames . PENDING_SEGMENTS . length ( ) + 1 ) , Character . MAX_RADIX ) ; if ( gen > maxPendingGen ) { maxPendingGen = gen ; } } } SegmentInfos infos ; if ( segmentsFileName == null ) { infos = new SegmentInfos ( ) ; message ( "top: init: no segments in index" ) ; } else { message ( "top: init: read existing segments commit " + segmentsFileName ) ; infos = SegmentInfos . readCommit ( dir , segmentsFileName ) ; message ( "top: init: segments: " + infos . toString ( ) + " version=" + infos . getVersion ( ) ) ; Collection < String > indexFiles = infos . files ( false ) ; lastCommitFiles . add ( segmentsFileName ) ; lastCommitFiles . addAll ( indexFiles ) ; deleter . incRef ( lastCommitFiles ) ; lastNRTFiles . addAll ( indexFiles ) ; deleter . incRef ( lastNRTFiles ) ; message ( "top: commitFiles=" + lastCommitFiles ) ; message ( "top: nrtFiles=" + lastNRTFiles ) ; } message ( "top: delete unknown files on init: all files=" + Arrays . toString ( dir . listAll ( ) ) ) ; deleter . deleteUnknownFiles ( segmentsFileName ) ; message ( "top: done delete unknown files on init: all files=" + Arrays . toString ( dir . listAll ( ) ) ) ; String s = infos . getUserData ( ) . get ( PRIMARY_GEN_KEY ) ; long myPrimaryGen ; if ( s == null ) { assert infos . size ( ) == 0 ; myPrimaryGen = - 1 ; } else { myPrimaryGen = Long . parseLong ( s ) ; } message ( "top: myPrimaryGen=" + myPrimaryGen ) ; boolean doCommit ; if ( infos . size ( ) > 0 && myPrimaryGen != - 1 && myPrimaryGen != curPrimaryGen ) { assert myPrimaryGen < curPrimaryGen ; final long initSyncStartNS = System . nanoTime ( ) ; message ( "top: init: primary changed while we were down myPrimaryGen=" + myPrimaryGen + " vs curPrimaryGen=" + curPrimaryGen + "; sync now before mgr init" ) ; CopyJob job = null ; message ( "top: now delete starting commit point " + segmentsFileName ) ; assert deleter . getRefCount ( segmentsFileName ) == 1 ; deleter . decRef ( Collections . singleton ( segmentsFileName ) ) ; if ( dir instanceof FSDirectory && ( ( FSDirectory ) dir ) . checkPendingDeletions ( ) ) { throw new RuntimeException ( "replica cannot start: existing segments file=" + segmentsFileName + " must be removed in order to start, but the file delete failed" ) ; } boolean didRemove = lastCommitFiles . remove ( segmentsFileName ) ; assert didRemove ; while ( true ) { job = newCopyJob ( "sync on startup replica=" + name ( ) + " myVersion=" + infos . getVersion ( ) , null , null , true , null ) ; job . start ( ) ; message ( "top: init: sync sis.version=" + job . getCopyState ( ) . version ) ; try { job . runBlocking ( ) ; job . finish ( ) ; break ; } catch ( IOException ioe ) { job . cancel ( "startup failed" , ioe ) ; if ( ioe . getMessage ( ) . contains ( "checksum mismatch after file copy" ) ) { message ( "top: failed to copy: " + ioe + "; retrying" ) ; } else { throw ioe ; } } } lastPrimaryGen = job . getCopyState ( ) . primaryGen ; byte [ ] infosBytes = job . getCopyState ( ) . infosBytes ; SegmentInfos syncInfos = SegmentInfos . readCommit ( dir , new BufferedChecksumIndexInput ( new ByteArrayIndexInput ( "SegmentInfos" , job . getCopyState ( ) . infosBytes ) ) , job . getCopyState ( ) . gen ) ; syncInfos . updateGeneration ( infos ) ; infos = syncInfos ; assert infos . getVersion ( ) == job . getCopyState ( ) . version ; message ( "  version=" + infos . getVersion ( ) + " segments=" + infos . toString ( ) ) ; message ( "top: init: incRef nrtFiles=" + job . getFileNames ( ) ) ; deleter . incRef ( job . getFileNames ( ) ) ; message ( "top: init: decRef lastNRTFiles=" + lastNRTFiles ) ; deleter . decRef ( lastNRTFiles ) ; lastNRTFiles . clear ( ) ; lastNRTFiles . addAll ( job . getFileNames ( ) ) ; message ( "top: init: set lastNRTFiles=" + lastNRTFiles ) ; lastFileMetaData = job . getCopyState ( ) . files ; message ( String . format ( Locale . ROOT , "top: %d: start: done sync: took %.3fs for %s, opened NRT reader version=%d" , id , ( System . nanoTime ( ) - initSyncStartNS ) / 1000000000.0 , bytesToString ( job . getTotalBytesCopied ( ) ) , job . getCopyState ( ) . version ) ) ; doCommit = true ; } else { doCommit = false ; lastPrimaryGen = curPrimaryGen ; message ( "top: same primary as before" ) ; } if ( infos . getGeneration ( ) < maxPendingGen ) { message ( "top: move infos generation from " + infos . getGeneration ( ) + " to " + maxPendingGen ) ; infos . setNextWriteGeneration ( maxPendingGen ) ; } sendNewReplica ( ) ; mgr = new SegmentInfosSearcherManager ( dir , this , infos , searcherFactory ) ; IndexSearcher searcher = mgr . acquire ( ) ; try { int hitCount = searcher . count ( new TermQuery ( new Term ( "marker" , "marker" ) ) ) ; message ( "top: marker count=" + hitCount + " version=" + ( ( DirectoryReader ) searcher . getIndexReader ( ) ) . getVersion ( ) ) ; } finally { mgr . release ( searcher ) ; } if ( doCommit ) { commit ( ) ; } message ( "top: done start" ) ; state = "idle" ; } catch ( Throwable t ) { if ( t . getMessage ( ) . startsWith ( "replica cannot start" ) == false ) { message ( "exc on start:" ) ; t . printStackTrace ( printStream ) ; } else { dir . close ( ) ; } IOUtils . reThrow ( t ) ; } }
start up this replica , which possibly requires heavy copying of files from the primary node , if we were down for a long time
