lin
2025-08-01 633231e833e21d5b8b1c00cb15aedb62b3b78e8f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * Copyright (c) 2016, Google Inc.
 * All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
 
#ifndef PERFTOOLS_PROFILES_PROTO_BUILDER_H_
#define PERFTOOLS_PROFILES_PROTO_BUILDER_H_
 
#include <stddef.h>
#include <algorithm>
#include <memory>
#include <string>
#include <tuple>
#include <unordered_map>
namespace perftools {
namespace profiles {
 
typedef int64_t int64;
typedef uint64_t uint64;
typedef std::string string;
 
}
}
#include "profile.pb.h"
 
namespace perftools {
namespace profiles {
 
// Provides mechanisms to facilitate the generation of profiles
// on a compressed protobuf:
// - Manages the creation of the string table.
// - Manages the creation of Functions for symbolized profiles.
// - Creates the association between locations and mappings.
// The caller should populate the profile with samples and their
// corresponding sample types, and any other optional fields.
class Builder {
 public:
  Builder();
 
  // Adds a string to the profile string table if not already present.
  // Returns a unique integer id for this string.
  int64 StringId(const char *str);
 
  // Adds a function with these attributes to the profile function
  // table, if not already present. Returns a unique integer id for
  // this function.
  uint64 FunctionId(const char *name, const char *system_name,
                    const char *file, int64 start_line);
 
  // Adds mappings for the currently running binary to the profile.
  void AddCurrentMappings();
 
  // Prepares the profile for encoding. Returns true on success.
  // If the profile has no locations, inserts location using the
  // location_ids from the samples as addresses.
  // Associates the locations to mappings by comparing the location
  // address into the mapping address range.
  bool Finalize();
 
  // Serializes and compresses the profile into a string, replacing
  // its contents. It calls Finalize() and returns whether the
  // encoding was successful.
  bool Emit(string *output);
 
  // Serializes and compresses a profile into a string, replacing its
  // contents. Returns false if there were errors on the serialization
  // or compression, and the output string will not contain valid data.
  static bool Marshal(const Profile &profile, string *output);
 
  // Serializes and compresses a profile into a file represented by a
  // file descriptor. Returns false if there were errors on the
  // serialization or compression.
  static bool MarshalToFile(const Profile &profile, int fd);
 
  // Serializes and compresses a profile into a file, creating a new
  // file or replacing its contents if it already exists.
  static bool MarshalToFile(const Profile &profile, const char *filename);
 
  // Determines if the profile is internally consistent (suitable for
  // serialization). Returns true if no errors were encountered.
  static bool CheckValid(const Profile &profile);
 
  // Extract the profile from the builder object. No further calls
  // should be made to the builder after this.
  std::unique_ptr<Profile> Consume() { return std::move(profile_); }
 
  // Returns the underlying profile, to populate any fields not
  // managed by the builder. The fields function and string_table
  // should be populated through Builder::StringId and
  // Builder::FunctionId.
  Profile *mutable_profile() { return profile_.get(); }
 
 private:
  // Holds the information about a function to facilitate deduplication.
  typedef std::tuple<int64, int64, int64, int64> Function;
  class FunctionHasher {
   public:
    size_t operator()(const Function &f) const {
      int64 hash = std::get<0>(f);
      hash = hash + ((hash << 8) ^ std::get<1>(f));
      hash = hash + ((hash << 8) ^ std::get<2>(f));
      hash = hash + ((hash << 8) ^ std::get<3>(f));
      return static_cast<size_t>(hash);
    }
  };
 
  // Hashes to deduplicate strings and functions.
  std::unordered_map<string, int64> strings_;
  std::unordered_map<Function, int64, FunctionHasher> functions_;
 
  // Actual profile being updated.
  std::unique_ptr<Profile> profile_;
};
 
}  // namespace profiles
}  // namespace perftools
 
#endif  // PERFTOOLS_PROFILES_PROTO_BUILDER_H_