@Override
    public long readFrom(OFile file, long pos, ORecordVersion version) throws IOException {
      final ODistributedVersion distributedVersion = (ODistributedVersion) version;

      int len = 0;
      distributedVersion.counter = file.readInt(pos + len);
      len += OBinaryProtocol.SIZE_INT;
      distributedVersion.timestamp = file.readLong(pos + len);
      len += OBinaryProtocol.SIZE_LONG;
      distributedVersion.macAddress = file.readLong(pos + len);
      len += OBinaryProtocol.SIZE_LONG;
      return len;
    }
    @Override
    public int writeTo(OFile file, long pos, ORecordVersion version) throws IOException {
      final ODistributedVersion distributedVersion = (ODistributedVersion) version;

      int len = 0;
      file.writeInt(pos + len, distributedVersion.counter);
      len += OBinaryProtocol.SIZE_INT;
      file.writeLong(pos + len, distributedVersion.timestamp);
      len += OBinaryProtocol.SIZE_LONG;
      file.writeLong(pos + len, distributedVersion.macAddress);
      len += OBinaryProtocol.SIZE_LONG;

      return len;
    }
 public void open() throws IOException {
   // @TODO: LAZY OPEN FILES
   for (OFile file : files)
     if (!file.open()) {
       // LAST TIME THE FILE WAS NOT CLOSED IN SOFT WAY
       OLogManager.instance()
           .warn(
               this,
               "segment file '%s' was not closed correctly last time",
               OFileUtils.getPath(file.getName()));
       // TODO VERIFY DATA?
       wasSoftlyClosedAtPreviousTime = false;
     }
 }
 public OSingleFileSegment(
     final OStorageLocal iStorage, final OStorageFileConfiguration iConfig, final String iType)
     throws IOException {
   config = iConfig;
   storage = iStorage;
   file =
       OFileFactory.instance()
           .create(
               iType,
               iStorage.getVariableParser().resolveVariables(iConfig.path),
               iStorage.getMode());
   file.setMaxSize((int) OFileUtils.getSizeAsNumber(iConfig.maxSize));
   file.setIncrementSize((int) OFileUtils.getSizeAsNumber(iConfig.incrementSize));
 }
  public void writeContinuously(long iPosition, byte[] iData) throws IOException {
    long[] pos = getRelativePosition(iPosition);

    // IT'S PREFERABLE TO FIND SPACE WITHOUT ENLARGE ANY FILES: FIND THE FIRST FILE WITH FREE SPACE
    // TO USE
    OFile file;
    int remainingSize = iData.length;
    long offset = pos[1];

    for (int i = (int) pos[0]; remainingSize > 0; ++i) {
      file = files[i];
      if (remainingSize > file.getFilledUpTo() - offset) {
        if (file.getFilledUpTo() < offset) {
          throw new ODatabaseException("range check! " + file.getFilledUpTo() + " " + offset);
        }
        file.write(
            offset, iData, (int) (file.getFilledUpTo() - offset), iData.length - remainingSize);
        remainingSize -= (file.getFilledUpTo() - offset);
      } else {
        file.write(offset, iData, remainingSize, iData.length - remainingSize);
        remainingSize = 0;
      }
      offset = 0;
    }
  }
  public boolean open() throws IOException {
    boolean softClosed = file.open();
    if (!softClosed) {
      // LAST TIME THE FILE WAS NOT CLOSED IN SOFT WAY
      OLogManager.instance()
          .warn(
              this,
              "segment file '%s' was not closed correctly last time",
              OFileUtils.getPath(file.getName()));
      wasSoftlyClosedAtPreviousTime = false;
    }

    return softClosed;
  }
  public void create() throws IOException {
    segment.create(START_SIZE);
    super.create();

    final OFile f = segment.getFile();
    if (OGlobalConfiguration.STORAGE_CONFIGURATION_SYNC_ON_UPDATE.getValueAsBoolean()) f.synch();
  }
  private OFile createNewFile() throws IOException {
    final int num = files.length - 1;

    final OFile file =
        OFileFactory.instance()
            .create(
                type,
                config.getLocation() + "/" + name + "." + num + fileExtension,
                storage.getMode());
    file.setMaxSize(fileMaxSize);
    file.create(fileStartSize);
    files[num] = file;

    addInfoFileConfigEntry(file);

    return file;
  }
  public void readContinuously(final long iPosition, byte[] iBuffer, final int iSize)
      throws IOException {
    long[] pos = getRelativePosition(iPosition);

    // IT'S PREFERABLE TO FIND SPACE WITHOUT ENLARGE ANY FILES: FIND THE FIRST FILE WITH FREE SPACE
    // TO USE
    OFile file;
    int remainingSize = iSize;
    long offset = pos[1];
    assert offset < Integer.MAX_VALUE;
    assert offset > -1;
    for (int i = (int) pos[0]; remainingSize > 0; ++i) {
      file = files[i];
      if (remainingSize > file.getFilledUpTo() - offset) {
        if (file.getFilledUpTo() < offset) {
          throw new ODatabaseException("range check! " + file.getFilledUpTo() + " " + offset);
        }
        int toRead = file.getFilledUpTo() - (int) offset;
        file.read(offset, iBuffer, toRead, iSize - remainingSize);
        remainingSize -= toRead;
      } else {
        file.read(offset, iBuffer, remainingSize, iSize - remainingSize);
        remainingSize = 0;
      }
      offset = 0;
    }
  }
 public void rename(String iOldName, String iNewName) {
   for (OFile file : files) {
     final String osFileName = file.getName();
     if (osFileName.startsWith(name)) {
       final File newFile =
           new File(
               storage.getStoragePath()
                   + "/"
                   + iNewName
                   + osFileName.substring(osFileName.lastIndexOf(name) + name.length()));
       for (OStorageFileConfiguration conf : config.infoFiles) {
         if (conf.parent.name.equals(name)) conf.parent.name = iNewName;
         if (conf.path.endsWith(osFileName))
           conf.path = new String(conf.path.replace(osFileName, newFile.getName()));
       }
       boolean renamed = file.renameTo(newFile);
       while (!renamed) {
         OMemoryWatchDog.freeMemoryForResourceCleanup(100);
         renamed = file.renameTo(newFile);
       }
     }
   }
 }
  private void addInfoFileConfigEntry(final OFile file) throws IOException {
    OStorageFileConfiguration[] newConfigFiles =
        new OStorageFileConfiguration[config.infoFiles.length + 1];
    for (int i = 0; i < config.infoFiles.length; ++i) newConfigFiles[i] = config.infoFiles[i];
    config.infoFiles = newConfigFiles;

    // CREATE A NEW ENTRY FOR THE NEW FILE
    String fileNameToStore =
        storage.getVariableParser().convertPathToRelative(OFileUtils.getPath(file.getPath()));

    final OStorageSegmentConfiguration template = config.root.fileTemplate;

    config.infoFiles[config.infoFiles.length - 1] =
        new OStorageFileConfiguration(
            config,
            fileNameToStore,
            template.fileType,
            template.fileMaxSize,
            template.fileIncrementSize);
  }
  /**
   * Find free space for iRecordSize bytes.
   *
   * @param iRecordSize
   * @return a pair file-id/file-pos
   * @throws IOException
   */
  public long[] allocateSpace(final int iRecordSize) throws IOException {
    // IT'S PREFEREABLE TO FIND SPACE WITHOUT ENLARGE ANY FILES: FIND THE FIRST FILE WITH FREE SPACE
    // TO USE
    OFile file;
    for (int i = 0; i < files.length; ++i) {
      file = files[i];

      if (file.getFreeSpace() >= iRecordSize)
        // FOUND: RETURN THIS OFFSET
        return new long[] {i, file.allocateSpace(iRecordSize)};
    }

    // NOT FOUND: CHECK IF CAN OVERSIZE SOME FILES
    for (int i = 0; i < files.length; ++i) {
      file = files[i];

      if (file.canOversize(iRecordSize)) {
        // FOUND SPACE: ENLARGE IT
        return new long[] {i, file.allocateSpace(iRecordSize)};
      }
    }

    // TRY TO CREATE A NEW FILE
    if (maxSize > 0 && getSize() >= maxSize)
      // OUT OF MAX SIZE
      throw new OStorageException(
          "Unable to allocate the requested space of "
              + iRecordSize
              + " bytes because the segment is full: max-Size="
              + maxSize
              + ", currentSize="
              + getFilledUpTo());

    // COPY THE OLD ARRAY TO THE NEW ONE
    OFile[] newFiles = new OFile[files.length + 1];
    System.arraycopy(files, 0, newFiles, 0, files.length);
    files = newFiles;

    // CREATE THE NEW FILE AND PUT IT AS LAST OF THE ARRAY
    file = createNewFile();
    file.allocateSpace(iRecordSize);

    config.root.update();

    return new long[] {files.length - 1, 0};
  }
  @Override
  public void update() throws OSerializationException {
    try {
      final OFile f = segment.getFile();

      if (!f.isOpen()) return;

      final byte[] buffer = toStream();

      final int len = buffer.length + OBinaryProtocol.SIZE_INT;

      if (len > f.getFileSize()) f.allocateSpace(len - f.getFileSize());

      f.writeInt(0, buffer.length);
      f.write(OBinaryProtocol.SIZE_INT, buffer);
      if (OGlobalConfiguration.STORAGE_CONFIGURATION_SYNC_ON_UPDATE.getValueAsBoolean()) f.synch();

    } catch (Exception e) {
      throw new OSerializationException("Error on update storage configuration", e);
    }
  }
