<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Orchard.Caching;
using Orchard.FileSystems.AppData;
using Orchard.FileSystems.VirtualPath;
using Orchard.Logging;

namespace Orchard.FileSystems.Dependencies {
    /// <summary>
    /// Similar to "Dependencies.xml" file, except we also store "GetFileHash" result for every 
    /// VirtualPath entry. This is so that if any virtual path reference in the file changes,
    /// the file stored by this component will also change.
    /// </summary>
    public class DefaultModuleDependenciesManager : IModuleDependenciesManager {
        private readonly IAppDataFolder _appDataFolder;
        private readonly IVirtualPathProvider _virtualPathProvider;
        private const string BasePath = "Dependencies";
        private const string FileName = "Dependencies.ModuleCompilation.xml";

        public DefaultModuleDependenciesManager(IAppDataFolder appDataFolder, IVirtualPathProvider virtualPathProvider) {
            _appDataFolder = appDataFolder;
            _virtualPathProvider = virtualPathProvider;
            Logger = NullLogger.Instance;
        }

        public ILogger Logger { get; set; }

        private string PersistencePath {
            get { return _appDataFolder.Combine(BasePath, FileName); }
        }

        public void StoreDependencies(IEnumerable<DependencyDescriptor> dependencyDescriptors) {
            var newDocument = CreateDocument(dependencyDescriptors);
            var previousDocument = ReadDocument(PersistencePath);
            if (CompareXmlDocuments(newDocument, previousDocument)) {
                Logger.Debug("Existing document is identical to new one. Skipping save.");
                return;
            }

            WriteDocument(PersistencePath, newDocument);
        }

        public IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor descriptor) {
            if (IsSupportedLoader(descriptor.LoaderName)) {
                // Currently, we return the same file for every module. An improvement would be to return
                // a specific file per module (this would decrease the number of recompilations needed
                // when modules change on disk).
                yield return _appDataFolder.GetVirtualPath(PersistencePath);
            }
        }

        private XDocument CreateDocument(IEnumerable<DependencyDescriptor> dependencies) {
            Func<string, XName> ns = (name => XName.Get(name));

            var document = new XDocument();
            document.Add(new XElement(ns("Dependencies")));
            var elements = FilterDependencies(dependencies).Select(
                d => new XElement("Dependency",
                    new XElement(ns("ModuleName"), d.Name),
                    new XElement(ns("LoaderName"), d.LoaderName),
                    new XElement(ns("VirtualPath"), d.VirtualPath),
                    new XElement(ns("FileHash"), _virtualPathProvider.GetFileHash(d.VirtualPath)),
                    new XElement(ns("References"), FilterReferences(d.References)
                        .Select(r => new XElement(ns("Reference"),<commit_msg>PERF: Adding various logging calls related to startup performance<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Orchard.Caching;
using Orchard.FileSystems.AppData;
using Orchard.FileSystems.VirtualPath;
using Orchard.Logging;

namespace Orchard.FileSystems.Dependencies {
    /// <summary>
    /// Similar to "Dependencies.xml" file, except we also store "GetFileHash" result for every 
    /// VirtualPath entry. This is so that if any virtual path reference in the file changes,
    /// the file stored by this component will also change.
    /// </summary>
    public class DefaultModuleDependenciesManager : IModuleDependenciesManager {
        private readonly IAppDataFolder _appDataFolder;
        private readonly IVirtualPathProvider _virtualPathProvider;
        private const string BasePath = "Dependencies";
        private const string FileName = "Dependencies.ModuleCompilation.xml";

        public DefaultModuleDependenciesManager(IAppDataFolder appDataFolder, IVirtualPathProvider virtualPathProvider) {
            _appDataFolder = appDataFolder;
            _virtualPathProvider = virtualPathProvider;
            Logger = NullLogger.Instance;
        }

        public ILogger Logger { get; set; }

        private string PersistencePath {
            get { return _appDataFolder.Combine(BasePath, FileName); }
        }

        public void StoreDependencies(IEnumerable<DependencyDescriptor> dependencyDescriptors) {
            Logger.Information("Storing module dependency file.");

            var newDocument = CreateDocument(dependencyDescriptors);
            var previousDocument = ReadDocument(PersistencePath);
            if (CompareXmlDocuments(newDocument, previousDocument)) {
                Logger.Debug("Existing document is identical to new one. Skipping save.");
            }
            else {
                WriteDocument(PersistencePath, newDocument);
            }

            Logger.Information("Done storing module dependency file.");
        }

        public IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor descriptor) {
            if (IsSupportedLoader(descriptor.LoaderName)) {
                // Currently, we return the same file for every module. An improvement would be to return
                // a specific file per module (this would decrease the number of recompilations needed
                // when modules change on disk).
                yield return _appDataFolder.GetVirtualPath(PersistencePath);
            }
        }

        private XDocument CreateDocument(IEnumerable<DependencyDescriptor> dependencies) {
            Func<string, XName> ns = (name => XName.Get(name));

            var document = new XDocument();
            document.Add(new XElement(ns("Dependencies")));
            var elements = FilterDependencies(dependencies).Select(
                d => new XElement("Dependency",
                    new XElement(ns("ModuleName"), d.Name),
                    new XElement(ns("LoaderName"), d.LoaderName),
                    new XElement(ns("VirtualPath"), d.VirtualPath),
                    new XElement(ns("FileHash"), _virtualPathProvider.GetFileHash(d.VirtualPath)),
                    new XElement(ns("References"), FilterReferences(d.References)
                        .Select(r => new XElement(ns("Reference"),
{'fraction_non_alphanumeric': 0.08020659273887286, 'fraction_numerical': 0.0, 'mean_word_length': 2.6638842515303285, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5327130', 'n_tokens_mistral': 1565, 'n_tokens_neox': 1483, 'n_words': 430}