FileDocCategorySizeDatePackage
DefaultSkipListWriter.javaAPI DocApache Lucene 2.2.05416Sat Jun 16 22:20:36 BST 2007org.apache.lucene.index

DefaultSkipListWriter

public class DefaultSkipListWriter extends MultiLevelSkipListWriter
Implements the skip list writer for the default posting list format that stores positions and payloads.

Fields Summary
private int[]
lastSkipDoc
private int[]
lastSkipPayloadLength
private long[]
lastSkipFreqPointer
private long[]
lastSkipProxPointer
private IndexOutput
freqOutput
private IndexOutput
proxOutput
private int
curDoc
private boolean
curStorePayloads
private int
curPayloadLength
private long
curFreqPointer
private long
curProxPointer
Constructors Summary
DefaultSkipListWriter(int skipInterval, int numberOfSkipLevels, int docCount, IndexOutput freqOutput, IndexOutput proxOutput)

    super(skipInterval, numberOfSkipLevels, docCount);
    this.freqOutput = freqOutput;
    this.proxOutput = proxOutput;
    
    lastSkipDoc = new int[numberOfSkipLevels];
    lastSkipPayloadLength = new int[numberOfSkipLevels];
    lastSkipFreqPointer = new long[numberOfSkipLevels];
    lastSkipProxPointer = new long[numberOfSkipLevels];
  
Methods Summary
protected voidresetSkip()

    super.resetSkip();
    Arrays.fill(lastSkipDoc, 0);
    Arrays.fill(lastSkipPayloadLength, -1);  // we don't have to write the first length in the skip list
    Arrays.fill(lastSkipFreqPointer, freqOutput.getFilePointer());
    Arrays.fill(lastSkipProxPointer, proxOutput.getFilePointer());
  
voidsetSkipData(int doc, boolean storePayloads, int payloadLength)
Sets the values for the current skip data.

    this.curDoc = doc;
    this.curStorePayloads = storePayloads;
    this.curPayloadLength = payloadLength;
    this.curFreqPointer = freqOutput.getFilePointer();
    this.curProxPointer = proxOutput.getFilePointer();
  
protected voidwriteSkipData(int level, org.apache.lucene.store.IndexOutput skipBuffer)

    // To efficiently store payloads in the posting lists we do not store the length of
    // every payload. Instead we omit the length for a payload if the previous payload had
    // the same length.
    // However, in order to support skipping the payload length at every skip point must be known.
    // So we use the same length encoding that we use for the posting lists for the skip data as well:
    // Case 1: current field does not store payloads
    //           SkipDatum                 --> DocSkip, FreqSkip, ProxSkip
    //           DocSkip,FreqSkip,ProxSkip --> VInt
    //           DocSkip records the document number before every SkipInterval th  document in TermFreqs. 
    //           Document numbers are represented as differences from the previous value in the sequence.
    // Case 2: current field stores payloads
    //           SkipDatum                 --> DocSkip, PayloadLength?, FreqSkip,ProxSkip
    //           DocSkip,FreqSkip,ProxSkip --> VInt
    //           PayloadLength             --> VInt    
    //         In this case DocSkip/2 is the difference between
    //         the current and the previous value. If DocSkip
    //         is odd, then a PayloadLength encoded as VInt follows,
    //         if DocSkip is even, then it is assumed that the
    //         current payload length equals the length at the previous
    //         skip point
    if (curStorePayloads) {
      int delta = curDoc - lastSkipDoc[level];
      if (curPayloadLength == lastSkipPayloadLength[level]) {
        // the current payload length equals the length at the previous skip point,
        // so we don't store the length again
        skipBuffer.writeVInt(delta * 2);
      } else {
        // the payload length is different from the previous one. We shift the DocSkip, 
        // set the lowest bit and store the current payload length as VInt.
        skipBuffer.writeVInt(delta * 2 + 1);
        skipBuffer.writeVInt(curPayloadLength);
        lastSkipPayloadLength[level] = curPayloadLength;
      }
    } else {
      // current field does not store payloads
      skipBuffer.writeVInt(curDoc - lastSkipDoc[level]);
    }
    skipBuffer.writeVInt((int) (curFreqPointer - lastSkipFreqPointer[level]));
    skipBuffer.writeVInt((int) (curProxPointer - lastSkipProxPointer[level]));

    lastSkipDoc[level] = curDoc;
    //System.out.println("write doc at level " + level + ": " + curDoc);
    
    lastSkipFreqPointer[level] = curFreqPointer;
    lastSkipProxPointer[level] = curProxPointer;