/** * 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); } }
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; }