blob: 4c6ea4960525f9ee0cfa1b0c4a316651fecaca01 [file] [log] [blame]
Mike Wittmanc1b619a2019-11-05 22:39:081// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_METRICS_CALL_STACK_PROFILE_METADATA_H_
6#define COMPONENTS_METRICS_CALL_STACK_PROFILE_METADATA_H_
7
8#include <map>
9#include <unordered_map>
10#include <utility>
11
Mike Wittmanc1b619a2019-11-05 22:39:0812#include "base/profiler/metadata_recorder.h"
Anton Bikineev1156b5f2021-05-15 22:35:3613#include "third_party/abseil-cpp/absl/types/optional.h"
Mike Wittmanc1b619a2019-11-05 22:39:0814#include "third_party/metrics_proto/sampled_profile.pb.h"
15
16namespace metrics {
17
18// Helper class for maintaining metadata state across samples and generating
19// metadata proto messages.
20class CallStackProfileMetadata {
21 public:
22 CallStackProfileMetadata();
23 ~CallStackProfileMetadata();
24
25 CallStackProfileMetadata(const CallStackProfileMetadata& other) = delete;
26 CallStackProfileMetadata& operator=(const CallStackProfileMetadata& other) =
27 delete;
28
29 // Records the metadata for the next sample.
30 void RecordMetadata(
Etienne Pierre-dorayfb883452020-04-28 17:50:2831 const base::MetadataRecorder::MetadataProvider& metadata_provider);
Mike Wittmanc1b619a2019-11-05 22:39:0832
33 // Creates MetadataItems for the currently active metadata, adding new name
34 // hashes to |metadata_name_hashes| if necessary. The same
35 // |metadata_name_hashes| must be passed to each invocation, and must not be
36 // modified outside this function.
37 google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem>
38 CreateSampleMetadata(
39 google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes);
40
Mike Wittmanb1b6c042020-02-12 22:54:2241 // Applies the |item| to the samples between |begin| and |end| in
42 // |stack_samples|. Overwrites any existing metadata item with the same key
43 // and value that are already applied to the samples.
44 void ApplyMetadata(
Etienne Pierre-doraycd2373fb2020-04-24 21:32:4245 const base::MetadataRecorder::Item& item,
Mike Wittmanb1b6c042020-02-12 22:54:2246 google::protobuf::RepeatedPtrField<
47 CallStackProfile::StackSample>::iterator begin,
48 google::protobuf::RepeatedPtrField<
49 CallStackProfile::StackSample>::iterator end,
50 google::protobuf::RepeatedPtrField<CallStackProfile::StackSample>*
51 stack_samples,
52 google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes);
53
Mike Wittmanc1b619a2019-11-05 22:39:0854 private:
55 // Comparison function for the metadata map.
56 struct MetadataKey;
57 struct MetadataKeyCompare {
58 bool operator()(const MetadataKey& a, const MetadataKey& b) const;
59 };
60
61 // Definitions for a map-based representation of sample metadata.
62 struct MetadataKey {
Anton Bikineev1156b5f2021-05-15 22:35:3663 MetadataKey(uint64_t name_hash, absl::optional<int64_t> key);
Mike Wittmanc1b619a2019-11-05 22:39:0864
65 MetadataKey(const MetadataKey& other);
66 MetadataKey& operator=(const MetadataKey& other);
67
68 // The name_hash and optional user-specified key uniquely identifies a
69 // metadata value. See base::MetadataRecorder for details.
70 uint64_t name_hash;
Anton Bikineev1156b5f2021-05-15 22:35:3671 absl::optional<int64_t> key;
Mike Wittmanc1b619a2019-11-05 22:39:0872 };
73 using MetadataMap = std::map<MetadataKey, int64_t, MetadataKeyCompare>;
74
Etienne Pierre-doraycd2373fb2020-04-24 21:32:4275 // Creates the metadata map from the array of items.
76 MetadataMap CreateMetadataMap(base::MetadataRecorder::ItemArray items,
Mike Wittmanc1b619a2019-11-05 22:39:0877 size_t item_count);
78
79 // Returns all metadata items with new values in the current sample.
80 MetadataMap GetNewOrModifiedMetadataItems(const MetadataMap& current_items,
81 const MetadataMap& previous_items);
82
83 // Returns all metadata items deleted since the previous sample.
84 MetadataMap GetDeletedMetadataItems(const MetadataMap& current_items,
85 const MetadataMap& previous_items);
86
87 // Appends the |name_hash| to |name_hashes| if it's not already
88 // present. Returns its index in |name_hashes|.
89 size_t MaybeAppendNameHash(
90 uint64_t name_hash,
91 google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes);
92
93 // The data provided for the next sample.
Etienne Pierre-doraycd2373fb2020-04-24 21:32:4294 base::MetadataRecorder::ItemArray metadata_items_;
Mike Wittmanc1b619a2019-11-05 22:39:0895 size_t metadata_item_count_ = 0;
96
97 // The data provided for the previous sample.
98 MetadataMap previous_items_;
99
100 // Maps metadata hash to index in |metadata_name_hash| array.
101 std::unordered_map<uint64_t, int> metadata_hashes_cache_;
102};
103
104} // namespace metrics
105
106#endif // COMPONENTS_METRICS_CALL_STACK_PROFILE_METADATA_H_