// 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 #include #include #include "base/profiler/metadata_recorder.h" #include "third_party/abseil-cpp/absl/types/optional.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( const base::MetadataRecorder::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 CreateSampleMetadata( google::protobuf::RepeatedField* 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::MetadataRecorder::Item& item, google::protobuf::RepeatedPtrField< CallStackProfile::StackSample>::iterator begin, google::protobuf::RepeatedPtrField< CallStackProfile::StackSample>::iterator end, google::protobuf::RepeatedPtrField* stack_samples, google::protobuf::RepeatedField* 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, absl::optional 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; absl::optional key; }; using MetadataMap = std::map; // Creates the metadata map from the array of items. MetadataMap CreateMetadataMap(base::MetadataRecorder::ItemArray 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* metadata_name_hashes); // The data provided for the next sample. base::MetadataRecorder::ItemArray 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 metadata_hashes_cache_; }; } // namespace metrics #endif // COMPONENTS_METRICS_CALL_STACK_PROFILE_METADATA_H_