use of org.apache.cassandra.io.sstable.format.VersionAndType in project cassandra by apache.
the class SSTablesGlobalTracker method handleSSTablesChange.
@VisibleForTesting
boolean handleSSTablesChange(Iterable<Descriptor> removed, Iterable<Descriptor> added) {
/*
We collect changes to 'sstablesForCurrentVersion' and 'sstablesForOtherVersions' as delta first, and then
apply those delta within a synchronized block below. The goal being to reduce the work done in that
synchronized block.
*/
int currentDelta = 0;
Map<VersionAndType, Integer> othersDelta = null;
/*
Note: we deal with removes first as if a notification both removes and adds, it's a compaction and while
it should never remove and add the same descriptor in practice, doing the remove first is more logical.
*/
for (Descriptor desc : removed) {
if (!allSSTables.remove(desc))
continue;
VersionAndType version = version(desc);
if (currentVersion.equals(version))
--currentDelta;
else
othersDelta = update(othersDelta, version, -1);
}
for (Descriptor desc : added) {
if (!allSSTables.add(desc))
continue;
VersionAndType version = version(desc);
if (currentVersion.equals(version))
++currentDelta;
else
othersDelta = update(othersDelta, version, +1);
}
if (currentDelta == 0 && (othersDelta == null))
return false;
/*
Set to true if the set of versions in use is changed by this update. That is, if a version having no
version prior now has some, or if the count for some version reaches 0.
*/
boolean triggerUpdate;
synchronized (this) {
triggerUpdate = (currentDelta > 0 && sstablesForCurrentVersion == 0) || (currentDelta < 0 && sstablesForCurrentVersion <= -currentDelta);
sstablesForCurrentVersion += currentDelta;
sstablesForCurrentVersion = sanitizeSSTablesCount(sstablesForCurrentVersion, currentVersion);
if (othersDelta != null) {
for (Map.Entry<VersionAndType, Integer> entry : othersDelta.entrySet()) {
VersionAndType version = entry.getKey();
int delta = entry.getValue();
/*
Updates the count, removing the version if it reaches 0 (note: we could use Map#compute for this,
but we wouldn't be able to modify `triggerUpdate` without making it an Object, so we don't bother).
*/
Integer oldValue = sstablesForOtherVersions.get(version);
int newValue = oldValue == null ? delta : oldValue + delta;
newValue = sanitizeSSTablesCount(newValue, version);
triggerUpdate |= oldValue == null || newValue == 0;
if (newValue == 0)
sstablesForOtherVersions.remove(version);
else
sstablesForOtherVersions.put(version, newValue);
}
}
if (triggerUpdate)
versionsInUse = computeVersionsInUse(sstablesForCurrentVersion, currentVersion, sstablesForOtherVersions);
}
return triggerUpdate;
}
Aggregations