#ifndef ABSL_PROFILING_INTERNAL_PROFILE_BUILDER_H_
#define ABSL_PROFILING_INTERNAL_PROFILE_BUILDER_H_
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/base/config.h"
#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/hash_container_defaults.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
struct ProfileProto {
static constexpr int kSampleType = 1;
static constexpr int kSample = 2;
static constexpr int kMapping = 3;
static constexpr int kLocation = 4;
static constexpr int kStringTable = 6;
static constexpr int kDropFrames = 7;
static constexpr int kComment = 13;
static constexpr int kDefaultSampleType = 14;
};
struct ValueTypeProto {
static constexpr int kType = 1;
static constexpr int kUnit = 2;
};
struct SampleProto {
static constexpr int kLocationId = 1;
static constexpr int kValue = 2;
static constexpr int kLabel = 3;
};
struct LabelProto {
static constexpr int kKey = 1;
static constexpr int kStr = 2;
static constexpr int kNum = 3;
static constexpr int kNumUnit = 4;
};
struct MappingProto {
static constexpr int kId = 1;
static constexpr int kMemoryStart = 2;
static constexpr int kMemoryLimit = 3;
static constexpr int kFileOffset = 4;
static constexpr int kFilename = 5;
static constexpr int kBuildId = 6;
};
struct LocationProto {
static constexpr int kId = 1;
static constexpr int kMappingId = 2;
static constexpr int kAddress = 3;
};
enum class StringId : size_t {};
enum class LocationId : size_t {};
enum class MappingId : size_t {};
class ProfileBuilder {
public:
struct Mapping {
uint64_t start;
uint64_t limit;
uint64_t offset;
std::string filename;
std::string build_id;
};
StringId InternString(absl::string_view str);
LocationId InternLocation(const void* address);
void AddSample(int64_t value, absl::Span<const void* const> stack,
absl::Span<const std::pair<StringId, int64_t>> labels);
void AddSampleType(StringId type, StringId unit);
void AddCurrentMappings();
MappingId AddMapping(uintptr_t memory_start, uintptr_t memory_limit,
uintptr_t file_offset, absl::string_view filename,
absl::string_view build_id);
std::string Emit() &&;
void set_drop_frames_id(StringId drop_frames_id);
void set_comment_id(StringId comment_id);
void set_default_sample_type_id(StringId default_sample_type_id);
private:
template <typename T>
struct HashtablezBarrier : std::allocator<T> {
HashtablezBarrier() = default;
template <typename U>
HashtablezBarrier(const HashtablezBarrier<U>&) {}
template <class U>
struct rebind {
using other = HashtablezBarrier<U>;
};
};
template <typename K, typename V>
using UnprofiledHashMap = absl::flat_hash_map<
K, V, DefaultHashContainerHash<K>, DefaultHashContainerEq<K>,
HashtablezBarrier<std::pair<const K, V>>>;
UnprofiledHashMap<std::string, StringId> string_table_{{"", StringId(0)}};
UnprofiledHashMap<uintptr_t, LocationId> location_table_;
absl::btree_map<uintptr_t, size_t> mapping_table_;
std::vector<Mapping> mappings_;
std::vector<std::string> sample_types_;
std::vector<std::string> samples_;
StringId drop_frames_id_{};
StringId comment_id_{};
StringId default_sample_type_id_{};
};
}
ABSL_NAMESPACE_END
}
#endif