Search in sources :

Example 1 with ValueContainer

use of com.intellij.util.indexing.ValueContainer in project intellij-community by JetBrains.

the class ChangeTrackingValueContainer method getMergedData.

// need 'synchronized' to ensure atomic initialization of merged data
// because several threads that acquired read lock may simultaneously execute the method
private ValueContainerImpl<Value> getMergedData() {
    ValueContainerImpl<Value> merged = myMerged;
    if (merged != null) {
        return merged;
    }
    synchronized (myInitializer.getLock()) {
        merged = myMerged;
        if (merged != null) {
            return merged;
        }
        FileId2ValueMapping<Value> fileId2ValueMapping = null;
        final ValueContainer<Value> fromDisk = myInitializer.compute();
        final ValueContainerImpl<Value> newMerged;
        if (fromDisk instanceof ValueContainerImpl) {
            newMerged = ((ValueContainerImpl<Value>) fromDisk).copy();
        } else {
            newMerged = ((ChangeTrackingValueContainer<Value>) fromDisk).getMergedData().copy();
        }
        if ((myAdded != null || myInvalidated != null) && (newMerged.size() > ValueContainerImpl.NUMBER_OF_VALUES_THRESHOLD || (myAdded != null && myAdded.size() > ValueContainerImpl.NUMBER_OF_VALUES_THRESHOLD))) {
            // Calculate file ids that have Value mapped to avoid O(NumberOfValuesInMerged) during removal
            fileId2ValueMapping = new FileId2ValueMapping<Value>(newMerged);
        }
        final FileId2ValueMapping<Value> finalFileId2ValueMapping = fileId2ValueMapping;
        if (myInvalidated != null) {
            myInvalidated.forEach(new TIntProcedure() {

                @Override
                public boolean execute(int inputId) {
                    if (finalFileId2ValueMapping != null)
                        finalFileId2ValueMapping.removeFileId(inputId);
                    else
                        newMerged.removeAssociatedValue(inputId);
                    return true;
                }
            });
        }
        if (myAdded != null) {
            if (fileId2ValueMapping != null) {
                // there is no sense for value per file validation because we have fileId -> value mapping and we are enforcing it here
                fileId2ValueMapping.disableOneValuePerFileValidation();
            }
            myAdded.forEach(new ValueContainer.ContainerAction<Value>() {

                @Override
                public boolean perform(final int inputId, final Value value) {
                    // enforcing "one-value-per-file for particular key" invariant
                    if (finalFileId2ValueMapping != null)
                        finalFileId2ValueMapping.removeFileId(inputId);
                    else
                        newMerged.removeAssociatedValue(inputId);
                    newMerged.addValue(inputId, value);
                    if (finalFileId2ValueMapping != null)
                        finalFileId2ValueMapping.associateFileIdToValue(inputId, value);
                    return true;
                }
            });
        }
        setNeedsCompacting(((UpdatableValueContainer) fromDisk).needsCompacting());
        myMerged = newMerged;
        return newMerged;
    }
}
Also used : TIntProcedure(gnu.trove.TIntProcedure) ValueContainer(com.intellij.util.indexing.ValueContainer)

Aggregations

ValueContainer (com.intellij.util.indexing.ValueContainer)1 TIntProcedure (gnu.trove.TIntProcedure)1