Package fi.foyt.hibernate.gae.search

Source Code of fi.foyt.hibernate.gae.search.GaeIndexOutput

package fi.foyt.hibernate.gae.search;

import java.io.IOException;
import java.util.logging.Logger;

import org.apache.lucene.store.IndexOutput;

import fi.foyt.hibernate.gae.search.persistence.dao.FileSegmentDAO;
import fi.foyt.hibernate.gae.search.persistence.domainmodel.FileSegment;

public class GaeIndexOutput extends IndexOutput {
 
  private static final Logger LOG = Logger.getLogger(GaeIndexInput.class.getName());
 
  public GaeIndexOutput(GaeFile f) {
    file = f;
    currentSegmentIndex = -1;
  }

  @Override
  public void close() throws IOException {
    flush();   
    LOG.fine("Index output writer closed");
  }

  @Override
  public void seek(long pos) throws IOException {
    // set the file length in case we seek back and flush() has not been called yet
    setFileLength();
    if (pos < segmentStart || pos >= segmentStart + GaeFile.SEGMENT_SIZE) {
      currentSegmentIndex = (int) (pos / GaeFile.SEGMENT_SIZE);
      switchCurrentSegment();
    }

    segmentPosition = (int) (pos % GaeFile.SEGMENT_SIZE);
  }

  @Override
  public long length() {
    return file.getLength();
  }

  @Override
  public void writeByte(byte b) throws IOException {
    try {
      if ((currentSegmentIndex < 0) || (segmentPosition == GaeFile.SEGMENT_SIZE)) {
        currentSegmentIndex++;
        switchCurrentSegment();
      }
 
      FileSegmentDAO fileSegmentDAO = new FileSegmentDAO();
     
      FileSegment fileSegment = getCurrentSegment();
      byte[] segmentData = getSegmentData(fileSegment, segmentPosition + 1);
      segmentData[segmentPosition++] = b;
      fileSegmentDAO.updateData(fileSegment, segmentData);
    } catch (Exception e) {
      throw new IOException(e);
    }
  }

  @Override
  public void writeBytes(byte[] b, int offset, int len) throws IOException {
    try {
      assert b != null;
      while (len > 0) {
        if ((currentSegmentIndex < 0) || (segmentPosition == GaeFile.SEGMENT_SIZE)) {
          currentSegmentIndex++;
          switchCurrentSegment();
        }
       
        FileSegmentDAO fileSegmentDAO = new FileSegmentDAO();
        FileSegment fileSegment = getCurrentSegment();
        int remainInSegment = GaeFile.SEGMENT_SIZE - segmentPosition;
        int bytesToCopy = len < remainInSegment ? len : remainInSegment;
       
        byte[] segmentData = getSegmentData(fileSegment, segmentPosition + bytesToCopy);
 
        System.arraycopy(b, offset, segmentData, segmentPosition, bytesToCopy);
        fileSegmentDAO.updateData(fileSegment, segmentData);
       
        offset += bytesToCopy;
        len -= bytesToCopy;
        segmentPosition += bytesToCopy;
      }
    } catch (Exception e) {
      throw new IOException(e);
    }
  }

  private final void switchCurrentSegment() throws IOException {
    if (currentSegmentIndex == file.getFileSegmentsCount()) {
      currentSegment = file.getNewSegment();
      currentSegmentIndex = currentSegment.getSegmentNo().intValue();
    } else {
      currentSegment = getCurrentSegment();
    }
   
    segmentPosition = 0;
    segmentStart = (long) GaeFile.SEGMENT_SIZE * (long) currentSegmentIndex;
  }

  private void setFileLength() {
    long pointer = segmentStart + segmentPosition;
    if (pointer > file.getLength()) {
      file.updateLength(pointer);
    }
  }

  @Override
  public void flush() throws IOException {
    file.setLastModified(System.currentTimeMillis());
    setFileLength();
   
    LOG.fine("Index output writer flushed");
  }

  @Override
  public long getFilePointer() {
    return currentSegmentIndex < 0 ? 0 : segmentStart + segmentPosition;
  }
 
  private byte[] getSegmentData(FileSegment fileSegment, int minLength) {
    byte[] segmentData = fileSegment.getData();
    if (segmentData == null) {
      file.updateLength(file.getLength() + minLength);
      return new byte[minLength];
    }
   
    if (segmentData.length < minLength) {
      file.updateLength(file.getLength() + (minLength - segmentData.length));
      byte[] newSegmentData = new byte[minLength];
      System.arraycopy(segmentData, 0, newSegmentData, 0, segmentData.length);
      return newSegmentData;
    }
   
    return segmentData;
  }
 
  private FileSegment getCurrentSegment() {
    if (currentSegment == null || currentSegment.getSegmentNo() != currentSegmentIndex)
      currentSegment = file.getFileSegment(currentSegmentIndex);

    return currentSegment;
  }
 
  private GaeFile file;
  private int currentSegmentIndex;
  private FileSegment currentSegment = null;
  private int segmentPosition;
  private long segmentStart;
}
TOP

Related Classes of fi.foyt.hibernate.gae.search.GaeIndexOutput

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.