Esempio n. 1
0
  /**
   * 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);
    }
  }
Esempio n. 3
0
  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;
  }