Coverage Report - org.galagosearch.core.types.NumberWordPosition
 
Classes in this File Line Coverage Branch Coverage Complexity
NumberWordPosition
25%
3/12
50%
1/2
0
NumberWordPosition$Processor
N/A
N/A
0
NumberWordPosition$Source
N/A
N/A
0
NumberWordPosition$WordDocumentPositionOrder
15%
4/26
0%
0/4
0
NumberWordPosition$WordDocumentPositionOrder$1
0%
0/9
0%
0/6
0
NumberWordPosition$WordDocumentPositionOrder$2
0%
0/9
0%
0/6
0
NumberWordPosition$WordDocumentPositionOrder$DuplicateEliminator
0%
0/39
0%
0/12
0
NumberWordPosition$WordDocumentPositionOrder$OrderedWriterClass
0%
0/16
0%
0/18
0
NumberWordPosition$WordDocumentPositionOrder$ShreddedBuffer
0%
0/164
0%
0/122
0
NumberWordPosition$WordDocumentPositionOrder$ShreddedCombiner
0%
0/55
0%
0/36
0
NumberWordPosition$WordDocumentPositionOrder$ShreddedProcessor
N/A
N/A
0
NumberWordPosition$WordDocumentPositionOrder$ShreddedReader
0%
0/98
0%
0/46
0
NumberWordPosition$WordDocumentPositionOrder$ShreddedSource
N/A
N/A
0
NumberWordPosition$WordDocumentPositionOrder$ShreddedWriter
0%
0/63
0%
0/30
0
NumberWordPosition$WordDocumentPositionOrder$TupleShredder
0%
0/20
0%
0/20
0
NumberWordPosition$WordDocumentPositionOrder$TupleUnshredder
0%
0/23
0%
0/2
0
 
 1  
 // This file was automatically generated with the command: 
 2  
 //     java org.galagosearch.tupleflow.typebuilder.TypeBuilderMojo ...
 3  
 package org.galagosearch.core.types;
 4  
 
 5  
 import org.galagosearch.tupleflow.Utility;
 6  
 import org.galagosearch.tupleflow.ArrayInput;
 7  
 import org.galagosearch.tupleflow.ArrayOutput;
 8  
 import org.galagosearch.tupleflow.Order;   
 9  
 import org.galagosearch.tupleflow.OrderedWriter;
 10  
 import org.galagosearch.tupleflow.Type; 
 11  
 import org.galagosearch.tupleflow.TypeReader;
 12  
 import org.galagosearch.tupleflow.Step; 
 13  
 import org.galagosearch.tupleflow.IncompatibleProcessorException;
 14  
 import org.galagosearch.tupleflow.ReaderSource;
 15  
 import java.io.IOException;             
 16  
 import java.io.EOFException;
 17  
 import java.io.UnsupportedEncodingException;
 18  
 import java.util.ArrayList;
 19  
 import java.util.Arrays;   
 20  
 import java.util.Comparator;
 21  
 import java.util.PriorityQueue;
 22  
 import java.util.Collection;
 23  
 
 24  
 public class NumberWordPosition implements Type<NumberWordPosition> {
 25  
     public int document;
 26  
     public byte[] word;
 27  
     public int position; 
 28  
     
 29  24
     public NumberWordPosition() {}
 30  0
     public NumberWordPosition(int document, byte[] word, int position) {
 31  0
         this.document = document;
 32  0
         this.word = word;
 33  0
         this.position = position;
 34  0
     }  
 35  
     
 36  
     public String toString() {
 37  
         try {
 38  0
             return String.format("%d,%s,%d",
 39  
                                    document, new String(word, "UTF-8"), position);
 40  0
         } catch(UnsupportedEncodingException e) {
 41  0
             throw new RuntimeException("Couldn't convert string to UTF-8.");
 42  
         }
 43  
     } 
 44  
 
 45  
     public Order<NumberWordPosition> getOrder(String... spec) {
 46  24
         if (Arrays.equals(spec, new String[] { "+word", "+document", "+position" })) {
 47  24
             return new WordDocumentPositionOrder();
 48  
         }
 49  0
         return null;
 50  
     } 
 51  
       
 52  
     public interface Processor extends Step, org.galagosearch.tupleflow.Processor<NumberWordPosition> {
 53  
         public void process(NumberWordPosition object) throws IOException;
 54  
         public void close() throws IOException;
 55  
     }                        
 56  
     public interface Source extends Step {
 57  
     }
 58  100
     public static class WordDocumentPositionOrder implements Order<NumberWordPosition> {
 59  
         public int hash(NumberWordPosition object) {
 60  0
             int h = 0;
 61  0
             h += Utility.hash(object.word);
 62  0
             h += Utility.hash(object.document);
 63  0
             h += Utility.hash(object.position);
 64  0
             return h;
 65  
         } 
 66  
         public Comparator<NumberWordPosition> greaterThan() {
 67  0
             return new Comparator<NumberWordPosition>() {
 68  0
                 public int compare(NumberWordPosition one, NumberWordPosition two) {
 69  0
                     int result = 0;
 70  
                     do {
 71  0
                         result = + Utility.compare(one.word, two.word);
 72  0
                         if(result != 0) break;
 73  0
                         result = + Utility.compare(one.document, two.document);
 74  0
                         if(result != 0) break;
 75  0
                         result = + Utility.compare(one.position, two.position);
 76  0
                         if(result != 0) break;
 77  
                     } while (false);
 78  0
                     return -result;
 79  
                 }
 80  
             };
 81  
         }     
 82  
         public Comparator<NumberWordPosition> lessThan() {
 83  0
             return new Comparator<NumberWordPosition>() {
 84  0
                 public int compare(NumberWordPosition one, NumberWordPosition two) {
 85  0
                     int result = 0;
 86  
                     do {
 87  0
                         result = + Utility.compare(one.word, two.word);
 88  0
                         if(result != 0) break;
 89  0
                         result = + Utility.compare(one.document, two.document);
 90  0
                         if(result != 0) break;
 91  0
                         result = + Utility.compare(one.position, two.position);
 92  0
                         if(result != 0) break;
 93  
                     } while (false);
 94  0
                     return result;
 95  
                 }
 96  
             };
 97  
         }     
 98  
         public TypeReader<NumberWordPosition> orderedReader(ArrayInput _input) {
 99  0
             return new ShreddedReader(_input);
 100  
         }    
 101  
 
 102  
         public TypeReader<NumberWordPosition> orderedReader(ArrayInput _input, int bufferSize) {
 103  0
             return new ShreddedReader(_input, bufferSize);
 104  
         }    
 105  
         public OrderedWriter<NumberWordPosition> orderedWriter(ArrayOutput _output) {
 106  0
             ShreddedWriter w = new ShreddedWriter(_output);
 107  0
             return new OrderedWriterClass(w); 
 108  
         }                                    
 109  0
         public static class OrderedWriterClass extends OrderedWriter< NumberWordPosition > {
 110  0
             NumberWordPosition last = null;
 111  0
             ShreddedWriter shreddedWriter = null; 
 112  
             
 113  0
             public OrderedWriterClass(ShreddedWriter s) {
 114  0
                 this.shreddedWriter = s;
 115  0
             }
 116  
             
 117  
             public void process(NumberWordPosition object) throws IOException {
 118  0
                boolean processAll = false;
 119  0
                if (processAll || last == null || 0 != Utility.compare(object.word, last.word)) { processAll = true; shreddedWriter.processWord(object.word); }
 120  0
                if (processAll || last == null || 0 != Utility.compare(object.document, last.document)) { processAll = true; shreddedWriter.processDocument(object.document); }
 121  0
                if (processAll || last == null || 0 != Utility.compare(object.position, last.position)) { processAll = true; shreddedWriter.processPosition(object.position); }
 122  0
                shreddedWriter.processTuple();
 123  0
                last = object;
 124  0
             }           
 125  
                  
 126  
             public void close() throws IOException {
 127  0
                 shreddedWriter.close();
 128  0
             }
 129  
             
 130  
             public Class<NumberWordPosition> getInputClass() {
 131  0
                 return NumberWordPosition.class;
 132  
             }
 133  
         } 
 134  
         public ReaderSource<NumberWordPosition> orderedCombiner(Collection<TypeReader<NumberWordPosition>> readers, boolean closeOnExit) {
 135  0
             ArrayList<ShreddedReader> shreddedReaders = new ArrayList();
 136  
             
 137  0
             for (TypeReader<NumberWordPosition> reader : readers) {
 138  0
                 shreddedReaders.add((ShreddedReader)reader);
 139  
             }
 140  
             
 141  0
             return new ShreddedCombiner(shreddedReaders, closeOnExit);
 142  
         }                  
 143  
         public NumberWordPosition clone(NumberWordPosition object) {
 144  0
             NumberWordPosition result = new NumberWordPosition();
 145  0
             if (object == null) return result;
 146  0
             result.document = object.document; 
 147  0
             result.word = object.word; 
 148  0
             result.position = object.position; 
 149  0
             return result;
 150  
         }                 
 151  
         public Class<NumberWordPosition> getOrderedClass() {
 152  76
             return NumberWordPosition.class;
 153  
         }                           
 154  
         public String[] getOrderSpec() {
 155  76
             return new String[] {"+word", "+document", "+position"};
 156  
         }
 157  
 
 158  
         public static String getSpecString() {
 159  0
             return "+word +document +position";
 160  
         }
 161  
                            
 162  
         public interface ShreddedProcessor extends Step {
 163  
             public void processWord(byte[] word) throws IOException;
 164  
             public void processDocument(int document) throws IOException;
 165  
             public void processPosition(int position) throws IOException;
 166  
             public void processTuple() throws IOException;
 167  
             public void close() throws IOException;
 168  
         }    
 169  
         public interface ShreddedSource extends Step {
 170  
         }                                              
 171  
         
 172  0
         public static class ShreddedWriter implements ShreddedProcessor {
 173  
             ArrayOutput output;
 174  0
             ShreddedBuffer buffer = new ShreddedBuffer();
 175  
             byte[] lastWord;
 176  
             int lastDocument;
 177  
             int lastPosition;
 178  0
             boolean lastFlush = false;
 179  
             
 180  0
             public ShreddedWriter(ArrayOutput output) {
 181  0
                 this.output = output;
 182  0
             }                        
 183  
             
 184  
             public void close() throws IOException {
 185  0
                 flush();
 186  0
             }
 187  
             
 188  
             public void processWord(byte[] word) {
 189  0
                 lastWord = word;
 190  0
                 buffer.processWord(word);
 191  0
             }
 192  
             public void processDocument(int document) {
 193  0
                 lastDocument = document;
 194  0
                 buffer.processDocument(document);
 195  0
             }
 196  
             public void processPosition(int position) {
 197  0
                 lastPosition = position;
 198  0
                 buffer.processPosition(position);
 199  0
             }
 200  
             public final void processTuple() throws IOException {
 201  0
                 if (lastFlush) {
 202  0
                     if(buffer.words.size() == 0) buffer.processWord(lastWord);
 203  0
                     if(buffer.documents.size() == 0) buffer.processDocument(lastDocument);
 204  0
                     if(buffer.positions.size() == 0) buffer.processPosition(lastPosition);
 205  0
                     lastFlush = false;
 206  
                 }
 207  0
                 buffer.processTuple();
 208  0
                 if (buffer.isFull())
 209  0
                     flush();
 210  0
             }
 211  
             public final void flushTuples(int pauseIndex) throws IOException {
 212  
                 
 213  0
                 while (buffer.getReadIndex() < pauseIndex) {
 214  
                            
 215  0
                     buffer.incrementTuple();
 216  
                 }
 217  0
             }  
 218  
             public final void flushWord(int pauseIndex) throws IOException {
 219  0
                 while (buffer.getReadIndex() < pauseIndex) {
 220  0
                     int nextPause = buffer.getWordEndIndex();
 221  0
                     int count = nextPause - buffer.getReadIndex();
 222  
                     
 223  0
                     output.writeBytes(buffer.getWord());
 224  0
                     output.writeInt(count);
 225  0
                     buffer.incrementWord();
 226  
                       
 227  0
                     flushDocument(nextPause);
 228  0
                     assert nextPause == buffer.getReadIndex();
 229  0
                 }
 230  0
             }
 231  
             public final void flushDocument(int pauseIndex) throws IOException {
 232  0
                 while (buffer.getReadIndex() < pauseIndex) {
 233  0
                     int nextPause = buffer.getDocumentEndIndex();
 234  0
                     int count = nextPause - buffer.getReadIndex();
 235  
                     
 236  0
                     output.writeInt(buffer.getDocument());
 237  0
                     output.writeInt(count);
 238  0
                     buffer.incrementDocument();
 239  
                       
 240  0
                     flushPosition(nextPause);
 241  0
                     assert nextPause == buffer.getReadIndex();
 242  0
                 }
 243  0
             }
 244  
             public final void flushPosition(int pauseIndex) throws IOException {
 245  0
                 while (buffer.getReadIndex() < pauseIndex) {
 246  0
                     int nextPause = buffer.getPositionEndIndex();
 247  0
                     int count = nextPause - buffer.getReadIndex();
 248  
                     
 249  0
                     output.writeInt(buffer.getPosition());
 250  0
                     output.writeInt(count);
 251  0
                     buffer.incrementPosition();
 252  
                       
 253  0
                     flushTuples(nextPause);
 254  0
                     assert nextPause == buffer.getReadIndex();
 255  0
                 }
 256  0
             }
 257  
             public void flush() throws IOException { 
 258  0
                 flushWord(buffer.getWriteIndex());
 259  0
                 buffer.reset(); 
 260  0
                 lastFlush = true;
 261  0
             }                           
 262  
         }
 263  0
         public static class ShreddedBuffer {
 264  0
             ArrayList<byte[]> words = new ArrayList();
 265  0
             ArrayList<Integer> documents = new ArrayList();
 266  0
             ArrayList<Integer> positions = new ArrayList();
 267  0
             ArrayList<Integer> wordTupleIdx = new ArrayList();
 268  0
             ArrayList<Integer> documentTupleIdx = new ArrayList();
 269  0
             ArrayList<Integer> positionTupleIdx = new ArrayList();
 270  0
             int wordReadIdx = 0;
 271  0
             int documentReadIdx = 0;
 272  0
             int positionReadIdx = 0;
 273  
                             
 274  0
             int writeTupleIndex = 0;
 275  0
             int readTupleIndex = 0;
 276  
             int batchSize;
 277  
 
 278  0
             public ShreddedBuffer(int batchSize) {
 279  0
                 this.batchSize = batchSize;
 280  
 
 281  0
             }                              
 282  
 
 283  
             public ShreddedBuffer() {    
 284  0
                 this(10000);
 285  0
             }                                                                                                                    
 286  
             
 287  
             public void processWord(byte[] word) {
 288  0
                 words.add(word);
 289  0
                 wordTupleIdx.add(writeTupleIndex);
 290  0
             }                                      
 291  
             public void processDocument(int document) {
 292  0
                 documents.add(document);
 293  0
                 documentTupleIdx.add(writeTupleIndex);
 294  0
             }                                      
 295  
             public void processPosition(int position) {
 296  0
                 positions.add(position);
 297  0
                 positionTupleIdx.add(writeTupleIndex);
 298  0
             }                                      
 299  
             public void processTuple() {
 300  0
                 assert words.size() > 0;
 301  0
                 assert documents.size() > 0;
 302  0
                 assert positions.size() > 0;
 303  0
                 writeTupleIndex++;
 304  0
             }
 305  
             public void resetData() {
 306  0
                 words.clear();
 307  0
                 documents.clear();
 308  0
                 positions.clear();
 309  0
                 wordTupleIdx.clear();
 310  0
                 documentTupleIdx.clear();
 311  0
                 positionTupleIdx.clear();
 312  0
                 writeTupleIndex = 0;
 313  0
             }                  
 314  
                                  
 315  
             public void resetRead() {
 316  0
                 readTupleIndex = 0;
 317  0
                 wordReadIdx = 0;
 318  0
                 documentReadIdx = 0;
 319  0
                 positionReadIdx = 0;
 320  0
             } 
 321  
 
 322  
             public void reset() {
 323  0
                 resetData();
 324  0
                 resetRead();
 325  0
             } 
 326  
             public boolean isFull() {
 327  0
                 return writeTupleIndex >= batchSize;
 328  
             }
 329  
 
 330  
             public boolean isEmpty() {
 331  0
                 return writeTupleIndex == 0;
 332  
             }                          
 333  
 
 334  
             public boolean isAtEnd() {
 335  0
                 return readTupleIndex >= writeTupleIndex;
 336  
             }           
 337  
             public void incrementWord() {
 338  0
                 wordReadIdx++;  
 339  0
             }                                                                                              
 340  
 
 341  
             public void autoIncrementWord() {
 342  0
                 while (readTupleIndex >= getWordEndIndex() && readTupleIndex < writeTupleIndex)
 343  0
                     wordReadIdx++;
 344  0
             }                 
 345  
             public void incrementDocument() {
 346  0
                 documentReadIdx++;  
 347  0
             }                                                                                              
 348  
 
 349  
             public void autoIncrementDocument() {
 350  0
                 while (readTupleIndex >= getDocumentEndIndex() && readTupleIndex < writeTupleIndex)
 351  0
                     documentReadIdx++;
 352  0
             }                 
 353  
             public void incrementPosition() {
 354  0
                 positionReadIdx++;  
 355  0
             }                                                                                              
 356  
 
 357  
             public void autoIncrementPosition() {
 358  0
                 while (readTupleIndex >= getPositionEndIndex() && readTupleIndex < writeTupleIndex)
 359  0
                     positionReadIdx++;
 360  0
             }                 
 361  
             public void incrementTuple() {
 362  0
                 readTupleIndex++;
 363  0
             }                    
 364  
             public int getWordEndIndex() {
 365  0
                 if ((wordReadIdx+1) >= wordTupleIdx.size())
 366  0
                     return writeTupleIndex;
 367  0
                 return wordTupleIdx.get(wordReadIdx+1);
 368  
             }
 369  
 
 370  
             public int getDocumentEndIndex() {
 371  0
                 if ((documentReadIdx+1) >= documentTupleIdx.size())
 372  0
                     return writeTupleIndex;
 373  0
                 return documentTupleIdx.get(documentReadIdx+1);
 374  
             }
 375  
 
 376  
             public int getPositionEndIndex() {
 377  0
                 if ((positionReadIdx+1) >= positionTupleIdx.size())
 378  0
                     return writeTupleIndex;
 379  0
                 return positionTupleIdx.get(positionReadIdx+1);
 380  
             }
 381  
             public int getReadIndex() {
 382  0
                 return readTupleIndex;
 383  
             }   
 384  
 
 385  
             public int getWriteIndex() {
 386  0
                 return writeTupleIndex;
 387  
             } 
 388  
             public byte[] getWord() {
 389  0
                 assert readTupleIndex < writeTupleIndex;
 390  0
                 assert wordReadIdx < words.size();
 391  
                 
 392  0
                 return words.get(wordReadIdx);
 393  
             }
 394  
             public int getDocument() {
 395  0
                 assert readTupleIndex < writeTupleIndex;
 396  0
                 assert documentReadIdx < documents.size();
 397  
                 
 398  0
                 return documents.get(documentReadIdx);
 399  
             }
 400  
             public int getPosition() {
 401  0
                 assert readTupleIndex < writeTupleIndex;
 402  0
                 assert positionReadIdx < positions.size();
 403  
                 
 404  0
                 return positions.get(positionReadIdx);
 405  
             }
 406  
 
 407  
             public void copyTuples(int endIndex, ShreddedProcessor output) throws IOException {
 408  0
                 while (getReadIndex() < endIndex) {
 409  0
                    output.processTuple();
 410  0
                    incrementTuple();
 411  
                 }
 412  0
             }                                                                           
 413  
             public void copyUntilIndexWord(int endIndex, ShreddedProcessor output) throws IOException {
 414  0
                 while (getReadIndex() < endIndex) {
 415  0
                     output.processWord(getWord());
 416  0
                     assert getWordEndIndex() <= endIndex;
 417  0
                     copyUntilIndexDocument(getWordEndIndex(), output);
 418  0
                     incrementWord();
 419  
                 }
 420  0
             } 
 421  
             public void copyUntilIndexDocument(int endIndex, ShreddedProcessor output) throws IOException {
 422  0
                 while (getReadIndex() < endIndex) {
 423  0
                     output.processDocument(getDocument());
 424  0
                     assert getDocumentEndIndex() <= endIndex;
 425  0
                     copyUntilIndexPosition(getDocumentEndIndex(), output);
 426  0
                     incrementDocument();
 427  
                 }
 428  0
             } 
 429  
             public void copyUntilIndexPosition(int endIndex, ShreddedProcessor output) throws IOException {
 430  0
                 while (getReadIndex() < endIndex) {
 431  0
                     output.processPosition(getPosition());
 432  0
                     assert getPositionEndIndex() <= endIndex;
 433  0
                     copyTuples(getPositionEndIndex(), output);
 434  0
                     incrementPosition();
 435  
                 }
 436  0
             }  
 437  
             public void copyUntilWord(ShreddedBuffer other, ShreddedProcessor output) throws IOException {
 438  0
                 while (!isAtEnd()) {
 439  0
                     if (other != null) {   
 440  0
                         assert !other.isAtEnd();
 441  0
                         int c = + Utility.compare(getWord(), other.getWord());
 442  
                     
 443  0
                         if (c > 0) {
 444  0
                             break;   
 445  
                         }
 446  
                         
 447  0
                         output.processWord(getWord());
 448  
                                       
 449  0
                         if (c < 0) {
 450  0
                             copyUntilIndexDocument(getWordEndIndex(), output);
 451  0
                         } else if (c == 0) {
 452  0
                             copyUntilDocument(other, output);
 453  0
                             autoIncrementWord();
 454  0
                             break;
 455  
                         }
 456  0
                     } else {
 457  0
                         output.processWord(getWord());
 458  0
                         copyUntilIndexDocument(getWordEndIndex(), output);
 459  
                     }
 460  0
                     incrementWord();  
 461  
                     
 462  
                
 463  
                 }
 464  0
             }
 465  
             public void copyUntilDocument(ShreddedBuffer other, ShreddedProcessor output) throws IOException {
 466  0
                 while (!isAtEnd()) {
 467  0
                     if (other != null) {   
 468  0
                         assert !other.isAtEnd();
 469  0
                         int c = + Utility.compare(getDocument(), other.getDocument());
 470  
                     
 471  0
                         if (c > 0) {
 472  0
                             break;   
 473  
                         }
 474  
                         
 475  0
                         output.processDocument(getDocument());
 476  
                                       
 477  0
                         if (c < 0) {
 478  0
                             copyUntilIndexPosition(getDocumentEndIndex(), output);
 479  0
                         } else if (c == 0) {
 480  0
                             copyUntilPosition(other, output);
 481  0
                             autoIncrementDocument();
 482  0
                             break;
 483  
                         }
 484  0
                     } else {
 485  0
                         output.processDocument(getDocument());
 486  0
                         copyUntilIndexPosition(getDocumentEndIndex(), output);
 487  
                     }
 488  0
                     incrementDocument();  
 489  
                     
 490  0
                     if (getWordEndIndex() <= readTupleIndex)
 491  0
                         break;   
 492  
                 }
 493  0
             }
 494  
             public void copyUntilPosition(ShreddedBuffer other, ShreddedProcessor output) throws IOException {
 495  0
                 while (!isAtEnd()) {
 496  0
                     if (other != null) {   
 497  0
                         assert !other.isAtEnd();
 498  0
                         int c = + Utility.compare(getPosition(), other.getPosition());
 499  
                     
 500  0
                         if (c > 0) {
 501  0
                             break;   
 502  
                         }
 503  
                         
 504  0
                         output.processPosition(getPosition());
 505  
                                       
 506  0
                         copyTuples(getPositionEndIndex(), output);
 507  0
                     } else {
 508  0
                         output.processPosition(getPosition());
 509  0
                         copyTuples(getPositionEndIndex(), output);
 510  
                     }
 511  0
                     incrementPosition();  
 512  
                     
 513  0
                     if (getDocumentEndIndex() <= readTupleIndex)
 514  0
                         break;   
 515  
                 }
 516  0
             }
 517  
             public void copyUntil(ShreddedBuffer other, ShreddedProcessor output) throws IOException {
 518  0
                 copyUntilWord(other, output);
 519  0
             }
 520  
             
 521  
         }                         
 522  0
         public static class ShreddedCombiner implements ReaderSource<NumberWordPosition>, ShreddedSource {   
 523  
             public ShreddedProcessor processor;
 524  
             Collection<ShreddedReader> readers;       
 525  0
             boolean closeOnExit = false;
 526  0
             boolean uninitialized = true;
 527  0
             PriorityQueue<ShreddedReader> queue = new PriorityQueue<ShreddedReader>();
 528  
             
 529  0
             public ShreddedCombiner(Collection<ShreddedReader> readers, boolean closeOnExit) {
 530  0
                 this.readers = readers;                                                       
 531  0
                 this.closeOnExit = closeOnExit;
 532  0
             }
 533  
                                   
 534  
             public void setProcessor(Step processor) throws IncompatibleProcessorException {  
 535  0
                 if (processor instanceof ShreddedProcessor) {
 536  0
                     this.processor = new DuplicateEliminator((ShreddedProcessor) processor);
 537  0
                 } else if (processor instanceof NumberWordPosition.Processor) {
 538  0
                     this.processor = new DuplicateEliminator(new TupleUnshredder((NumberWordPosition.Processor) processor));
 539  0
                 } else if (processor instanceof org.galagosearch.tupleflow.Processor) {
 540  0
                     this.processor = new DuplicateEliminator(new TupleUnshredder((org.galagosearch.tupleflow.Processor<NumberWordPosition>) processor));
 541  
                 } else {
 542  0
                     throw new IncompatibleProcessorException(processor.getClass().getName() + " is not supported by " + this.getClass().getName());                                                                       
 543  
                 }
 544  0
             }                                
 545  
             
 546  
             public Class<NumberWordPosition> getOutputClass() {
 547  0
                 return NumberWordPosition.class;
 548  
             }
 549  
             
 550  
             public void initialize() throws IOException {
 551  0
                 for (ShreddedReader reader : readers) {
 552  0
                     reader.fill();                                        
 553  
                     
 554  0
                     if (!reader.getBuffer().isAtEnd())
 555  0
                         queue.add(reader);
 556  
                 }   
 557  
 
 558  0
                 uninitialized = false;
 559  0
             }
 560  
 
 561  
             public void run() throws IOException {
 562  0
                 initialize();
 563  
                
 564  0
                 while (queue.size() > 0) {
 565  0
                     ShreddedReader top = queue.poll();
 566  0
                     ShreddedReader next = null;
 567  0
                     ShreddedBuffer nextBuffer = null; 
 568  
                     
 569  0
                     assert !top.getBuffer().isAtEnd();
 570  
                                                   
 571  0
                     if (queue.size() > 0) {
 572  0
                         next = queue.peek();
 573  0
                         nextBuffer = next.getBuffer();
 574  0
                         assert !nextBuffer.isAtEnd();
 575  
                     }
 576  
                     
 577  0
                     top.getBuffer().copyUntil(nextBuffer, processor);
 578  0
                     if (top.getBuffer().isAtEnd())
 579  0
                         top.fill();                 
 580  
                         
 581  0
                     if (!top.getBuffer().isAtEnd())
 582  0
                         queue.add(top);
 583  0
                 }              
 584  
                 
 585  0
                 if (closeOnExit)
 586  0
                     processor.close();
 587  0
             }
 588  
 
 589  
             public NumberWordPosition read() throws IOException {
 590  0
                 if (uninitialized)
 591  0
                     initialize();
 592  
 
 593  0
                 NumberWordPosition result = null;
 594  
 
 595  0
                 while (queue.size() > 0) {
 596  0
                     ShreddedReader top = queue.poll();
 597  0
                     result = top.read();
 598  
 
 599  0
                     if (result != null) {
 600  0
                         if (top.getBuffer().isAtEnd())
 601  0
                             top.fill();
 602  
 
 603  0
                         queue.offer(top);
 604  0
                         break;
 605  
                     } 
 606  0
                 }
 607  
 
 608  0
                 return result;
 609  
             }
 610  
         } 
 611  0
         public static class ShreddedReader implements Step, Comparable<ShreddedReader>, TypeReader<NumberWordPosition>, ShreddedSource {      
 612  
             public ShreddedProcessor processor;
 613  
             ShreddedBuffer buffer;
 614  0
             NumberWordPosition last = new NumberWordPosition();         
 615  0
             long updateWordCount = -1;
 616  0
             long updateDocumentCount = -1;
 617  0
             long updatePositionCount = -1;
 618  0
             long tupleCount = 0;
 619  0
             long bufferStartCount = 0;  
 620  
             ArrayInput input;
 621  
             
 622  0
             public ShreddedReader(ArrayInput input) {
 623  0
                 this.input = input; 
 624  0
                 this.buffer = new ShreddedBuffer();
 625  0
             }                               
 626  
             
 627  0
             public ShreddedReader(ArrayInput input, int bufferSize) { 
 628  0
                 this.input = input;
 629  0
                 this.buffer = new ShreddedBuffer(bufferSize);
 630  0
             }
 631  
                  
 632  
             public final int compareTo(ShreddedReader other) {
 633  0
                 ShreddedBuffer otherBuffer = other.getBuffer();
 634  
                 
 635  0
                 if (buffer.isAtEnd() && otherBuffer.isAtEnd()) {
 636  0
                     return 0;                 
 637  0
                 } else if (buffer.isAtEnd()) {
 638  0
                     return -1;
 639  0
                 } else if (otherBuffer.isAtEnd()) {
 640  0
                     return 1;
 641  
                 }
 642  
                                    
 643  0
                 int result = 0;
 644  
                 do {
 645  0
                     result = + Utility.compare(buffer.getWord(), otherBuffer.getWord());
 646  0
                     if(result != 0) break;
 647  0
                     result = + Utility.compare(buffer.getDocument(), otherBuffer.getDocument());
 648  0
                     if(result != 0) break;
 649  0
                     result = + Utility.compare(buffer.getPosition(), otherBuffer.getPosition());
 650  0
                     if(result != 0) break;
 651  
                 } while (false);                                             
 652  
                 
 653  0
                 return result;
 654  
             }
 655  
             
 656  
             public final ShreddedBuffer getBuffer() {
 657  0
                 return buffer;
 658  
             }                
 659  
             
 660  
             public final NumberWordPosition read() throws IOException {
 661  0
                 if (buffer.isAtEnd()) {
 662  0
                     fill();             
 663  
                 
 664  0
                     if (buffer.isAtEnd()) {
 665  0
                         return null;
 666  
                     }
 667  
                 }
 668  
                       
 669  0
                 assert !buffer.isAtEnd();
 670  0
                 NumberWordPosition result = new NumberWordPosition();
 671  
                 
 672  0
                 result.word = buffer.getWord();
 673  0
                 result.document = buffer.getDocument();
 674  0
                 result.position = buffer.getPosition();
 675  
                 
 676  0
                 buffer.incrementTuple();
 677  0
                 buffer.autoIncrementWord();
 678  0
                 buffer.autoIncrementDocument();
 679  0
                 buffer.autoIncrementPosition();
 680  
                 
 681  0
                 return result;
 682  
             }           
 683  
             
 684  
             public final void fill() throws IOException {
 685  
                 try {   
 686  0
                     buffer.reset();
 687  
                     
 688  0
                     if (tupleCount != 0) {
 689  
                                                       
 690  0
                         if(updateWordCount - tupleCount > 0) {
 691  0
                             buffer.words.add(last.word);
 692  0
                             buffer.wordTupleIdx.add((int) (updateWordCount - tupleCount));
 693  
                         }                              
 694  0
                         if(updateDocumentCount - tupleCount > 0) {
 695  0
                             buffer.documents.add(last.document);
 696  0
                             buffer.documentTupleIdx.add((int) (updateDocumentCount - tupleCount));
 697  
                         }                              
 698  0
                         if(updatePositionCount - tupleCount > 0) {
 699  0
                             buffer.positions.add(last.position);
 700  0
                             buffer.positionTupleIdx.add((int) (updatePositionCount - tupleCount));
 701  
                         }
 702  0
                         bufferStartCount = tupleCount;
 703  
                     }
 704  
                     
 705  0
                     while (!buffer.isFull()) {
 706  0
                         updatePosition();
 707  0
                         buffer.processTuple();
 708  0
                         tupleCount++;
 709  
                     }
 710  0
                 } catch(EOFException e) {}
 711  0
             }
 712  
 
 713  
             public final void updateWord() throws IOException {
 714  0
                 if (updateWordCount > tupleCount)
 715  0
                     return;
 716  
                      
 717  0
                 last.word = input.readBytes();
 718  0
                 updateWordCount = tupleCount + input.readInt();
 719  
                                       
 720  0
                 buffer.processWord(last.word);
 721  0
             }
 722  
             public final void updateDocument() throws IOException {
 723  0
                 if (updateDocumentCount > tupleCount)
 724  0
                     return;
 725  
                      
 726  0
                 updateWord();
 727  0
                 last.document = input.readInt();
 728  0
                 updateDocumentCount = tupleCount + input.readInt();
 729  
                                       
 730  0
                 buffer.processDocument(last.document);
 731  0
             }
 732  
             public final void updatePosition() throws IOException {
 733  0
                 if (updatePositionCount > tupleCount)
 734  0
                     return;
 735  
                      
 736  0
                 updateDocument();
 737  0
                 last.position = input.readInt();
 738  0
                 updatePositionCount = tupleCount + input.readInt();
 739  
                                       
 740  0
                 buffer.processPosition(last.position);
 741  0
             }
 742  
 
 743  
             public void run() throws IOException {
 744  
                 while (true) {
 745  0
                     fill();
 746  
                     
 747  0
                     if (buffer.isAtEnd())
 748  0
                         break;
 749  
                     
 750  0
                     buffer.copyUntil(null, processor);
 751  
                 }      
 752  0
                 processor.close();
 753  0
             }
 754  
             
 755  
             public void setProcessor(Step processor) throws IncompatibleProcessorException {  
 756  0
                 if (processor instanceof ShreddedProcessor) {
 757  0
                     this.processor = new DuplicateEliminator((ShreddedProcessor) processor);
 758  0
                 } else if (processor instanceof NumberWordPosition.Processor) {
 759  0
                     this.processor = new DuplicateEliminator(new TupleUnshredder((NumberWordPosition.Processor) processor));
 760  0
                 } else if (processor instanceof org.galagosearch.tupleflow.Processor) {
 761  0
                     this.processor = new DuplicateEliminator(new TupleUnshredder((org.galagosearch.tupleflow.Processor<NumberWordPosition>) processor));
 762  
                 } else {
 763  0
                     throw new IncompatibleProcessorException(processor.getClass().getName() + " is not supported by " + this.getClass().getName());                                                                       
 764  
                 }
 765  0
             }                                
 766  
             
 767  
             public Class<NumberWordPosition> getOutputClass() {
 768  0
                 return NumberWordPosition.class;
 769  
             }                
 770  
         }
 771  
         
 772  
         public static class DuplicateEliminator implements ShreddedProcessor {
 773  
             public ShreddedProcessor processor;
 774  0
             NumberWordPosition last = new NumberWordPosition();
 775  0
             boolean wordProcess = true;
 776  0
             boolean documentProcess = true;
 777  0
             boolean positionProcess = true;
 778  
                                            
 779  0
             public DuplicateEliminator() {}
 780  0
             public DuplicateEliminator(ShreddedProcessor processor) {
 781  0
                 this.processor = processor;
 782  0
             }
 783  
             
 784  
             public void setShreddedProcessor(ShreddedProcessor processor) {
 785  0
                 this.processor = processor;
 786  0
             }
 787  
 
 788  
             public void processWord(byte[] word) throws IOException {  
 789  0
                 if (wordProcess || Utility.compare(word, last.word) != 0) {
 790  0
                     last.word = word;
 791  0
                     processor.processWord(word);
 792  0
             resetDocument();
 793  0
                     wordProcess = false;
 794  
                 }
 795  0
             }
 796  
             public void processDocument(int document) throws IOException {  
 797  0
                 if (documentProcess || Utility.compare(document, last.document) != 0) {
 798  0
                     last.document = document;
 799  0
                     processor.processDocument(document);
 800  0
             resetPosition();
 801  0
                     documentProcess = false;
 802  
                 }
 803  0
             }
 804  
             public void processPosition(int position) throws IOException {  
 805  0
                 if (positionProcess || Utility.compare(position, last.position) != 0) {
 806  0
                     last.position = position;
 807  0
                     processor.processPosition(position);
 808  0
                     positionProcess = false;
 809  
                 }
 810  0
             }  
 811  
             
 812  
             public void resetWord() {
 813  0
                  wordProcess = true;
 814  0
             resetDocument();
 815  0
             }                                                
 816  
             public void resetDocument() {
 817  0
                  documentProcess = true;
 818  0
             resetPosition();
 819  0
             }                                                
 820  
             public void resetPosition() {
 821  0
                  positionProcess = true;
 822  0
             }                                                
 823  
                                
 824  
             public void processTuple() throws IOException {
 825  0
                 processor.processTuple();
 826  0
             } 
 827  
             
 828  
             public void close() throws IOException {
 829  0
                 processor.close();
 830  0
             }                    
 831  
         }
 832  
         public static class TupleUnshredder implements ShreddedProcessor {
 833  0
             NumberWordPosition last = new NumberWordPosition();
 834  
             public org.galagosearch.tupleflow.Processor<NumberWordPosition> processor;                               
 835  
             
 836  0
             public TupleUnshredder(NumberWordPosition.Processor processor) {
 837  0
                 this.processor = processor;
 838  0
             }         
 839  
             
 840  0
             public TupleUnshredder(org.galagosearch.tupleflow.Processor<NumberWordPosition> processor) {
 841  0
                 this.processor = processor;
 842  0
             }
 843  
             
 844  
             public NumberWordPosition clone(NumberWordPosition object) {
 845  0
                 NumberWordPosition result = new NumberWordPosition();
 846  0
                 if (object == null) return result;
 847  0
                 result.document = object.document; 
 848  0
                 result.word = object.word; 
 849  0
                 result.position = object.position; 
 850  0
                 return result;
 851  
             }                 
 852  
             
 853  
             public void processWord(byte[] word) throws IOException {
 854  0
                 last.word = word;
 855  0
             }   
 856  
                 
 857  
             public void processDocument(int document) throws IOException {
 858  0
                 last.document = document;
 859  0
             }   
 860  
                 
 861  
             public void processPosition(int position) throws IOException {
 862  0
                 last.position = position;
 863  0
             }   
 864  
                 
 865  
             
 866  
             public void processTuple() throws IOException {
 867  0
                 processor.process(clone(last));
 868  0
             }               
 869  
             
 870  
             public void close() throws IOException {
 871  0
                 processor.close();
 872  0
             }
 873  
         }     
 874  0
         public static class TupleShredder implements Processor {
 875  0
             NumberWordPosition last = new NumberWordPosition();
 876  
             public ShreddedProcessor processor;
 877  
             
 878  0
             public TupleShredder(ShreddedProcessor processor) {
 879  0
                 this.processor = processor;
 880  0
             }                              
 881  
             
 882  
             public NumberWordPosition clone(NumberWordPosition object) {
 883  0
                 NumberWordPosition result = new NumberWordPosition();
 884  0
                 if (object == null) return result;
 885  0
                 result.document = object.document; 
 886  0
                 result.word = object.word; 
 887  0
                 result.position = object.position; 
 888  0
                 return result;
 889  
             }                 
 890  
             
 891  
             public void process(NumberWordPosition object) throws IOException {                                                                                                                                                   
 892  0
                 boolean processAll = false;
 893  0
                 if(last == null || Utility.compare(last.word, object.word) != 0 || processAll) { processor.processWord(object.word); processAll = true; }
 894  0
                 if(last == null || Utility.compare(last.document, object.document) != 0 || processAll) { processor.processDocument(object.document); processAll = true; }
 895  0
                 if(last == null || Utility.compare(last.position, object.position) != 0 || processAll) { processor.processPosition(object.position); processAll = true; }
 896  0
                 processor.processTuple();                                         
 897  0
             }
 898  
                           
 899  
             public Class<NumberWordPosition> getInputClass() {
 900  0
                 return NumberWordPosition.class;
 901  
             }
 902  
             
 903  
             public void close() throws IOException {
 904  0
                 processor.close();
 905  0
             }                     
 906  
         }
 907  
     } 
 908  
 }