Package com.orientechnologies.orient.core.storage.fs

Source Code of com.orientechnologies.orient.core.storage.fs.OFileClassic

/*
* Copyright 1999-2010 Luca Garulli (l.garulli--at--orientechnologies.com)
*
* 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 com.orientechnologies.orient.core.storage.fs;

import java.io.IOException;
import java.nio.ByteBuffer;

import com.orientechnologies.common.io.OIOException;
import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.orient.core.OConstants;

/**
* Need to be synchronized by the external. Multiple Reader, Single Writer.<br/>
* Header structure:<br/>
* <br/>
* +-----------+--------------+---------------+---------------+<br/>
* | FILE SIZE | FILLED UP TO | SOFTLY CLOSED | SECURITY CODE |<br/>
* | 8 bytes . | 8 bytes .... | 1 byte ...... | 32 bytes .... |<br/>
* +-----------+--------------+---------------+---------------+<br/>
* = 1024 bytes<br/>
* <br/>
*/
public class OFileClassic extends OFile {
  protected ByteBuffer internalWriteBuffer = getBuffer(OConstants.SIZE_LONG);

  public OFileClassic(String iFileName, String iMode) throws IOException {
    super(iFileName, iMode);
  }

  @Override
  public void close() throws IOException {
    setSoftlyClosed(true);
    if (internalWriteBuffer != null)
      internalWriteBuffer = null;

    super.close();
  }

  @Override
  public void read(long iOffset, byte[] iDestBuffer, int iLenght)
      throws IOException {
    iOffset = checkRegions(iOffset, iLenght);

    ByteBuffer buffer = ByteBuffer.wrap(iDestBuffer);
    channel.read(buffer, iOffset);
  }

  @Override
  public int readInt(long iOffset) throws IOException {
    iOffset = checkRegions(iOffset, OConstants.SIZE_INT);
    return readData(iOffset, OConstants.SIZE_INT).getInt();
  }

  @Override
  public long readLong(long iOffset) throws IOException {
    iOffset = checkRegions(iOffset, OConstants.SIZE_LONG);
    return readData(iOffset, OConstants.SIZE_LONG).getLong();
  }

  @Override
  public short readShort(long iOffset) throws IOException {
    iOffset = checkRegions(iOffset, OConstants.SIZE_SHORT);
    return readData(iOffset, OConstants.SIZE_SHORT).getShort();
  }

  @Override
  public byte readByte(long iOffset) throws IOException {
    iOffset = checkRegions(iOffset, OConstants.SIZE_BYTE);
    return readData(iOffset, OConstants.SIZE_BYTE).get();
  }

  @Override
  public void writeInt(long iOffset, int iValue) throws IOException {
    iOffset = checkRegions(iOffset, OConstants.SIZE_INT);
    ByteBuffer buffer = getWriteBuffer(OConstants.SIZE_INT);
    buffer.putInt(iValue);
    writeData(buffer, iOffset);
  }

  @Override
  public void writeLong(long iOffset, long iValue) throws IOException {
    iOffset = checkRegions(iOffset, OConstants.SIZE_LONG);
    ByteBuffer buffer = getWriteBuffer(OConstants.SIZE_LONG);
    buffer.putLong(iValue);
    writeData(buffer, iOffset);
  }

  @Override
  public void writeShort(long iOffset, short iValue) throws IOException {
    iOffset = checkRegions(iOffset, OConstants.SIZE_INT);
    ByteBuffer buffer = getWriteBuffer(OConstants.SIZE_SHORT);
    buffer.putShort(iValue);
    writeData(buffer, iOffset);
  }

  @Override
  public void writeByte(long iOffset, byte iValue) throws IOException {
    iOffset = checkRegions(iOffset, OConstants.SIZE_BYTE);
    ByteBuffer buffer = getWriteBuffer(OConstants.SIZE_BYTE);
    buffer.put(iValue);
    writeData(buffer, iOffset);
  }

  @Override
  public void write(long iOffset, byte[] iSourceBuffer) throws IOException {
    iOffset = checkRegions(iOffset, iSourceBuffer.length);

    channel.write(ByteBuffer.wrap(iSourceBuffer), iOffset);
  }

  @Override
  public void changeSize(int iSize) {
    super.changeSize(iSize);
    try {
      channel.force(false);
      channel.close();
      openChannel(iSize);

    } catch (IOException e) {
      OLogManager.instance().error(this,
          "Error on changing the file size to " + iSize + " bytes",
          e, OIOException.class);
    }
  }

  /**
   * Do nothing. Use OFileSecure to be assure the file is saved
   *
   * @see OFileMMapSecure
   */
  @Override
  public void synch() {
  }

  @Override
  protected void readHeader() throws IOException {
    size = readData(0, OConstants.SIZE_INT).getInt();
    filledUpTo = readData(OConstants.SIZE_INT, OConstants.SIZE_INT)
        .getInt();
  }

  @Override
  protected void writeHeader() throws IOException {
    ByteBuffer buffer = getWriteBuffer(OConstants.SIZE_INT * 2);
    buffer.putInt(size);
    buffer.putInt(filledUpTo);
    writeData(buffer, 0);
  }

  @Override
  public void writeHeaderLong(final int iPosition,final  long iValue)
      throws IOException {
    ByteBuffer buffer = getWriteBuffer(OConstants.SIZE_LONG);
    buffer.putLong(iValue);
    writeData(buffer, HEADER_DATA_OFFSET + iPosition);
  }

  @Override
  public long readHeaderLong(final int iPosition) throws IOException {
    return readData(HEADER_DATA_OFFSET + iPosition, OConstants.SIZE_LONG).getLong();
  }

  @Override
  public boolean isSoftlyClosed() throws IOException {
    return readData(SOFTLY_CLOSED_OFFSET, OConstants.SIZE_BYTE).get() == 1;
  }

  @Override
  protected void setSoftlyClosed(final boolean iValue) throws IOException {
    final ByteBuffer buffer = getWriteBuffer(OConstants.SIZE_BYTE);
    buffer.put((byte) (iValue ? 1 : 0));
    writeData(buffer, SOFTLY_CLOSED_OFFSET);
    synch();
  }

  private ByteBuffer readData(final long iOffset,final  int iSize) throws IOException {
    ByteBuffer buffer = getBuffer(iSize);
    channel.read(buffer, iOffset);
    buffer.rewind();
    return buffer;
  }

  private void writeData(final ByteBuffer iBuffer, final long iOffset) throws IOException {
    iBuffer.rewind();
    channel.write(iBuffer, iOffset);
  }

  private ByteBuffer getBuffer(final int iLenght) {
    return ByteBuffer.allocate(iLenght);
  }

  private ByteBuffer getWriteBuffer(final int iLenght) {
    if (iLenght <= OConstants.SIZE_LONG)
      // RECYCLE WRITE BYTE BUFFER SINCE WRITES ARE SYNCHRONIZED
      return (ByteBuffer) internalWriteBuffer.rewind();

    return getBuffer(iLenght);
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.storage.fs.OFileClassic

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.