private Pair<ClustererState,Integer> createInput(int partitionNumber,int threadId,int inputStart){
  int partitionSize=effectiveVocabulary.size() / vparts;
  int partitionStart=partitionNumber * partitionSize;
  int partitionEnd=partitionNumber == vparts - 1 ? effectiveVocabulary.size() : (partitionNumber + 1) * partitionSize;
  partitionSize=partitionEnd - partitionStart;
  int targetInputSize=partitionSize / numThreads;
  int startIndex=inputStart == 0 ? partitionStart + inputStart : inputStart;
  int endIndex=Math.min(partitionEnd,startIndex + targetInputSize);
  if (endIndex - startIndex <= 0)   return null;
  int i=endIndex - 1;
  for (; i < partitionEnd - 1; ++i) {
    IString iWord=effectiveVocabulary.get(i);
    IString nextWord=effectiveVocabulary.get(i + 1);
    int iClass=wordToClass.get(iWord);
    int nextClass=wordToClass.get(nextWord);
    if (iClass != nextClass) {
      break;
    }
  }
  logger.info(String.format("endIndex: %d -> %d",endIndex,i + 1));
  endIndex=i + 1;
  List<IString> inputVocab=effectiveVocabulary.subList(startIndex,endIndex);
  logger.info(String.format("Partition %d thread %d size %d: input %d-%d",partitionNumber,threadId,inputVocab.size(),startIndex,endIndex - 1));
  ClustererState state=new ClustererState(inputVocab,this.wordCount,this.historyCount,this.wordToClass,this.classCount,this.classHistoryCount,numClasses,this.currentObjectiveValue);
  return new Pair<ClustererState,Integer>(state,endIndex);
}

private Pair < ClustererState , Integer > createInput ( int partitionNumber , int threadId , int inputStart ) { int partitionSize = effectiveVocabulary . size ( ) / vparts ; int partitionStart = partitionNumber * partitionSize ; int partitionEnd = partitionNumber == vparts - 1 ? effectiveVocabulary . size ( ) : ( partitionNumber + 1 ) * partitionSize ; partitionSize = partitionEnd - partitionStart ; int targetInputSize = partitionSize / numThreads ; int startIndex = inputStart == 0 ? partitionStart + inputStart : inputStart ; int endIndex = Math . min ( partitionEnd , startIndex + targetInputSize ) ; if ( endIndex - startIndex <= 0 ) return null ; int i = endIndex - 1 ; for ( ; i < partitionEnd - 1 ; ++ i ) { IString iWord = effectiveVocabulary . get ( i ) ; IString nextWord = effectiveVocabulary . get ( i + 1 ) ; int iClass = wordToClass . get ( iWord ) ; int nextClass = wordToClass . get ( nextWord ) ; if ( iClass != nextClass ) { break ; } } logger . info ( String . format ( "endIndex: %d -> %d" , endIndex , i + 1 ) ) ; endIndex = i + 1 ; List < IString > inputVocab = effectiveVocabulary . subList ( startIndex , endIndex ) ; logger . info ( String . format ( "Partition %d thread %d size %d: input %d-%d" , partitionNumber , threadId , inputVocab . size ( ) , startIndex , endIndex - 1 ) ) ; ClustererState state = new ClustererState ( inputVocab , this . wordCount , this . historyCount , this . wordToClass , this . classCount , this . classHistoryCount , numClasses , this . currentObjectiveValue ) ; return new Pair < ClustererState , Integer > ( state , endIndex ) ; }
create the input to a clustering iteration .
