/// <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)); }
/// <nodoc /> public VersionedFileIdentityAndContentInfo(VersionedFileIdentity identity, FileContentInfo fileContentInfo) { Identity = identity; FileContentInfo = fileContentInfo; }