Beispiel #1
0
        /// <summary>
        /// Creates a <see cref="FileMaterializationInfo"/> with an associated change tracking subscription.
        /// </summary>
        public FileMaterializationInfo(FileContentInfo fileContentInfo, PathAtom fileName, ReparsePointInfo?reparsePointInfo = null)
        {
            FileName         = fileName;
            FileContentInfo  = fileContentInfo;
            ReparsePointInfo = reparsePointInfo ?? ReparsePointInfo.CreateNoneReparsePoint();

            // NOTE: Update ExecutionResultSerializer WriteOutputContent/ReadOutputContent when adding new fields (i.e., BuildXL.Engine.Cache bond structure)
            // NOTE: Update FileArtifactKeyedHash when adding new fields (i.e., BuildXL.Engine bond structure)
        }
        /// <summary>
        /// Performs a smart copy in which no writes are performed if the destination already has the same content as the source
        /// (as provided in <paramref name="sourceContentInfo" />).
        /// Note that the destination may be replaced if it exists (otherwise there's no use in comparing hashes).
        /// </summary>
        /// <remarks>
        /// Note that <paramref name="sourceContentInfo" /> should be faithful to <paramref name="sourcePath" />, since that hash is
        /// to be recorded for <paramref name="destinationPath" />.
        /// </remarks>
        /// <returns>Indicates if the copy was elided (up-to-date) or actually performed.</returns>
        public static async Task <ConditionalUpdateResult> CopyIfContentMismatchedAsync(
            this FileContentTable fileContentTable,
            string sourcePath,
            string destinationPath,
            FileContentInfo sourceContentInfo)
        {
            Contract.Requires(!string.IsNullOrEmpty(sourcePath));
            Contract.Requires(!string.IsNullOrEmpty(destinationPath));

            VersionedFileIdentityAndContentInfo?destinationInfo = null;

            bool copied = await FileUtilities.CopyFileAsync(
                sourcePath,
                destinationPath,
                predicate : (source, dest) =>
            {
                // Nonexistent destination?
                if (dest == null)
                {
                    return(true);
                }

                VersionedFileIdentityAndContentInfo?knownDestinationInfo = fileContentTable.TryGetKnownContentHash(destinationPath, dest);
                if (!knownDestinationInfo.HasValue || knownDestinationInfo.Value.FileContentInfo.Hash != sourceContentInfo.Hash)
                {
                    return(true);
                }

                destinationInfo = knownDestinationInfo.Value;
                return(false);
            },
                onCompletion : (source, dest) =>
            {
                Contract.Assume(
                    destinationInfo == null,
                    "onCompletion should only happen when we committed to a copy (and then, we shouldn't have a destination version yet).");
                VersionedFileIdentity identity =
                    fileContentTable.RecordContentHash(
                        destinationPath,
                        dest,
                        sourceContentInfo.Hash,
                        sourceContentInfo.Length,
                        strict: true);
                destinationInfo = new VersionedFileIdentityAndContentInfo(identity, sourceContentInfo);
            });

            Contract.Assume(destinationInfo != null);
            return(new ConditionalUpdateResult(!copied, destinationInfo.Value));
        }
Beispiel #3
0
 /// <nodoc />
 public VersionedFileIdentityAndContentInfo(VersionedFileIdentity identity, FileContentInfo fileContentInfo)
 {
     Identity        = identity;
     FileContentInfo = fileContentInfo;
 }