Beispiel #14
0
 public void create(final int iStartSize) throws IOException {
   file.create(iStartSize);
 }
  public long getSize() {
    long size = 0;
    for (OFile file : files) size += file.getFileSize();

    return size;
  }
  public long getFilledUpTo() {
    long filled = 0;
    for (OFile file : files) filled += file.getFilledUpTo();

    return filled;
  }
Beispiel #17
0
 public void synch() throws IOException {
   file.synch();
 }
Beispiel #18
0
 public void setSoftlyClosed(boolean softlyClosed) throws IOException {
   file.setSoftlyClosed(softlyClosed);
 }
  public long allocateSpaceContinuously(final int iSize) throws IOException {
    // IT'S PREFERABLE TO FIND SPACE WITHOUT ENLARGE ANY FILES: FIND THE FIRST FILE WITH FREE SPACE
    // TO USE
    OFile file;
    int remainingSize = iSize;
    // IF SOME FILES ALREADY CREATED
    int offset = -1;
    int fileNumber = -1;
    if (files.length > 0) {
      // CHECK IF THERE IS FREE SPACE IN LAST FILE IN CHAIN

      file = files[files.length - 1];

      if (file.getFreeSpace() > 0) {
        fileNumber = files.length - 1;
        if (remainingSize > file.getFreeSpace()) {
          remainingSize -= file.getFreeSpace();
          offset = file.allocateSpace(file.getFreeSpace());
        } else {
          return (long) (files.length - 1) * fileMaxSize + file.allocateSpace(remainingSize);
        }
      }

      // NOT FOUND FREE SPACE: CHECK IF CAN OVERSIZE LAST FILE

      final int oversize = fileMaxSize - file.getFileSize();
      if (oversize > 0 && remainingSize > 0) {
        fileNumber = files.length - 1;
        if (remainingSize > oversize) {
          remainingSize -= oversize;
          int newOffset = file.allocateSpace(oversize);
          // SAVE OFFSET IF IT WASN'T SAVED EARLIER
          if (offset == -1) offset = newOffset;
        } else {
          int newOffset = file.allocateSpace(remainingSize);
          if (offset == -1) offset = newOffset;
          if (fileNumber == -1) {
            fileNumber = files.length - 1;
          }
          return (long) fileNumber * fileMaxSize + offset;
        }
      }
    }

    // CREATE NEW FILE BECAUSE THERE IS NO FILES OR WE CANNOT ENLARGE EXISTING ENOUGH
    if (remainingSize > 0) {
      if (maxSize > 0 && getSize() >= maxSize)
        // OUT OF MAX SIZE
        throw new OStorageException(
            "Unable to allocate the requested space of "
                + iSize
                + " bytes because the segment is full: max-Size="
                + maxSize
                + ", currentSize="
                + getFilledUpTo());

      // COPY THE OLD ARRAY TO THE NEW ONE
      OFile[] newFiles = new OFile[files.length + 1];
      for (int i = 0; i < files.length; ++i) newFiles[i] = files[i];
      files = newFiles;

      // CREATE THE NEW FILE AND PUT IT AS LAST OF THE ARRAY
      file = createNewFile();
      file.allocateSpace(iSize);

      config.root.update();

      if (fileNumber == -1) {
        fileNumber = files.length - 1;
      }

      if (offset == -1) offset = 0;
    }

    return (long) fileNumber * fileMaxSize + offset;
  }
 public void setSoftlyClosed(boolean softlyClosed) throws IOException {
   for (OFile file : files) {
     if (file != null && file.isOpen()) file.setSoftlyClosed(softlyClosed);
   }
 }
Beispiel #21
0
 public long getSize() {
   return file.getFileSize();
 }
Beispiel #22
0
 public void truncate() throws IOException {
   // SHRINK TO 0
   file.shrink(0);
 }
Beispiel #23
0
 public void close() throws IOException {
   if (file != null) file.close();
 }
Beispiel #24
0
 public void delete() throws IOException {
   if (file != null) file.delete();
 }
 public void close() throws IOException {
   for (OFile file : files) {
     if (file != null) file.close();
   }
 }
Beispiel #26
0
 public boolean exists() {
   return file.exists();
 }
 public void delete() throws IOException {
   for (OFile file : files) {
     if (file != null) file.delete();
   }
 }
Beispiel #28
0
 public long getFilledUpTo() {
   return file.getFilledUpTo();
 }
 public void synch() throws IOException {
   for (OFile file : files) {
     if (file != null && file.isOpen()) file.synch();
   }
 }