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