예제 #1
0
        private Possible <FullCacheRecordWithDeterminism, Failure> AddOrGet(WeakFingerprintHash weak, CasHash casElement, BuildXL.Cache.Interfaces.Hash hashElement, CasEntries hashes)
        {
            Contract.Requires(!IsClosed);
            Contract.Requires(hashes.IsValid);

            Contract.Assert(!m_readOnly);

            // We check the Cas entries if we are strict
            if (StrictMetadataCasCoupling)
            {
                // Check that the content is valid.
                if (!m_pinnedToCas.ContainsKey(casElement))
                {
                    return(new UnpinnedCasEntryFailure(CacheId, casElement));
                }

                foreach (CasHash hash in hashes)
                {
                    if (!m_pinnedToCas.ContainsKey(hash))
                    {
                        return(new UnpinnedCasEntryFailure(CacheId, hash));
                    }
                }
            }

            var strongFingerprints = Cache.Fingerprints.GetOrAdd(weak, (key) => new ConcurrentDictionary <StrongFingerprint, FullCacheRecord>());

            var record = strongFingerprints.AddOrUpdate(
                new StrongFingerprint(weak, casElement, hashElement, Cache.CacheId),
                (strong) => new FullCacheRecord(strong, hashes),
                (strong, oldRecord) =>
            {
                // Do no harm here - we will recheck this outside to produce the error that it was a bad attempt
                if (oldRecord.CasEntries.Determinism.IsSinglePhaseNonDeterministic != hashes.Determinism.IsSinglePhaseNonDeterministic)
                {
                    return(oldRecord);
                }

                // We replace if we are SinglePhaseNonDeterministic *or*
                // if we are upgrading the determinism.
                if (hashes.Determinism.IsSinglePhaseNonDeterministic ||
                    (!oldRecord.CasEntries.Determinism.IsDeterministicTool &&
                     (hashes.Determinism.IsDeterministic && !hashes.Determinism.Equals(oldRecord.CasEntries.Determinism))) ||
                    HasMissingContent(oldRecord.CasEntries))
                {
                    oldRecord = new FullCacheRecord(strong, hashes);
                }

                return(oldRecord);
            });

            if (record.CasEntries.Determinism.IsSinglePhaseNonDeterministic != hashes.Determinism.IsSinglePhaseNonDeterministic)
            {
                return(new SinglePhaseMixingFailure(CacheId));
            }

            AddSessionRecord(record);
            if (record.CasEntries.Equals(hashes))
            {
                record = null;
            }
            else
            {
                // Check if tool determinism did not make it in - that means a very bad thing happened
                if (hashes.Determinism.IsDeterministicTool)
                {
                    return(new NotDeterministicFailure(Cache.CacheId, record, new FullCacheRecord(record.StrongFingerprint, hashes)));
                }
            }

            if (record == null)
            {
                return(new FullCacheRecordWithDeterminism(hashes.GetFinalDeterminism(Cache.IsAuthoritative, Cache.CacheGuid, CacheDeterminism.NeverExpires)));
            }
            else
            {
                return(new FullCacheRecordWithDeterminism(new FullCacheRecord(record.StrongFingerprint, record.CasEntries.GetModifiedCasEntriesWithDeterminism(Cache.IsAuthoritative, Cache.CacheGuid, CacheDeterminism.NeverExpires))));
            }
        }
예제 #2
0
        public Task <Possible <FullCacheRecordWithDeterminism, Failure> > AddOrGetAsync(WeakFingerprintHash weak, CasHash casElement, BuildXL.Cache.Interfaces.Hash hashElement, CasEntries hashes, UrgencyHint urgencyHint, Guid activityId)
        {
            Contract.Requires(!IsClosed);
            Contract.Requires(hashes.IsValid);
            Contract.Assert(!m_readOnly);

            return(Task.Run(() => AddOrGet(weak, casElement, hashElement, hashes)));
        }