Search in sources :

Example 1 with VersionAndType

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;
}
Also used : VersionAndType(org.apache.cassandra.io.sstable.format.VersionAndType) Descriptor(org.apache.cassandra.io.sstable.Descriptor) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Map(java.util.Map) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Descriptor (org.apache.cassandra.io.sstable.Descriptor)1 VersionAndType (org.apache.cassandra.io.sstable.format.VersionAndType)1