in ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLogCache.java [316:365]
TruncationSegments truncate(long index, LogSegment openSegment, Runnable clearOpenSegment) {
final String reason = "truncate(" + index + ")";
try(AutoCloseableLock writeLock = writeLock()) {
final int segmentIndex = binarySearch(index);
if (segmentIndex == -segments.size() - 1) {
if (openSegment != null && openSegment.getEndIndex() >= index) {
final long oldEnd = openSegment.getEndIndex();
if (index == openSegment.getStartIndex()) {
// the open segment should be deleted
final SegmentFileInfo deleted = deleteOpenSegment(openSegment, clearOpenSegment);
return new TruncationSegments(reason, null, Collections.singletonList(deleted));
} else {
openSegment.truncate(index);
Preconditions.assertTrue(!openSegment.isOpen(),
() -> "Illegal state: " + openSegment + " remains open after truncate.");
final SegmentFileInfo info = new SegmentFileInfo(openSegment.getStartIndex(),
oldEnd, true, openSegment.getTotalFileSize(), openSegment.getEndIndex());
segments.add(openSegment);
sizeInBytes += openSegment.getTotalFileSize();
clearOpenSegment.run();
return new TruncationSegments(reason, info, Collections.emptyList());
}
}
} else if (segmentIndex >= 0) {
final LogSegment ts = segments.get(segmentIndex);
final long oldEnd = ts.getEndIndex();
final List<SegmentFileInfo> list = new ArrayList<>();
sizeInBytes -= ts.getTotalFileSize();
ts.truncate(index);
sizeInBytes += ts.getTotalFileSize();
final int size = segments.size();
for(int i = size - 1;
i >= (ts.numOfEntries() == 0? segmentIndex: segmentIndex + 1);
i--) {
LogSegment s = segments.remove(i);
sizeInBytes -= s.getTotalFileSize();
final long endOfS = i == segmentIndex? oldEnd: s.getEndIndex();
s.clear();
list.add(new SegmentFileInfo(s.getStartIndex(), endOfS, false, 0, s.getEndIndex()));
}
if (openSegment != null) {
list.add(deleteOpenSegment(openSegment, clearOpenSegment));
}
SegmentFileInfo t = ts.numOfEntries() == 0? null:
new SegmentFileInfo(ts.getStartIndex(), oldEnd, false, ts.getTotalFileSize(), ts.getEndIndex());
return new TruncationSegments(reason, t, list);
}
return null;
}
}