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 }