Ejemplo n.º 1
0
        /// <summary>
        /// Deserializes into an instance of <see cref="VolumeMap"/>.
        /// </summary>
        public static VolumeMap Deserialize(BuildXLReader reader)
        {
            Contract.Requires(reader != null);

            var volumeMap = new VolumeMap();
            int count     = reader.ReadInt32Compact();

            for (int i = 0; i < count; ++i)
            {
                ulong          serialNumber = reader.ReadUInt64();
                bool           isValid      = reader.ReadBoolean();
                VolumeGuidPath path         = isValid ? VolumeGuidPath.Create(reader.ReadString()) : VolumeGuidPath.Invalid;
                volumeMap.m_volumePathsBySerial.Add(serialNumber, path);
            }

            int numJunctionRoots = reader.ReadInt32Compact();

            for (int i = 0; i < numJunctionRoots; ++i)
            {
                string path = reader.ReadString();
                var    id   = FileIdAndVolumeId.Deserialize(reader);
                volumeMap.m_junctionRootFileIds.Add(path, id);
            }

            return(volumeMap);
        }
Ejemplo n.º 2
0
        private static void ReadDictionary(BuildXLReader reader, Dictionary <string, FileIdAndVolumeId> dict)
        {
            int count = reader.ReadInt32Compact();

            for (int i = 0; i < count; ++i)
            {
                string path = reader.ReadString();
                var    id   = FileIdAndVolumeId.Deserialize(reader);
                dict.Add(path, id);
            }
        }
Ejemplo n.º 3
0
        private static LoadResult TryLoadInternal(string fileContentTablePath, byte entryTimeToLive)
        {
            Contract.Requires(!string.IsNullOrWhiteSpace(fileContentTablePath));
            Contract.Requires(entryTimeToLive > 0);

            if (!FileUtilities.FileExistsNoFollow(fileContentTablePath))
            {
                return(LoadResult.FileNotFound(fileContentTablePath));
            }

            Stopwatch sw = Stopwatch.StartNew();

            try
            {
                using (FileStream stream = FileUtilities.CreateFileStream(
                           fileContentTablePath,
                           FileMode.Open,
                           FileAccess.Read,
                           FileShare.Read | FileShare.Delete,
                           // Ok to evict the file from standby since the file will be overwritten and never reread from disk after this point.
                           FileOptions.SequentialScan))
                {
                    try
                    {
                        Analysis.IgnoreResult(s_fileEnvelope.ReadHeader(stream));
                    }
                    catch (BuildXLException ex)
                    {
                        return(LoadResult.InvalidFormat(fileContentTablePath, ex.LogEventMessage, sw.ElapsedMilliseconds));
                    }

                    using (var reader = new BuildXLReader(debug: false, stream: stream, leaveOpen: true))
                    {
                        var loadedTable = new FileContentTable();

                        uint numberOfEntries = reader.ReadUInt32();
                        int  hashLength      = ContentHashingUtilities.HashInfo.ByteLength;
                        var  hashBuffer      = new byte[hashLength];

                        for (uint i = 0; i < numberOfEntries; i++)
                        {
                            // Key: Volume and file ID
                            var fileIdAndVolumeId = FileIdAndVolumeId.Deserialize(reader);

                            // Entry: USN, hash, length, time to live.
                            Usn usn = new Usn(reader.ReadUInt64());

                            int hashBytesRead = 0;
                            while (hashBytesRead != hashLength)
                            {
                                int thisRead = reader.Read(hashBuffer, hashBytesRead, hashLength - hashBytesRead);
                                if (thisRead == 0)
                                {
                                    return(LoadResult.InvalidFormat(fileContentTablePath, "Unexpected end of stream", sw.ElapsedMilliseconds));
                                }

                                hashBytesRead += thisRead;
                                Contract.Assert(hashBytesRead <= hashLength);
                            }

                            long length = reader.ReadInt64();

                            byte thisEntryTimeToLive = reader.ReadByte();
                            if (thisEntryTimeToLive == 0)
                            {
                                return(LoadResult.InvalidFormat(fileContentTablePath, "TTL value must be positive", sw.ElapsedMilliseconds));
                            }

                            thisEntryTimeToLive = Math.Min(thisEntryTimeToLive, entryTimeToLive);
                            Contract.Assert(thisEntryTimeToLive > 0);

                            // We've loaded this entry just now and so clearly haven't used it yet. Tentatively decrement the TTL
                            // for the in-memory table; if the table is saved again without using this entry, the TTL will stay at this
                            // lower value.
                            thisEntryTimeToLive--;

                            var  observedVersionAndHash = new Entry(usn, ContentHashingUtilities.CreateFrom(hashBuffer), length, thisEntryTimeToLive);
                            bool added = loadedTable.m_entries.TryAdd(fileIdAndVolumeId, observedVersionAndHash);
                            Contract.Assume(added);
                        }

                        loadedTable.Counters.AddToCounter(FileContentTableCounters.NumEntries, loadedTable.Count);

                        return(LoadResult.Success(fileContentTablePath, loadedTable, sw.ElapsedMilliseconds));
                    }
                }
            }
            catch (Exception ex)
            {
                return(LoadResult.Exception(fileContentTablePath, ex, sw.ElapsedMilliseconds));
            }
        }