/// <summary> /// Store build outputs in the cache by reading them from the file system /// </summary> /// <param name="builder">Builder key (first part of the key)</param> /// <param name="fingerprint">Dependency fingerprint created when the builder was executed (second part of the key)</param> /// <param name="outputs">Target-relative path of the build outputs to be cached</param> /// <param name="targetRoot">File system abstraction of the root target directory</param> public void Store(BuildKey builder, IDependencyFingerprint fingerprint, IEnumerable <TargetRelativePath> outputs, IFileSystemDirectory targetRoot) { MemoryCacheItem item = GetOrCreate(builder); var map = new ConcurrentDictionary <TargetRelativePath, byte[]>(); Parallel.ForEach(outputs, outputPath => { if (targetRoot.Exists(outputPath)) { using (var stream = targetRoot.ReadBinaryFile(outputPath)) { var buf = new byte[stream.Length]; stream.Read(buf, 0, buf.Length); map.TryAdd(outputPath, buf); } } else { map.TryAdd(outputPath, null); } }); item.Update(fingerprint, map); }
/// <summary> /// Store build outputs in the cache by reading them from the file system /// </summary> /// <param name="builder">Builder key (first part of the key)</param> /// <param name="fingerprint">Dependency fingerprint created when the builder was executed (second part of the key)</param> /// <param name="outputs">Target-relative path of the build outputs to be cached</param> /// <param name="targetRoot">File system abstraction of the root target directory</param> public void Store(BuildKey builder, IDependencyFingerprint fingerprint, IEnumerable<TargetRelativePath> outputs, IFileSystemDirectory targetRoot) { MemoryCacheItem item = GetOrCreate(builder); var map = new ConcurrentDictionary<TargetRelativePath, byte[]>(); Parallel.ForEach(outputs, outputPath => { if (targetRoot.Exists(outputPath)) { using (var stream = targetRoot.ReadBinaryFile(outputPath)) { var buf = new byte[stream.Length]; stream.Read(buf, 0, buf.Length); map.TryAdd(outputPath, buf); } } else { map.TryAdd(outputPath, null); } }); item.Update(fingerprint, map); }
/// <summary> /// Compares the stored fingerprint with another one /// </summary> /// <param name="otherFingerprint">The fingerprint to compare to</param> /// <returns>Returns <c>true</c> if the stored fingerprint matches the given one</returns> public bool MatchesFingerprint(IDependencyFingerprint otherFingerprint) { rwlock.EnterReadLock(); try { return(fingerprint.With(fp => fp.Equals(otherFingerprint))); } finally { rwlock.ExitReadLock(); } }
/// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(IDependencyFingerprint other) { var otherFingerprint = other as SourceSetFingerprint; if (otherFingerprint != null) { return(Equals(otherFingerprint)); } else { return(false); } }
/// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(IDependencyFingerprint other) { var combinedFingerprint = other as CombinedFingerprint; if (combinedFingerprint != null) { return(Equals(combinedFingerprint)); } else { return(false); } }
/// <summary> /// Updates the cached data for this item /// </summary> /// <param name="newFingerprint">The new dependency fingerprint</param> /// <param name="newOutputs">File name - binary data map of all the build outputs</param> public void Update(IDependencyFingerprint newFingerprint, IDictionary<TargetRelativePath, byte[]> newOutputs) { rwlock.EnterWriteLock(); try { fingerprint = newFingerprint; outputs = new Dictionary<TargetRelativePath, byte[]>(); foreach (var pair in newOutputs) outputs.Add(pair); } finally { rwlock.ExitWriteLock(); } }
/// <summary> /// Checks if the cache contains stored outputs for a given builder with a given dependency fingerprint /// /// <para>If <see cref="IBuildCache.Restore"/> will be also called, the cache must be locked first using /// the <see cref="IBuildCache.LockForBuilder"/> method.</para> /// </summary> /// <param name="builder">Builder key</param> /// <param name="fingerprint">Current dependency fingerprint</param> /// <returns>Returns <c>true</c> if there are stored outputs for the given builder and fingerprint combination.</returns> public bool Contains(BuildKey builder, IDependencyFingerprint fingerprint) { lock (cache) { MemoryCacheItem item; if (cache.TryGetValue(builder, out item)) { return(item.MatchesFingerprint(fingerprint)); } else { return(false); } } }
/// <summary> /// Checks if the cache contains stored outputs for a given builder with a given dependency fingerprint /// /// <para>If <see cref="IBuildCache.Restore"/> will be also called, the cache must be locked first using /// the <see cref="IBuildCache.LockForBuilder"/> method.</para> /// </summary> /// <param name="builder">Builder key</param> /// <param name="fingerprint">Current dependency fingerprint</param> /// <returns>Returns <c>true</c> if there are stored outputs for the given builder and fingerprint combination.</returns> public bool Contains(BuildKey builder, IDependencyFingerprint fingerprint) { lock (cache) { MemoryCacheItem item; if (cache.TryGetValue(builder, out item)) { return item.MatchesFingerprint(fingerprint); } else { return false; } } }
public bool Equals(IDependencyFingerprint other) { if (ReferenceEquals(null, other)) { return(false); } if (ReferenceEquals(this, other)) { return(true); } if (other.GetType() != this.GetType()) { return(false); } return(Equals((FSRepositoryFingerprint)other)); }
/// <summary> /// Store build outputs in the cache by reading them from the file system /// </summary> /// <param name="builder">Builder key (first part of the key)</param> /// <param name="fingerprint">Dependency fingerprint created when the builder was executed (second part of the key)</param> /// <param name="outputs">Target-relative path of the build outputs to be cached</param> /// <param name="targetRoot">File system abstraction of the root target directory</param> public void Store(BuildKey builder, IDependencyFingerprint fingerprint, IEnumerable<TargetRelativePath> outputs, IFileSystemDirectory targetRoot) { var lck = GetOrCreateLock(builder); lck.EnterWriteLock(); try { var cacheDir = cacheRoot.GetChildDirectory(GetCacheDirectoryName(builder), createIfMissing: true); SaveDependencyFingerprint(fingerprint, cacheDir); SaveOutputs(outputs, targetRoot, cacheDir); } finally { lck.ExitWriteLock(); } }
/// <summary> /// Checks if the cache contains stored outputs for a given builder with a given dependency fingerprint /// /// <para>If <see cref="IBuildCache.Restore"/> will be also called, the cache must be locked first using /// the <see cref="IBuildCache.LockForBuilder"/> method.</para> /// </summary> /// <param name="builder">Builder key</param> /// <param name="fingerprint">Current dependency fingerprint</param> /// <returns>Returns <c>true</c> if there are stored outputs for the given builder and fingerprint combination.</returns> public bool Contains(BuildKey builder, IDependencyFingerprint fingerprint) { var lck = GetOrCreateLock(builder); lck.EnterReadLock(); try { var dirName = GetCacheDirectoryName(builder); if (cacheRoot.Value.ChildDirectories.Contains(dirName)) { var cacheDir = cacheRoot.Value.GetChildDirectory(dirName); if (cacheDir.Files.Contains(DepsFileName)) { using (var depsStream = cacheDir.ReadBinaryFile(DepsFileName)) using (var memStream = new MemoryStream()) { fingerprint.Save(protocolSerializer, memStream); if (depsStream.Length != memStream.Length) { return(false); } var buf1 = memStream.ToArray(); var buf2 = new byte[depsStream.Length]; depsStream.Read(buf2, 0, (int)depsStream.Length); for (int i = 0; i < buf1.Length; i++) { if (buf1[i] != buf2[i]) { return(false); } } return(true); } } } return(false); } finally { lck.ExitReadLock(); } }
/// <summary> /// Updates the cached data for this item /// </summary> /// <param name="newFingerprint">The new dependency fingerprint</param> /// <param name="newOutputs">File name - binary data map of all the build outputs</param> public void Update(IDependencyFingerprint newFingerprint, IDictionary <TargetRelativePath, byte[]> newOutputs) { rwlock.EnterWriteLock(); try { fingerprint = newFingerprint; outputs = new Dictionary <TargetRelativePath, byte[]>(); foreach (var pair in newOutputs) { outputs.Add(pair); } } finally { rwlock.ExitWriteLock(); } }
/// <summary> /// Store build outputs in the cache by reading them from the file system /// </summary> /// <param name="builder">Builder key (first part of the key)</param> /// <param name="fingerprint">Dependency fingerprint created when the builder was executed (second part of the key)</param> /// <param name="outputs">Target-relative path of the build outputs to be cached</param> /// <param name="targetRoot">File system abstraction of the root target directory</param> public void Store(BuildKey builder, IDependencyFingerprint fingerprint, IEnumerable <TargetRelativePath> outputs, IFileSystemDirectory targetRoot) { var lck = GetOrCreateLock(builder); lck.EnterWriteLock(); try { var cacheDir = cacheRoot.Value.GetChildDirectory(GetCacheDirectoryName(builder), createIfMissing: true); SaveDependencyFingerprint(fingerprint, cacheDir); SaveOutputs(outputs, targetRoot, cacheDir); } finally { lck.ExitWriteLock(); } }
/// <summary> /// Checks if the cache contains stored outputs for a given builder with a given dependency fingerprint /// /// <para>If <see cref="IBuildCache.Restore"/> will be also called, the cache must be locked first using /// the <see cref="IBuildCache.LockForBuilder"/> method.</para> /// </summary> /// <param name="builder">Builder key</param> /// <param name="fingerprint">Current dependency fingerprint</param> /// <returns>Returns <c>true</c> if there are stored outputs for the given builder and fingerprint combination.</returns> public bool Contains(BuildKey builder, IDependencyFingerprint fingerprint) { var lck = GetOrCreateLock(builder); lck.EnterReadLock(); try { var dirName = GetCacheDirectoryName(builder); if (cacheRoot.Value.ChildDirectories.Contains(dirName)) { var cacheDir = cacheRoot.Value.GetChildDirectory(dirName); if (cacheDir.Files.Contains(DepsFileName)) { using (var depsStream = cacheDir.ReadBinaryFile(DepsFileName)) using (var memStream = new MemoryStream()) { fingerprint.Save(protocolSerializer, memStream); if (depsStream.Length != memStream.Length) return false; var buf1 = memStream.ToArray(); var buf2 = new byte[depsStream.Length]; depsStream.Read(buf2, 0, (int) depsStream.Length); for (int i = 0; i < buf1.Length; i++) if (buf1[i] != buf2[i]) return false; return true; } } } return false; } finally { lck.ExitReadLock(); } }
/// <summary> /// Checks if the cache contains stored outputs for a given builder with a given dependency fingerprint /// /// <para>If <see cref="IBuildCache.Restore"/> will be also called, the cache must be locked first using /// the <see cref="IBuildCache.LockForBuilder"/> method.</para> /// </summary> /// <param name="builder">Builder key</param> /// <param name="fingerprint">Current dependency fingerprint</param> /// <returns>Returns <c>true</c> if there are stored outputs for the given builder and fingerprint combination.</returns> public bool Contains(BuildKey builder, IDependencyFingerprint fingerprint) { var lck = GetOrCreateLock(builder); lck.EnterReadLock(); try { var dirName = GetCacheDirectoryName(builder); if (cacheRoot.ChildDirectories.Contains(dirName)) { var cacheDir = cacheRoot.GetChildDirectory(dirName); if (cacheDir.Files.Contains(DepsFileName)) { using (var depsStream = cacheDir.ReadBinaryFile(DepsFileName)) { var fpType = fingerprint.GetType(); var storedFp = Activator.CreateInstance(fpType, protocolSerializer, depsStream); bool fingerprintEquals = fingerprint.Equals(storedFp); if (!fingerprintEquals && EnableFingerprintDiff) { log.DebugFormat("[{0}] Fingerprint differs", dirName); log.DebugFormat("[{1}] Cached: {0}", storedFp, dirName); log.DebugFormat("[{1}] Current: {0}", fingerprint, dirName); } return(fingerprintEquals); } } } return(false); } finally { lck.ExitReadLock(); } }
/// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(IDependencyFingerprint other) { return(other is NoDependencyFingerprint); }
/// <summary> /// Saves a dependency fingerprint to the cache directory /// </summary> /// <param name="fingerprint">Fingerprint to be saved</param> /// <param name="cacheDir">Target directory</param> private void SaveDependencyFingerprint(IDependencyFingerprint fingerprint, IFileSystemDirectory cacheDir) { using (var depStream = cacheDir.CreateBinaryFile(DepsFileName)) fingerprint.Save(protocolSerializer, depStream); }
/// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(IDependencyFingerprint other) { return other is NoDependencyFingerprint; }
/// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(IDependencyFingerprint other) { var opf = other as InheritablePropertiesFingerprint <TParams, TDef>; return(opf != null && Equals(opf)); }
/// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(IDependencyFingerprint other) { var opf = other as ObjectPropertiesFingerprint; return(opf != null && Equals(opf)); }
/// <summary> /// Checks if the cache contains stored outputs for a given builder with a given dependency fingerprint /// /// <para>If <see cref="IBuildCache.Restore"/> will be also called, the cache must be locked first using /// the <see cref="IBuildCache.LockForBuilder"/> method.</para> /// </summary> /// <param name="builder">Builder key</param> /// <param name="fingerprint">Current dependency fingerprint</param> /// <returns>Returns <c>true</c> if there are stored outputs for the given builder and fingerprint combination.</returns> public bool Contains(BuildKey builder, IDependencyFingerprint fingerprint) { var lck = GetOrCreateLock(builder); lck.EnterReadLock(); try { var dirName = GetCacheDirectoryName(builder); if (cacheRoot.ChildDirectories.Contains(dirName)) { var cacheDir = cacheRoot.GetChildDirectory(dirName); if (cacheDir.Files.Contains(DepsFileName)) { using (var depsStream = cacheDir.ReadBinaryFile(DepsFileName)) { var fpType = fingerprint.GetType(); var storedFp = Activator.CreateInstance(fpType, protocolSerializer, depsStream); bool fingerprintEquals = fingerprint.Equals(storedFp); if (!fingerprintEquals && EnableFingerprintDiff) { log.DebugFormat("[{0}] Fingerprint differs", dirName); log.DebugFormat("[{1}] Cached: {0}", storedFp, dirName); log.DebugFormat("[{1}] Current: {0}", fingerprint, dirName); } return fingerprintEquals; } } } return false; } finally { lck.ExitReadLock(); } }
/// <summary> /// Compares the stored fingerprint with another one /// </summary> /// <param name="otherFingerprint">The fingerprint to compare to</param> /// <returns>Returns <c>true</c> if the stored fingerprint matches the given one</returns> public bool MatchesFingerprint(IDependencyFingerprint otherFingerprint) { rwlock.EnterReadLock(); try { return fingerprint.With(fp => fp.Equals(otherFingerprint)); } finally { rwlock.ExitReadLock(); } }