Merge "trace_processor: migrate stack profile mapping to new db tables"
diff --git a/Android.bp b/Android.bp
index 7cd8b64..0d5f5e6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5711,7 +5711,6 @@
     "src/trace_processor/span_join_operator_table.cc",
     "src/trace_processor/sql_stats_table.cc",
     "src/trace_processor/stack_profile_frame_table.cc",
-    "src/trace_processor/stack_profile_mapping_table.cc",
     "src/trace_processor/stats_table.cc",
     "src/trace_processor/storage_columns.cc",
     "src/trace_processor/storage_schema.cc",
diff --git a/BUILD b/BUILD
index 2b10ea6..504f825 100644
--- a/BUILD
+++ b/BUILD
@@ -806,8 +806,6 @@
         "src/trace_processor/sql_stats_table.h",
         "src/trace_processor/stack_profile_frame_table.cc",
         "src/trace_processor/stack_profile_frame_table.h",
-        "src/trace_processor/stack_profile_mapping_table.cc",
-        "src/trace_processor/stack_profile_mapping_table.h",
         "src/trace_processor/stats_table.cc",
         "src/trace_processor/stats_table.h",
         "src/trace_processor/storage_columns.cc",
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index be12e90..f7b6b64 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -303,8 +303,6 @@
     "sql_stats_table.h",
     "stack_profile_frame_table.cc",
     "stack_profile_frame_table.h",
-    "stack_profile_mapping_table.cc",
-    "stack_profile_mapping_table.h",
     "stats_table.cc",
     "stats_table.h",
     "storage_columns.cc",
diff --git a/src/trace_processor/export_json.cc b/src/trace_processor/export_json.cc
index 507505a..07fe227 100644
--- a/src/trace_processor/export_json.cc
+++ b/src/trace_processor/export_json.cc
@@ -855,11 +855,10 @@
                       callsites.frame_id()[callsite_id] < frames.size());
       size_t frame_id = static_cast<size_t>(callsites.frame_id()[callsite_id]);
 
-      const TraceStorage::StackProfileMappings& mappings =
-          storage->stack_profile_mappings();
+      const auto& mappings = storage->stack_profile_mapping_table();
       PERFETTO_DCHECK(frames.mappings()[frame_id] >= 0 &&
-                      frames.mappings()[frame_id] < mappings.size());
-      size_t mapping_id = static_cast<size_t>(frames.mappings()[frame_id]);
+                      frames.mappings()[frame_id] < mappings.row_count());
+      uint32_t mapping_id = static_cast<uint32_t>(frames.mappings()[frame_id]);
 
       NullTermStringView symbol_name;
       uint32_t symbol_set_id = frames.symbol_set_ids()[frame_id];
@@ -875,8 +874,8 @@
                ? PrintUint64(static_cast<uint64_t>(frames.rel_pcs()[frame_id]))
                      .c_str()
                : symbol_name.c_str()),
-          GetNonNullString(storage, mappings.names()[mapping_id]),
-          GetNonNullString(storage, mappings.build_ids()[mapping_id]));
+          GetNonNullString(storage, mappings.name()[mapping_id]),
+          GetNonNullString(storage, mappings.build_id()[mapping_id]));
 
       callstack.emplace_back(frame_entry);
 
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index f087228..17bf554 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -1136,13 +1136,15 @@
   UniqueTid utid = storage->AddEmptyThread(kThreadID);
   storage->GetMutableThread(utid)->upid = upid;
 
-  uint32_t module_row_id_1 = storage->mutable_stack_profile_mappings()->Insert(
-      {storage->InternString("foo_module_id"), 0, 0, 0, 0, 0,
-       storage->InternString("foo_module_name")});
+  uint32_t module_row_id_1 =
+      storage->mutable_stack_profile_mapping_table()->Insert(
+          {storage->InternString("foo_module_id"), 0, 0, 0, 0, 0,
+           storage->InternString("foo_module_name")});
 
-  uint32_t module_row_id_2 = storage->mutable_stack_profile_mappings()->Insert(
-      {storage->InternString("bar_module_id"), 0, 0, 0, 0, 0,
-       storage->InternString("bar_module_name")});
+  uint32_t module_row_id_2 =
+      storage->mutable_stack_profile_mapping_table()->Insert(
+          {storage->InternString("bar_module_id"), 0, 0, 0, 0, 0,
+           storage->InternString("bar_module_name")});
 
   // TODO(140860736): Once we support null values for
   // stack_profile_frame.symbol_set_id remove this hack
