int holeSize = iRecordSize + RECORD_FIX_SIZE;
final long timer = OProfiler.getInstance().startChrono();
long[] pos = getRelativePosition(iRecordOffset);
final OFile file = files[(int) pos[0]];
final ODataHoleInfo closestHole = getCloserHole(iRecordOffset, iRecordSize, file, pos);
OProfiler.getInstance().stopChrono(PROFILER_HOLE_FIND_CLOSER, timer);
if (closestHole == null)
// CREATE A NEW ONE
holeSegment.createHole(iRecordOffset, holeSize);
else if (closestHole.dataOffset + closestHole.size == iRecordOffset) {
// IT'S CONSECUTIVE TO ANOTHER HOLE AT THE LEFT: UPDATE LAST ONE
holeSize += closestHole.size;
holeSegment.updateHole(closestHole, closestHole.dataOffset, holeSize);
} else if (holePositionOffset + holeSize == closestHole.dataOffset) {
// IT'S CONSECUTIVE TO ANOTHER HOLE AT THE RIGHT: UPDATE LAST ONE
holeSize += closestHole.size;
holeSegment.updateHole(closestHole, holePositionOffset, holeSize);
} else {
// QUITE CLOSE, AUTO-DEFRAG!
long closestHoleOffset;
if (iRecordOffset > closestHole.dataOffset)
closestHoleOffset = (closestHole.dataOffset + closestHole.size) - iRecordOffset;
else
closestHoleOffset = closestHole.dataOffset - (iRecordOffset + iRecordSize);
if (closestHoleOffset < 0) {
// MOVE THE DATA ON THE RIGHT AND USE ONE HOLE FOR BOTH
closestHoleOffset *= -1;
// SEARCH LAST SEGMENT
long moveFrom = closestHole.dataOffset + closestHole.size;
int recordSize;
final long offsetLimit = iRecordOffset;
final List<long[]> segmentPositions = new ArrayList<long[]>();
while (moveFrom < offsetLimit) {
pos = getRelativePosition(moveFrom);
if (pos[1] >= file.getFilledUpTo())
// END OF FILE
break;
recordSize = file.readInt(pos[1]) + RECORD_FIX_SIZE;
// SAVE DATA IN ARRAY
segmentPositions.add(0, new long[] { moveFrom, recordSize });
moveFrom += recordSize;