in server/src/main/java/org/apache/cassandra/sidecar/restore/RestoreRangeTask.java [466:520]
private void removeOutOfRangeSSTables(File directory, RestoreSliceManifest manifest) throws RestoreJobException, IOException
{
Set<TokenRange> ranges = localTokenRangesProvider.localTokenRanges(range.keyspace()).get(range.owner().id());
if (ranges == null || ranges.isEmpty())
{
// Note: retry is allowed for the failure
throw new RestoreJobException("Unable to fetch local range, retry later");
}
// 1. remove the sstables that are fully out of range
// 2. detect if there is any range that partially overlaps. In that case, signal that this node is required to run nodetool cleanup on job completion
Iterator<Map.Entry<String, RestoreSliceManifest.ManifestEntry>> it = manifest.entrySet().iterator();
while (it.hasNext())
{
RestoreSliceManifest.ManifestEntry entry = it.next().getValue();
// TokenRange is open-closed, hence subtracting one from the rangeStart read from manifest
TokenRange sstableRange = new TokenRange(entry.startToken().subtract(BigInteger.ONE),
entry.endToken());
boolean hasOverlap = false;
boolean fullyEnclosed = false;
for (TokenRange owningRange : ranges)
{
if (hasOverlap)
{
break;
}
hasOverlap = owningRange.intersects(sstableRange);
if (hasOverlap)
{
fullyEnclosed = owningRange.encloses(sstableRange);
}
}
// fully out of range
if (!hasOverlap)
{
// remove the entry from manifest
it.remove();
// delete the files
for (String fileName : entry.componentsChecksum().keySet())
{
Path path = directory.toPath().resolve(fileName);
Files.deleteIfExists(path);
}
}
// overlaps, but is not fully enclosed; we need to run cleanup on this node
else if (!fullyEnclosed)
{
range.requestOutOfRangeDataCleanup();
}
}
}