diff --git a/src/trace_processor/heap_profile_tracker_unittest.cc b/src/trace_processor/heap_profile_tracker_unittest.cc
index f7c3734..fc52001 100644
--- a/src/trace_processor/heap_profile_tracker_unittest.cc
+++ b/src/trace_processor/heap_profile_tracker_unittest.cc
@@ -121,20 +121,20 @@
   context.heap_profile_tracker->FinalizeProfile(
       kDefaultSequence, stack_profile_tracker.get(), nullptr);
 
-  EXPECT_THAT(context.storage->stack_profile_mappings().build_ids(),
-              ElementsAre(context.storage->InternString({kBuildIDHexName})));
-  EXPECT_THAT(context.storage->stack_profile_mappings().exact_offsets(),
-              ElementsAre(kMappingExactOffset));
-  EXPECT_THAT(context.storage->stack_profile_mappings().start_offsets(),
-              ElementsAre(kMappingStartOffset));
-  EXPECT_THAT(context.storage->stack_profile_mappings().starts(),
-              ElementsAre(kMappingStart));
-  EXPECT_THAT(context.storage->stack_profile_mappings().ends(),
-              ElementsAre(kMappingEnd));
-  EXPECT_THAT(context.storage->stack_profile_mappings().load_biases(),
-              ElementsAre(kMappingLoadBias));
-  EXPECT_THAT(context.storage->stack_profile_mappings().names(),
-              ElementsAre(fully_qualified_mapping_name));
+  EXPECT_THAT(context.storage->stack_profile_mapping_table().build_id()[0],
+              context.storage->InternString({kBuildIDHexName}));
+  EXPECT_THAT(context.storage->stack_profile_mapping_table().exact_offset()[0],
+              kMappingExactOffset);
+  EXPECT_THAT(context.storage->stack_profile_mapping_table().start_offset()[0],
+              kMappingStartOffset);
+  EXPECT_THAT(context.storage->stack_profile_mapping_table().start()[0],
+              kMappingStart);
+  EXPECT_THAT(context.storage->stack_profile_mapping_table().end()[0],
+              kMappingEnd);
+  EXPECT_THAT(context.storage->stack_profile_mapping_table().load_bias()[0],
+              kMappingLoadBias);
+  EXPECT_THAT(context.storage->stack_profile_mapping_table().name()[0],
+              fully_qualified_mapping_name);
 }
 
 // Insert the same mapping from two different packets, with different strings
@@ -222,8 +222,8 @@
   hpt->CommitAllocations(kDefaultSequence, spt.get(), nullptr);
   auto foo_bar_id = context.storage->string_pool().GetId("/foo/bar");
   ASSERT_NE(foo_bar_id, base::nullopt);
-  EXPECT_THAT(context.storage->stack_profile_mappings().names(),
-              ElementsAre(*foo_bar_id));
+  EXPECT_THAT(context.storage->stack_profile_mapping_table().name()[0],
+              *foo_bar_id);
 }
 
 // Insert multiple mappings, frames and callstacks and check result.
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker.cc b/src/trace_processor/importers/proto/heap_graph_tracker.cc
index 7e8ca92..94f10f9 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker.cc
@@ -187,10 +187,11 @@
     }
   }
 
-  TraceStorage::StackProfileMappings::Row mapping_row{};
-  mapping_row.name_id = context_->storage->InternString("JAVA");
+  tables::StackProfileMappingTable::Row mapping_row{};
+  mapping_row.name = context_->storage->InternString("JAVA");
   uint32_t mapping_id =
-      context_->storage->mutable_stack_profile_mappings()->Insert(mapping_row);
+      context_->storage->mutable_stack_profile_mapping_table()->Insert(
+          mapping_row);
 
   auto paths = sequence_state.walker.FindPathsFromRoot();
   for (const auto& p : paths.children)
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index 0a61e0c..6c3c92a 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -616,10 +616,9 @@
   protos::pbzero::ModuleSymbols::Decoder module_symbols(blob.data, blob.size);
   std::string hex_build_id = base::ToHex(module_symbols.build_id().data,
                                          module_symbols.build_id().size);
