@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); } }
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; }
public void synch() throws IOException { file.synch(); }
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); } }
public long getSize() { return file.getFileSize(); }
public void truncate() throws IOException { // SHRINK TO 0 file.shrink(0); }
public void close() throws IOException { if (file != null) file.close(); }
public void delete() throws IOException { if (file != null) file.delete(); }
public void close() throws IOException { for (OFile file : files) { if (file != null) file.close(); } }
public boolean exists() { return file.exists(); }
public void delete() throws IOException { for (OFile file : files) { if (file != null) file.delete(); } }
public long getFilledUpTo() { return file.getFilledUpTo(); }
public void synch() throws IOException { for (OFile file : files) { if (file != null && file.isOpen()) file.synch(); } }