winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ARPCorrelation.h (6174B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #pragma once
      4 
      5 #include <winget/LocIndependent.h>
      6 #include <winget/RepositorySource.h>
      7 
      8 #include <memory>
      9 #include <utility>
     10 #include <vector>
     11 
     12 namespace AppInstaller
     13 {
     14     namespace Manifest
     15     {
     16         struct Manifest;
     17         struct ManifestLocalization;
     18     }
     19 
     20     namespace Repository
     21     {
     22         struct IPackage;
     23         struct IPackageVersion;
     24         struct Source;
     25     }
     26 }
     27 
     28 namespace AppInstaller::Repository::Correlation
     29 {
     30     // Contains the { Id, Version, Channel }
     31     using ARPEntrySnapshot = std::tuple<Utility::LocIndString, Utility::LocIndString, Utility::LocIndString>;
     32 
     33     // Struct holding all the data from an ARP entry we use for the correlation
     34     struct ARPEntry
     35     {
     36         ARPEntry(std::shared_ptr<AppInstaller::Repository::IPackage> entry, bool isNewOrUpdated) : Entry(std::move(entry)), IsNewOrUpdated(isNewOrUpdated) {}
     37 
     38         // Data found in the ARP entry
     39         std::shared_ptr<AppInstaller::Repository::IPackage> Entry;
     40 
     41         // Whether this entry changed with the current installation
     42         bool IsNewOrUpdated;
     43     };
     44 
     45     // One of the possible options that could be chosen for correlation.
     46     struct CorrelationMeasure
     47     {
     48         // The value that the correlation algorithm assigned to the match with the package.
     49         double Measure{};
     50 
     51         // The package that was measured.
     52         std::shared_ptr<AppInstaller::Repository::IPackageVersion> Package{};
     53     };
     54 
     55     // The result of a heuristics correlation attempt.
     56     struct ARPHeuristicsCorrelationResult
     57     {
     58         // Correlated package from ARP
     59         std::shared_ptr<AppInstaller::Repository::IPackageVersion> Package{};
     60 
     61         // The reason for the correlation (for diagnostics).
     62         std::string Reason;
     63 
     64         // The correlation metrics and their associated ARP package information (for diagnostics).
     65         std::vector<CorrelationMeasure> Measures;
     66     };
     67 
     68     // The result of a correlation attempt.
     69     struct ARPCorrelationResult : public ARPHeuristicsCorrelationResult
     70     {
     71         // Number of ARP entries that are new or updated
     72         size_t ChangesToARP{};
     73 
     74         // Number of ARP entries that match with the installed package
     75         size_t MatchesInARP{};
     76 
     77         // Number of changed ARP entries that match the installed package
     78         size_t CountOfIntersectionOfChangesAndMatches{};
     79 
     80         ARPCorrelationResult& operator=(ARPHeuristicsCorrelationResult&& other)
     81         {
     82             *static_cast<ARPHeuristicsCorrelationResult*>(this) = std::move(other);
     83             return *this;
     84         }
     85     };
     86 
     87     // Allows callers finer control over how the correlation result will be chosen.
     88     // The values appear in order of their application in the correlation algorithm, meaning that a later
     89     // setting that is set to true can be preempted by an earlier setting, if a correlation occurs with the
     90     // earlier setting.
     91     // The default values are chosen to reflect what is used after an install on a consumer system.
     92     struct ARPCorrelationSettings
     93     {
     94         // This setting controls whether the name and publisher normalization algorithm will be used for correlation.
     95         // When true, normalization will be the first choice for correlation. This means that a normalized name+publisher
     96         // match will result in correlation (unless there are multiple matches).
     97         // When false, normalization will only be used for the statistics (MatchesInARP), but the correlation result package
     98         // will not be based on normalization.
     99         bool AllowNormalization = true;
    100 
    101         // This settings controls whether a single changed ARP entry is sufficient to result in correlation.
    102         // When true, if only a single ARP entry is detected as new or changed, it will be chosen as the correlated result.
    103         bool AllowSingleChange = false;
    104     };
    105 
    106     struct IARPMatchConfidenceAlgorithm
    107     {
    108         virtual ~IARPMatchConfidenceAlgorithm() = default;
    109         virtual void Init(const AppInstaller::Manifest::Manifest& manifest) = 0;
    110         virtual double ComputeConfidence(const ARPEntry& arpEntry) const = 0;
    111 
    112         // Returns an instance of the algorithm we will actually use.
    113         // We may use multiple instances/specializations for testing and experimentation.
    114         static IARPMatchConfidenceAlgorithm& Instance();
    115 
    116 #ifndef AICLI_DISABLE_TEST_HOOKS
    117         static void OverrideInstance(IARPMatchConfidenceAlgorithm* algorithmOverride);
    118         static void ResetInstance();
    119 #endif
    120     };
    121 
    122     ARPHeuristicsCorrelationResult FindARPEntryForNewlyInstalledPackageWithHeuristics(
    123         const AppInstaller::Manifest::Manifest& manifest,
    124         const std::vector<ARPEntry>& arpEntries);
    125 
    126     ARPHeuristicsCorrelationResult FindARPEntryForNewlyInstalledPackageWithHeuristics(
    127         const AppInstaller::Manifest::Manifest& manifest,
    128         const std::vector<ARPEntry>& arpEntries,
    129         IARPMatchConfidenceAlgorithm& algorithm);
    130 
    131     // Holds data needed for ARP correlation, as well as functions to run correlation on the collected data.
    132     struct ARPCorrelationData
    133     {
    134         ARPCorrelationData() = default;
    135         virtual ~ARPCorrelationData() = default;
    136 
    137         // Captures the ARP state before the package installation.
    138         void CapturePreInstallSnapshot();
    139 
    140         // Captures the ARP state differences after the package installation.
    141         void CapturePostInstallSnapshot();
    142 
    143         // Correlates the given manifest against the data previously collected with capture calls.
    144         virtual ARPCorrelationResult CorrelateForNewlyInstalled(const Manifest::Manifest& manifest, const ARPCorrelationSettings& settings = {});
    145 
    146         const std::vector<ARPEntrySnapshot>& GetPreInstallSnapshot() const { return m_preInstallSnapshot; }
    147 
    148     private:
    149         std::vector<ARPEntrySnapshot> m_preInstallSnapshot;
    150 
    151         Source m_postInstallSnapshotSource;
    152         std::vector<Correlation::ARPEntry> m_postInstallSnapshot;
    153     };
    154 }