-  auto mapping_rows =
-      context_->storage->stack_profile_mappings().FindMappingRow(
-          context_->storage->InternString(module_symbols.path()),
-          context_->storage->InternString(base::StringView(hex_build_id)));
+  auto mapping_rows = context_->storage->FindMappingRow(
+      context_->storage->InternString(module_symbols.path()),
+      context_->storage->InternString(base::StringView(hex_build_id)));
   if (mapping_rows.empty()) {
     context_->storage->IncrementStats(stats::stackprofile_invalid_mapping_id);
     return;
diff --git a/src/trace_processor/stack_profile_mapping_table.cc b/src/trace_processor/stack_profile_mapping_table.cc
deleted file mode 100644
index 52a9038..0000000
--- a/src/trace_processor/stack_profile_mapping_table.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/stack_profile_mapping_table.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-StackProfileMappingTable::StackProfileMappingTable(sqlite3*,
-                                                   const TraceStorage* storage)
-    : storage_(storage) {}
-
-void StackProfileMappingTable::RegisterTable(sqlite3* db,
-                                             const TraceStorage* storage) {
-  SqliteTable::Register<StackProfileMappingTable>(db, storage,
-                                                  "stack_profile_mapping");
-}
-
-StorageSchema StackProfileMappingTable::CreateStorageSchema() {
-  const auto& mappings = storage_->stack_profile_mappings();
-  return StorageSchema::Builder()
-      .AddGenericNumericColumn("id", RowAccessor())
-      .AddStringColumn("build_id", &mappings.build_ids(),
-                       &storage_->string_pool())
-      .AddNumericColumn("exact_offset", &mappings.exact_offsets())
-      .AddNumericColumn("start_offset", &mappings.start_offsets())
-      .AddNumericColumn("start", &mappings.starts())
-      .AddNumericColumn("end", &mappings.ends())
-      .AddNumericColumn("load_bias", &mappings.load_biases())
-      .AddStringColumn("name", &mappings.names(), &storage_->string_pool())
-      .Build({"id"});
-}
-
-uint32_t StackProfileMappingTable::RowCount() {
-  return storage_->stack_profile_mappings().size();
-}
-
-int StackProfileMappingTable::BestIndex(const QueryConstraints& qc,
-                                        BestIndexInfo* info) {
-  info->sqlite_omit_order_by = true;
-  info->estimated_cost = HasEqConstraint(qc, "id") ? 1 : RowCount();
-  return SQLITE_OK;
-}
-
-}  // namespace trace_processor
-}  // namespace perfetto
diff --git a/src/trace_processor/stack_profile_mapping_table.h b/src/trace_processor/stack_profile_mapping_table.h
deleted file mode 100644
index c627a1e..0000000
--- a/src/trace_processor/stack_profile_mapping_table.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_STACK_PROFILE_MAPPING_TABLE_H_
-#define SRC_TRACE_PROCESSOR_STACK_PROFILE_MAPPING_TABLE_H_
-
-#include "src/trace_processor/storage_table.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-class StackProfileMappingTable : public StorageTable {
- public:
-  static void RegisterTable(sqlite3* db, const TraceStorage* storage);
-
-  StackProfileMappingTable(sqlite3*, const TraceStorage*);
-
-  // StorageTable implementation.
-  StorageSchema CreateStorageSchema() override;
-  uint32_t RowCount() override;
-  int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
-
- private:
-  const TraceStorage* const storage_;
-};
-
-}  // namespace trace_processor
-}  // namespace perfetto
-
-#endif  // SRC_TRACE_PROCESSOR_STACK_PROFILE_MAPPING_TABLE_H_
diff --git a/src/trace_processor/stack_profile_tracker.cc b/src/trace_processor/stack_profile_tracker.cc
index 25815ea..0629541 100644
--- a/src/trace_processor/stack_profile_tracker.cc
+++ b/src/trace_processor/stack_profile_tracker.cc
@@ -73,7 +73,7 @@
     build_id = context_->storage->InternString(base::StringView(hex_build_id));
   }
 
