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)))); } }
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))); }