Package org.sindice.siren.index.codecs.siren10

Source Code of org.sindice.siren.index.codecs.siren10.PosBlockIndexOutput$PosBlockWriter

/**
* Copyright 2014 National University of Ireland, Galway.
*
* This file is part of the SIREn project. Project and contact information:
*
*  https://github.com/rdelbru/SIREn
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.sindice.siren.index.codecs.siren10;

import java.io.IOException;

import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.IntsRef;
import org.sindice.siren.index.codecs.block.BlockCompressor;
import org.sindice.siren.index.codecs.block.BlockIndexOutput;
import org.sindice.siren.util.ArrayUtils;

/**
* Implementation of the {@link BlockIndexOutput} for the .pos file of the SIREn
* postings format.
*/
public class PosBlockIndexOutput extends BlockIndexOutput {

  private final int maxBlockSize;
  private final BlockCompressor posCompressor;

  public PosBlockIndexOutput(final IndexOutput out, final int maxBlockSize,
                             final BlockCompressor posCompressor)
  throws IOException {
    super(out);
    this.posCompressor = posCompressor;
    this.maxBlockSize = maxBlockSize;
  }

  @Override
  public PosBlockWriter getBlockWriter() {
    return new PosBlockWriter();
  }

  /**
   * Implementation of the {@link BlockWriter} for the .pos file.
   *
   * <p>
   *
   * Encode and write blocks containing the term positions.
   */
  protected class PosBlockWriter extends BlockWriter {

    IntsRef posBuffer;

    BytesRef posCompressedBuffer;

    private int currentPos = 0;

    public PosBlockWriter() {
      // ensure that the input buffers has the minimum size required
      // maxBlockSize is just use as a minimum initial capacity for the buffers
      posBuffer = new IntsRef(this.getMinimumBufferSize(maxBlockSize, posCompressor.getWindowSize()));
    }

    @Override
    protected void writeHeader() throws IOException {
      // logger.debug("Write Pos header: {}", this.hashCode());
      // logger.debug("Pos header start at {}", out.getFilePointer());

      // write block sizes
      out.writeVInt(posBuffer.length);
      // write size of compressed data block
      out.writeVInt(posCompressedBuffer.length);
    }

    @Override
    protected void compress() {
      // Flip buffer before compression
      posBuffer.length = posBuffer.offset;
      posBuffer.offset = 0;

      // determine max size of compressed buffer to avoid overflow
      final int size = posCompressor.maxCompressedSize(posBuffer.length);
      posCompressedBuffer = new BytesRef(size);

      posCompressor.compress(posBuffer, posCompressedBuffer);
    }

    @Override
    protected void writeData() throws IOException {
      // logger.debug("Write Pos data: {}", this.hashCode());

      out.writeBytes(posCompressedBuffer.bytes, posCompressedBuffer.length);
    }

    /**
     * Add the term position to the buffer
     */
    public void write(final int pos) {
      if (posBuffer.offset >= posBuffer.ints.length) {
        // Take the max to ensure that buffer will be large enough
        int newLength = Math.max(posBuffer.offset + 1, posBuffer.ints.length * 3/2);
        // ensure that the buffer is large enough to accomodate the window size
        newLength = this.getMinimumBufferSize(newLength, posCompressor.getWindowSize());
        ArrayUtils.growAndCopy(posBuffer, newLength);
      }

      posBuffer.ints[posBuffer.offset++] = pos - currentPos;
      currentPos = pos;
    }

    @Override
    protected void initBlock() {
      posBuffer.offset = posBuffer.length = 0;
      this.resetCurrentPosition();
    }

    public void resetCurrentPosition() {
      currentPos = 0;
    }

    @Override
    public boolean isEmpty() {
      return posBuffer.offset == 0;
    }

    @Override
    public boolean isFull() {
      // this implementation is never full as it is synchronised with doc block
      // and grows on demand
      return false;
    }

  }

}
TOP

Related Classes of org.sindice.siren.index.codecs.siren10.PosBlockIndexOutput$PosBlockWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.