-  TraceStorage::StackProfileMappings::Row row{
+  tables::StackProfileMappingTable::Row row{
       build_id,
       static_cast<int64_t>(mapping.exact_offset),
       static_cast<int64_t>(mapping.start_offset),
@@ -82,26 +82,26 @@
       static_cast<int64_t>(mapping.load_bias),
       context_->storage->InternString(base::StringView(path))};
 
-  TraceStorage::StackProfileMappings* mappings =
-      context_->storage->mutable_stack_profile_mappings();
+  tables::StackProfileMappingTable* mappings =
+      context_->storage->mutable_stack_profile_mapping_table();
   int64_t cur_row = -1;
   auto it = mapping_idx_.find(row);
   if (it != mapping_idx_.end()) {
     cur_row = it->second;
   } else {
     std::vector<int64_t> db_mappings =
-        mappings->FindMappingRow(row.name_id, row.build_id);
+        context_->storage->FindMappingRow(row.name, row.build_id);
     for (const int64_t preexisting_mapping : db_mappings) {
       PERFETTO_DCHECK(preexisting_mapping >= 0);
-      size_t preexisting_row_id = static_cast<size_t>(preexisting_mapping);
-      TraceStorage::StackProfileMappings::Row preexisting_row{
-          mappings->build_ids()[preexisting_row_id],
-          mappings->exact_offsets()[preexisting_row_id],
-          mappings->start_offsets()[preexisting_row_id],
-          mappings->starts()[preexisting_row_id],
-          mappings->ends()[preexisting_row_id],
-          mappings->load_biases()[preexisting_row_id],
-          mappings->names()[preexisting_row_id]};
+      uint32_t preexisting_row_id = static_cast<uint32_t>(preexisting_mapping);
+      tables::StackProfileMappingTable::Row preexisting_row{
+          mappings->build_id()[preexisting_row_id],
+          mappings->exact_offset()[preexisting_row_id],
+          mappings->start_offset()[preexisting_row_id],
+          mappings->start()[preexisting_row_id],
+          mappings->end()[preexisting_row_id],
+          mappings->load_bias()[preexisting_row_id],
+          mappings->name()[preexisting_row_id]};
 
       if (row == preexisting_row) {
         cur_row = preexisting_mapping;
@@ -109,7 +109,9 @@
     }
     if (cur_row == -1) {
       cur_row =
-          context_->storage->mutable_stack_profile_mappings()->Insert(row);
+          context_->storage->mutable_stack_profile_mapping_table()->Insert(row);
+      context_->storage->InsertMappingRow(row.name, row.build_id,
+                                          static_cast<uint32_t>(cur_row));
     }
     mapping_idx_.emplace(row, cur_row);
   }
diff --git a/src/trace_processor/stack_profile_tracker.h b/src/trace_processor/stack_profile_tracker.h
index 9496929..99d99de 100644
--- a/src/trace_processor/stack_profile_tracker.h
+++ b/src/trace_processor/stack_profile_tracker.h
@@ -168,7 +168,7 @@
 
   // TODO(oysteine): Share these indices between the StackProfileTrackers,
   // since they're not sequence-specific.
-  std::unordered_map<TraceStorage::StackProfileMappings::Row, int64_t>
+  std::unordered_map<tables::StackProfileMappingTable::Row, int64_t>
       mapping_idx_;
   std::unordered_map<TraceStorage::StackProfileFrames::Row, int64_t> frame_idx_;
   std::unordered_map<tables::StackProfileCallsiteTable::Row, int64_t>
diff --git a/src/trace_processor/tables/profiler_tables.h b/src/trace_processor/tables/profiler_tables.h
index c5a7342..e49e8da 100644
--- a/src/trace_processor/tables/profiler_tables.h
+++ b/src/trace_processor/tables/profiler_tables.h
@@ -51,6 +51,19 @@
 
 PERFETTO_TP_TABLE(PERFETTO_TP_SYMBOL_DEF);
 
+#define PERFETTO_TP_STACK_PROFILE_MAPPING_DEF(NAME, PARENT, C) \
+  NAME(StackProfileMappingTable, "stack_profile_mapping")      \
+  PERFETTO_TP_ROOT_TABLE(PARENT, C)                            \
+  C(StringPool::Id, build_id)                                  \
+  C(int64_t, exact_offset)                                     \
+  C(int64_t, start_offset)                                     \
+  C(int64_t, start)                                            \
+  C(int64_t, end)                                              \
+  C(int64_t, load_bias)                                        \
+  C(StringPool::Id, name)
+
+PERFETTO_TP_TABLE(PERFETTO_TP_STACK_PROFILE_MAPPING_DEF);
+
 #define PERFETTO_TP_HEAP_PROFILE_ALLOCATION_DEF(NAME, PARENT, C) \
   NAME(HeapProfileAllocationTable, "heap_profile_allocation")    \
   PERFETTO_TP_ROOT_TABLE(PARENT, C)                              \
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 12a5a84..933df04 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -38,7 +38,6 @@
 #include "src/trace_processor/sqlite/sqlite3_str_split.h"
 #include "src/trace_processor/sqlite/sqlite_table.h"
 #include "src/trace_processor/stack_profile_frame_table.h"
-#include "src/trace_processor/stack_profile_mapping_table.h"
 #include "src/trace_processor/stats_table.h"
 #include "src/trace_processor/thread_table.h"
 #include "src/trace_processor/window_operator_table.h"
@@ -374,7 +373,6 @@
   AndroidLogsTable::RegisterTable(*db_, context_.storage.get());
   RawTable::RegisterTable(*db_, context_.storage.get());
   StackProfileFrameTable::RegisterTable(*db_, context_.storage.get());
-  StackProfileMappingTable::RegisterTable(*db_, context_.storage.get());
   MetadataTable::RegisterTable(*db_, context_.storage.get());
 
   // New style db-backed tables.
@@ -432,6 +430,9 @@
   DbSqliteTable::RegisterTable(
       *db_, &storage->stack_profile_callsite_table(),
       storage->stack_profile_callsite_table().table_name());
+  DbSqliteTable::RegisterTable(
+      *db_, &storage->stack_profile_mapping_table(),
+      storage->stack_profile_mapping_table().table_name());
 
   DbSqliteTable::RegisterTable(
       *db_, &storage->vulkan_memory_allocations_table(),
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index 0e9e827..081cffd 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -707,72 +707,6 @@
         index_;
   };
 
-  class StackProfileMappings {
-   public:
-    struct Row {
-      StringId build_id;
-      int64_t exact_offset;
-      int64_t start_offset;
-      int64_t start;
-      int64_t end;
-      int64_t load_bias;
-      StringId name_id;
-
-      bool operator==(const Row& other) const {
-        return std::tie(build_id, exact_offset, start_offset, start, end,
-                        load_bias, name_id) ==
-               std::tie(other.build_id, other.exact_offset, other.start_offset,
-                        other.start, other.end, other.load_bias, other.name_id);
-      }
-    };
-
-    uint32_t size() const { return static_cast<uint32_t>(names_.size()); }
-
-    uint32_t Insert(const Row& row) {
-      build_ids_.emplace_back(row.build_id);
-      exact_offsets_.emplace_back(row.exact_offset);
-      start_offsets_.emplace_back(row.start_offset);
-      starts_.emplace_back(row.start);
-      ends_.emplace_back(row.end);
-      load_biases_.emplace_back(row.load_bias);
-      names_.emplace_back(row.name_id);
-
-      size_t row_number = build_ids_.size() - 1;
-      index_[std::make_pair(row.name_id, row.build_id)].emplace_back(
-          row_number);
-      return static_cast<uint32_t>(row_number);
-    }
-
-    std::vector<int64_t> FindMappingRow(StringId name,
-                                        StringId build_id) const {
-      auto it = index_.find(std::make_pair(name, build_id));
-      if (it == index_.end())
-        return {};
-      return it->second;
-    }
-
-    const std::deque<StringId>& build_ids() const { return build_ids_; }
-    const std::deque<int64_t>& exact_offsets() const { return exact_offsets_; }
-    const std::deque<int64_t>& start_offsets() const { return start_offsets_; }
-    const std::deque<int64_t>& starts() const { return starts_; }
-    const std::deque<int64_t>& ends() const { return ends_; }
-    const std::deque<int64_t>& load_biases() const { return load_biases_; }
-    const std::deque<StringId>& names() const { return names_; }
-
-   private:
-    std::deque<StringId> build_ids_;
-    std::deque<int64_t> exact_offsets_;
-    std::deque<int64_t> start_offsets_;
-    std::deque<int64_t> starts_;
-    std::deque<int64_t> ends_;
-    std::deque<int64_t> load_biases_;
-    std::deque<StringId> names_;
-
-    std::map<std::pair<StringId /* name */, StringId /* build id */>,
-             std::vector<int64_t>>
-        index_;
-  };
-
   UniqueTid AddEmptyThread(uint32_t tid) {
     unique_threads_.emplace_back(tid);
     return static_cast<UniqueTid>(unique_threads_.size() - 1);
@@ -1024,11 +958,11 @@
   const RawEvents& raw_events() const { return raw_events_; }
   RawEvents* mutable_raw_events() { return &raw_events_; }
 
-  const StackProfileMappings& stack_profile_mappings() const {
-    return stack_profile_mappings_;
+  const tables::StackProfileMappingTable& stack_profile_mapping_table() const {
+    return stack_profile_mapping_table_;
   }
-  StackProfileMappings* mutable_stack_profile_mappings() {
-    return &stack_profile_mappings_;
+  tables::StackProfileMappingTable* mutable_stack_profile_mapping_table() {
+    return &stack_profile_mapping_table_;
   }
 
   const StackProfileFrames& stack_profile_frames() const {
@@ -1113,6 +1047,20 @@
   // Returns (0, 0) if the trace is empty.
   std::pair<int64_t, int64_t> GetTraceTimestampBoundsNs() const;
 
+  // TODO(lalitm): remove this when we have a better home.
+  std::vector<int64_t> FindMappingRow(StringId name, StringId build_id) const {
+    auto it = stack_profile_mapping_index_.find(std::make_pair(name, build_id));
+    if (it == stack_profile_mapping_index_.end())
+      return {};
+    return it->second;
+  }
+
+  // TODO(lalitm): remove this when we have a better home.
+  void InsertMappingRow(StringId name, StringId build_id, uint32_t row) {
+    auto pair = std::make_pair(name, build_id);
+    stack_profile_mapping_index_[pair].emplace_back(row);
+  }
+
  private:
   static constexpr uint8_t kRowIdTableShift = 32;
 
@@ -1124,6 +1072,10 @@
   TraceStorage(TraceStorage&&) = delete;
   TraceStorage& operator=(TraceStorage&&) = delete;
 
+  // TODO(lalitm): remove this when we find a better home for this.
+  using MappingKey = std::pair<StringId /* name */, StringId /* build id */>;
+  std::map<MappingKey, std::vector<int64_t>> stack_profile_mapping_index_;
+
   // One entry for each unique string in the trace.
   StringPool string_pool_;
 
@@ -1205,7 +1157,8 @@
   RawEvents raw_events_;
   AndroidLogs android_log_;
 
-  StackProfileMappings stack_profile_mappings_;
+  tables::StackProfileMappingTable stack_profile_mapping_table_{&string_pool_,
+                                                                nullptr};
   StackProfileFrames stack_profile_frames_;
   tables::StackProfileCallsiteTable stack_profile_callsite_table_{&string_pool_,
                                                                   nullptr};
@@ -1257,9 +1210,9 @@
 
 template <>
 struct hash<
-    ::perfetto::trace_processor::TraceStorage::StackProfileMappings::Row> {
+    ::perfetto::trace_processor::tables::StackProfileMappingTable::Row> {
   using argument_type =
-      ::perfetto::trace_processor::TraceStorage::StackProfileMappings::Row;
+      ::perfetto::trace_processor::tables::StackProfileMappingTable::Row;
   using result_type = size_t;
 
   result_type operator()(const argument_type& r) const {
@@ -1268,7 +1221,7 @@
            std::hash<int64_t>{}(r.start_offset) ^
            std::hash<int64_t>{}(r.start) ^ std::hash<int64_t>{}(r.end) ^
            std::hash<int64_t>{}(r.load_bias) ^
-           std::hash<::perfetto::trace_processor::StringId>{}(r.name_id);
+           std::hash<::perfetto::trace_processor::StringId>{}(r.name);
   }
 };