| // Copyright 2019 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef COMPONENTS_METRICS_CALL_STACK_PROFILE_METADATA_H_ | 
 | #define COMPONENTS_METRICS_CALL_STACK_PROFILE_METADATA_H_ | 
 |  | 
 | #include <map> | 
 | #include <unordered_map> | 
 | #include <utility> | 
 |  | 
 | #include "base/optional.h" | 
 | #include "base/profiler/metadata_recorder.h" | 
 | #include "third_party/metrics_proto/sampled_profile.pb.h" | 
 |  | 
 | namespace metrics { | 
 |  | 
 | // Helper class for maintaining metadata state across samples and generating | 
 | // metadata proto messages. | 
 | class CallStackProfileMetadata { | 
 |  public: | 
 |   CallStackProfileMetadata(); | 
 |   ~CallStackProfileMetadata(); | 
 |  | 
 |   CallStackProfileMetadata(const CallStackProfileMetadata& other) = delete; | 
 |   CallStackProfileMetadata& operator=(const CallStackProfileMetadata& other) = | 
 |       delete; | 
 |  | 
 |   // Records the metadata for the next sample. | 
 |   void RecordMetadata( | 
 |       base::ProfileBuilder::MetadataProvider* metadata_provider); | 
 |  | 
 |   // Creates MetadataItems for the currently active metadata, adding new name | 
 |   // hashes to |metadata_name_hashes| if necessary. The same | 
 |   // |metadata_name_hashes| must be passed to each invocation, and must not be | 
 |   // modified outside this function. | 
 |   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> | 
 |   CreateSampleMetadata( | 
 |       google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes); | 
 |  | 
 |   // Applies the |item| to the samples between |begin| and |end| in | 
 |   // |stack_samples|. Overwrites any existing metadata item with the same key | 
 |   // and value that are already applied to the samples. | 
 |   void ApplyMetadata( | 
 |       const base::ProfileBuilder::MetadataItem& item, | 
 |       google::protobuf::RepeatedPtrField< | 
 |           CallStackProfile::StackSample>::iterator begin, | 
 |       google::protobuf::RepeatedPtrField< | 
 |           CallStackProfile::StackSample>::iterator end, | 
 |       google::protobuf::RepeatedPtrField<CallStackProfile::StackSample>* | 
 |           stack_samples, | 
 |       google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes); | 
 |  | 
 |  private: | 
 |   // Comparison function for the metadata map. | 
 |   struct MetadataKey; | 
 |   struct MetadataKeyCompare { | 
 |     bool operator()(const MetadataKey& a, const MetadataKey& b) const; | 
 |   }; | 
 |  | 
 |   // Definitions for a map-based representation of sample metadata. | 
 |   struct MetadataKey { | 
 |     MetadataKey(uint64_t name_hash, base::Optional<int64_t> key); | 
 |  | 
 |     MetadataKey(const MetadataKey& other); | 
 |     MetadataKey& operator=(const MetadataKey& other); | 
 |  | 
 |     // The name_hash and optional user-specified key uniquely identifies a | 
 |     // metadata value. See base::MetadataRecorder for details. | 
 |     uint64_t name_hash; | 
 |     base::Optional<int64_t> key; | 
 |   }; | 
 |   using MetadataMap = std::map<MetadataKey, int64_t, MetadataKeyCompare>; | 
 |  | 
 |   // Creates the metdata map from the array of items. | 
 |   MetadataMap CreateMetadataMap(base::ProfileBuilder::MetadataItemArray items, | 
 |                                 size_t item_count); | 
 |  | 
 |   // Returns all metadata items with new values in the current sample. | 
 |   MetadataMap GetNewOrModifiedMetadataItems(const MetadataMap& current_items, | 
 |                                             const MetadataMap& previous_items); | 
 |  | 
 |   // Returns all metadata items deleted since the previous sample. | 
 |   MetadataMap GetDeletedMetadataItems(const MetadataMap& current_items, | 
 |                                       const MetadataMap& previous_items); | 
 |  | 
 |   // Appends the |name_hash| to |name_hashes| if it's not already | 
 |   // present. Returns its index in |name_hashes|. | 
 |   size_t MaybeAppendNameHash( | 
 |       uint64_t name_hash, | 
 |       google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes); | 
 |  | 
 |   // The data provided for the next sample. | 
 |   base::ProfileBuilder::MetadataItemArray metadata_items_; | 
 |   size_t metadata_item_count_ = 0; | 
 |  | 
 |   // The data provided for the previous sample. | 
 |   MetadataMap previous_items_; | 
 |  | 
 |   // Maps metadata hash to index in |metadata_name_hash| array. | 
 |   std::unordered_map<uint64_t, int> metadata_hashes_cache_; | 
 | }; | 
 |  | 
 | }  // namespace metrics | 
 |  | 
 | #endif  // COMPONENTS_METRICS_CALL_STACK_PROFILE_METADATA_H_ |