Exemple #1
0
        /// <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);
        }
Exemple #2
0
        /// <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);
        }
Exemple #3
0
 /// <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();
     }
 }
Exemple #4
0
        /// <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);
            }
        }
Exemple #5
0
        /// <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);
            }
        }
Exemple #6
0
 /// <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();
     }
 }
Exemple #7
0
 /// <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);
         }
     }
 }
Exemple #8
0
 /// <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;
         }
     }
 }
Exemple #9
0
 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));
 }
Exemple #10
0
        /// <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();
            }
        }
Exemple #11
0
        /// <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();
            }
        }
Exemple #12
0
 /// <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();
     }
 }
Exemple #13
0
        /// <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();
            }
        }
Exemple #14
0
        /// <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();
            }
        }
Exemple #15
0
        /// <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();
            }
        }
Exemple #16
0
 /// <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);
 }
Exemple #17
0
 /// <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);
 }
Exemple #18
0
 /// <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;
 }
Exemple #19
0
        /// <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));
        }
Exemple #20
0
        /// <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));
        }
Exemple #21
0
        /// <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();
            }
        }
Exemple #22
0
 /// <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);
 }
Exemple #23
0
 /// <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();
     }
 }