trace_processor: remove tableid and refactor argstracker to use ids

The last place TableId was being used was in args tracker. Now that we
have proper, strongly typed ids we can use this to disambiguate tables
so do not need to use TableId anymore.

This CL changes ArgsTracker to stop using TableId and instead create
BoundInserters based on the type of the passed in Id. We can thus also
remove the IndexOf calls throughout the codebase and use BoundInserter
for everything with minimal boilerplate allowing us to omit flat_key in
a lot of places.

Context: go/perfetto-tp-refactor
Bug: 135177627
Change-Id: I8fec9e3186fdb87b28ed33d06902a363c8873e60
diff --git a/src/trace_processor/args_tracker.cc b/src/trace_processor/args_tracker.cc
index 703f8ee..a0114ce 100644
--- a/src/trace_processor/args_tracker.cc
+++ b/src/trace_processor/args_tracker.cc
@@ -27,7 +27,7 @@
   Flush();
 }
 
-void ArgsTracker::AddArg(TableId table,
+void ArgsTracker::AddArg(Column* arg_set_id,
                          uint32_t row,
                          StringId flat_key,
                          StringId key,
@@ -35,7 +35,7 @@
   args_.emplace_back();
 
   auto* rid_arg = &args_.back();
-  rid_arg->table = table;
+  rid_arg->column = arg_set_id;
   rid_arg->row = row;
   rid_arg->flat_key = flat_key;
   rid_arg->key = key;
@@ -51,63 +51,42 @@
   // We sort here because a single packet may add multiple args with different
   // rowids.
   auto comparator = [](const Arg& f, const Arg& s) {
-    return f.table < s.table && f.row < s.row;
+    // We only care that all args for a specific arg set appear in a contiguous
+    // block, but not about the relative order of one block to another. The
+    // simplest way to achieve that is to sort by table column pointer & row,
+    // which identify the arg set.
+    return f.column < s.column && f.row < s.row;
   };
   std::stable_sort(args_.begin(), args_.end(), comparator);
 
-  auto* storage = context_->storage.get();
   for (uint32_t i = 0; i < args_.size();) {
     const auto& arg = args_[i];
-    auto table_id = arg.table;
+    Column* column = arg.column;
     auto row = arg.row;
 
     uint32_t next_rid_idx = i + 1;
     while (next_rid_idx < args_.size() &&
-           table_id == args_[next_rid_idx].table &&
+           column == args_[next_rid_idx].column &&
            row == args_[next_rid_idx].row) {
       next_rid_idx++;
     }
 
     ArgSetId set_id =
         context_->global_args_tracker->AddArgSet(args_, i, next_rid_idx);
-    switch (table_id) {
-      case TableId::kRawEvents:
-        storage->mutable_raw_table()->mutable_arg_set_id()->Set(row, set_id);
-        break;
-      case TableId::kCounterValues:
-        storage->mutable_counter_table()->mutable_arg_set_id()->Set(row,
-                                                                    set_id);
-        break;
-      case TableId::kInstants:
-        storage->mutable_instant_table()->mutable_arg_set_id()->Set(row,
-                                                                    set_id);
-        break;
-      case TableId::kNestableSlices:
-        storage->mutable_slice_table()->mutable_arg_set_id()->Set(row, set_id);
-        break;
-      // Special case: overwrites the metadata table row.
-      case TableId::kMetadataTable:
-        storage->mutable_metadata_table()->mutable_int_value()->Set(row,
-                                                                    set_id);
-        break;
-      case TableId::kTrack:
-        storage->mutable_track_table()->mutable_source_arg_set_id()->Set(
-            row, set_id);
-        break;
-      case TableId::kVulkanMemoryAllocation:
-        storage->mutable_vulkan_memory_allocations_table()
-            ->mutable_arg_set_id()
-            ->Set(row, set_id);
-        break;
-      case TableId::kInvalid:
-      case TableId::kSched:
-        PERFETTO_FATAL("Unsupported table to insert args into");
-    }
+    column->Set(row, SqlValue::Long(set_id));
+
     i = next_rid_idx;
   }
   args_.clear();
 }
 
+ArgsTracker::BoundInserter::BoundInserter(ArgsTracker* args_tracker,
+                                          Column* arg_set_id_column,
+                                          uint32_t row)
+    : args_tracker_(args_tracker),
+      arg_set_id_column_(arg_set_id_column),
+      row_(row) {}
+
 ArgsTracker::BoundInserter::~BoundInserter() {}
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/args_tracker.h b/src/trace_processor/args_tracker.h
index 2c6c8c4..9acccfb 100644
--- a/src/trace_processor/args_tracker.h
+++ b/src/trace_processor/args_tracker.h
@@ -34,40 +34,85 @@
   // args should be associated with.
   class BoundInserter {
    public:
-    BoundInserter(ArgsTracker* args_tracker, TableId table, uint32_t row)
-        : args_tracker_(args_tracker), table_(table), row_(row) {}
     virtual ~BoundInserter();
 
     // Adds an arg with the same key and flat_key.
-    void AddArg(StringId key, Variadic v) { AddArg(key, key, v); }
-
-    // Virtual for testing.
-    virtual void AddArg(StringId flat_key, StringId key, Variadic v) {
-      args_tracker_->AddArg(table_, row_, flat_key, key, v);
+    BoundInserter& AddArg(StringId key, Variadic v) {
+      return AddArg(key, key, v);
     }
 
+    // Virtual for testing.
+    virtual BoundInserter& AddArg(StringId flat_key, StringId key, Variadic v) {
+      args_tracker_->AddArg(arg_set_id_column_, row_, flat_key, key, v);
+      return *this;
+    }
+
+   protected:
+    BoundInserter(ArgsTracker* args_tracker,
+                  Column* arg_set_id_column,
+                  uint32_t row);
+
    private:
+    friend class ArgsTracker;
+
     ArgsTracker* args_tracker_ = nullptr;
-    TableId table_ = TableId::kInvalid;
+    Column* arg_set_id_column_ = nullptr;
     uint32_t row_ = 0;
   };
 
   explicit ArgsTracker(TraceProcessorContext*);
   virtual ~ArgsTracker();
 
-  // Adds a arg for this row id with the given key and value.
-  // Virtual for testing.
-  virtual void AddArg(TableId table,
-                      uint32_t row,
-                      StringId flat_key,
-                      StringId key,
-                      Variadic);
+  BoundInserter AddArgsTo(RawId id) {
+    return AddArgsTo(context_->storage->mutable_raw_table(), id);
+  }
+
+  BoundInserter AddArgsTo(CounterId id) {
+    return AddArgsTo(context_->storage->mutable_counter_table(), id);
+  }
+
+  BoundInserter AddArgsTo(InstantId id) {
+    return AddArgsTo(context_->storage->mutable_instant_table(), id);
+  }
+
+  BoundInserter AddArgsTo(SliceId id) {
+    return AddArgsTo(context_->storage->mutable_slice_table(), id);
+  }
+
+  BoundInserter AddArgsTo(MetadataId id) {
+    auto* table = context_->storage->mutable_metadata_table();
+    uint32_t row = *table->id().IndexOf(id);
+    return BoundInserter(this, table->mutable_int_value(), row);
+  }
+
+  BoundInserter AddArgsTo(TrackId id) {
+    auto* table = context_->storage->mutable_track_table();
+    uint32_t row = *table->id().IndexOf(id);
+    return BoundInserter(this, table->mutable_source_arg_set_id(), row);
+  }
+
+  BoundInserter AddArgsTo(VulkanAllocId id) {
+    return AddArgsTo(
+        context_->storage->mutable_vulkan_memory_allocations_table(), id);
+  }
 
   // Commits the added args to storage.
   // Virtual for testing.
   virtual void Flush();
 
  private:
+  template <typename Table>
+  BoundInserter AddArgsTo(Table* table, typename Table::Id id) {
+    uint32_t row = *table->id().IndexOf(id);
+    return BoundInserter(this, table->mutable_arg_set_id(), row);
+  }
+
+  void AddArg(Column* arg_set_id,
+              uint32_t row,
+              StringId flat_key,
+              StringId key,
+              Variadic);
+
   std::vector<GlobalArgsTracker::Arg> args_;
   TraceProcessorContext* const context_;
 };
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index a86d023..17ebe2d 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -147,6 +147,39 @@
     PERFETTO_FATAL("For GCC");
   }
 
+  // Sets the value of the column at the given |row|.
+  void Set(uint32_t row, SqlValue value) {
+    PERFETTO_CHECK(value.type == type());
+    switch (type_) {
+      case ColumnType::kInt32: {
+        mutable_sparse_vector<int32_t>()->Set(
+            row, static_cast<int32_t>(value.long_value));
+        break;
+      }
+      case ColumnType::kUint32: {
+        mutable_sparse_vector<uint32_t>()->Set(
+            row, static_cast<uint32_t>(value.long_value));
+        break;
+      }
+      case ColumnType::kInt64: {
+        mutable_sparse_vector<int64_t>()->Set(
+            row, static_cast<int64_t>(value.long_value));
+        break;
+      }
+      case ColumnType::kDouble: {
+        mutable_sparse_vector<double>()->Set(row, value.double_value);
+        break;
+      }
+      case ColumnType::kString: {
+        PERFETTO_FATAL(
+            "Setting a generic value on a string column is not implemented");
+      }
+      case ColumnType::kId: {
+        PERFETTO_FATAL("Cannot set value on a id column");
+      }
+    }
+  }
+
   // Sorts |idx| in ascending or descending order (determined by |desc|) based
   // on the contents of this column.
   void StableSort(bool desc, std::vector<uint32_t>* idx) const;
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index bee6e2a..c7cf7ab 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -375,15 +375,14 @@
 
   RawId id = storage->mutable_raw_table()->Insert(
       {0, storage->InternString("chrome_event.metadata"), 0, 0});
-  uint32_t row = *storage->raw_table().id().IndexOf(id);
 
   StringId name1_id = storage->InternString(base::StringView(kName1));
   StringId name2_id = storage->InternString(base::StringView(kName2));
   StringId value1_id = storage->InternString(base::StringView(kValue1));
-  context_.args_tracker->AddArg(TableId::kRawEvents, row, name1_id, name1_id,
-                                Variadic::String(value1_id));
-  context_.args_tracker->AddArg(TableId::kRawEvents, row, name2_id, name2_id,
-                                Variadic::Integer(kValue2));
+
+  context_.args_tracker->AddArgsTo(id)
+      .AddArg(name1_id, Variadic::String(value1_id))
+      .AddArg(name2_id, Variadic::Integer(kValue2));
   context_.args_tracker->Flush();
 
   base::TempFile temp_file = base::TempFile::Create();
@@ -456,12 +455,10 @@
   StringId name_id = storage->InternString(base::StringView(kName));
   SliceId id = storage->mutable_slice_table()->Insert(
       {0, 0, track.value, cat_id, name_id, 0, 0, 0});
-  uint32_t row = *storage->slice_table().id().IndexOf(id);
+  auto inserter = context_.args_tracker->AddArgsTo(id);
 
   auto add_arg = [&](const char* key, Variadic value) {
-    StringId key_id = storage->InternString(key);
-    context_.args_tracker->AddArg(TableId::kNestableSlices, row, key_id, key_id,
-                                  value);
+    inserter.AddArg(storage->InternString(key), value);
   };
 
   add_arg("legacy_event.bind_id", Variadic::UnsignedInteger(kBindId));
@@ -1047,12 +1044,11 @@
   RawId id = storage->mutable_raw_table()->Insert(
       {kTimestamp, storage->InternString("track_event.legacy_event"), /*cpu=*/0,
        utid});
-  uint32_t row = *storage->raw_table().id().IndexOf(id);
+  auto inserter = context_.args_tracker->AddArgsTo(id);
 
   auto add_arg = [&](const char* key, Variadic value) {
     StringId key_id = storage->InternString(key);
-    context_.args_tracker->AddArg(TableId::kRawEvents, row, key_id, key_id,
-                                  value);
+    inserter.AddArg(key_id, value);
   };
 
   StringId cat_id = storage->InternString(base::StringView(kCategory));
@@ -1123,26 +1119,23 @@
 
   RawId id = storage->mutable_raw_table()->Insert(
       {0, storage->InternString("chrome_event.legacy_system_trace"), 0, 0});
-  uint32_t row = *storage->raw_table().id().IndexOf(id);
+  auto inserter = context_.args_tracker->AddArgsTo(id);
 
   StringId data_id = storage->InternString("data");
   StringId ftrace_data_id = storage->InternString(kLegacyFtraceData);
-  context_.args_tracker->AddArg(TableId::kRawEvents, row, data_id, data_id,
-                                Variadic::String(ftrace_data_id));
+  inserter.AddArg(data_id, Variadic::String(ftrace_data_id));
 
   id = storage->mutable_raw_table()->Insert(
       {0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0});
-  row = *storage->raw_table().id().IndexOf(id);
+  inserter = context_.args_tracker->AddArgsTo(id);
   StringId json_data1_id = storage->InternString(kLegacyJsonData1);
-  context_.args_tracker->AddArg(TableId::kRawEvents, row, data_id, data_id,
-                                Variadic::String(json_data1_id));
+  inserter.AddArg(data_id, Variadic::String(json_data1_id));
 
   id = storage->mutable_raw_table()->Insert(
       {0, storage->InternString("chrome_event.legacy_user_trace"), 0, 0});
-  row = *storage->raw_table().id().IndexOf(id);
+  inserter = context_.args_tracker->AddArgsTo(id);
   StringId json_data2_id = storage->InternString(kLegacyJsonData2);
-  context_.args_tracker->AddArg(TableId::kRawEvents, row, data_id, data_id,
-                                Variadic::String(json_data2_id));
+  inserter.AddArg(data_id, Variadic::String(json_data2_id));
 
   context_.args_tracker->Flush();
 
@@ -1249,18 +1242,16 @@
   StringId arg2_id = context_.storage->InternString(base::StringView("arg2"));
   StringId val_id = context_.storage->InternString(base::StringView("val"));
 
-  std::array<uint32_t, 3> slice_rows;
+  std::vector<ArgsTracker::BoundInserter> slice_inserters;
   for (size_t i = 0; i < name_ids.size(); i++) {
     auto slice_id = context_.storage->mutable_slice_table()->Insert(
         {0, 0, track.value, cat_id, name_ids[i], 0, 0, 0});
-    slice_rows[i] = *context_.storage->slice_table().id().IndexOf(slice_id);
+    slice_inserters.emplace_back(context_.args_tracker->AddArgsTo(slice_id));
   }
 
-  for (uint32_t row : slice_rows) {
-    context_.args_tracker->AddArg(TableId::kNestableSlices, row, arg1_id,
-                                  arg1_id, Variadic::Integer(5));
-    context_.args_tracker->AddArg(TableId::kNestableSlices, row, arg2_id,
-                                  arg2_id, Variadic::String(val_id));
+  for (auto& inserter : slice_inserters) {
+    inserter.AddArg(arg1_id, Variadic::Integer(5))
+        .AddArg(arg2_id, Variadic::String(val_id));
   }
   context_.args_tracker->Flush();
 
@@ -1316,15 +1307,14 @@
 
   RawId id = storage->mutable_raw_table()->Insert(
       {0, storage->InternString("chrome_event.metadata"), 0, 0});
-  uint32_t row = *storage->raw_table().id().IndexOf(id);
 
   StringId name1_id = storage->InternString(base::StringView(kName1));
   StringId name2_id = storage->InternString(base::StringView(kName2));
   StringId value1_id = storage->InternString(base::StringView(kValue1));
-  context_.args_tracker->AddArg(TableId::kRawEvents, row, name1_id, name1_id,
-                                Variadic::String(value1_id));
-  context_.args_tracker->AddArg(TableId::kRawEvents, row, name2_id, name2_id,
-                                Variadic::Integer(kValue2));
+
+  context_.args_tracker->AddArgsTo(id)
+      .AddArg(name1_id, Variadic::String(value1_id))
+      .AddArg(name2_id, Variadic::Integer(kValue2));
   context_.args_tracker->Flush();
 
   auto metadata_filter = [](const char* metadata_name) {
diff --git a/src/trace_processor/global_args_tracker.h b/src/trace_processor/global_args_tracker.h
index a368954..09cf9af 100644
--- a/src/trace_processor/global_args_tracker.h
+++ b/src/trace_processor/global_args_tracker.h
@@ -35,7 +35,7 @@
     StringId key = 0;
     Variadic value = Variadic::Integer(0);
 
-    TableId table;
+    Column* column;
     uint32_t row;
   };
 
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index 79b1e72..afce6e2 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -360,24 +360,20 @@
   UniqueTid utid = context_->process_tracker->GetOrCreateThread(tid);
   RawId id =
       context_->storage->mutable_raw_table()->Insert({ts, event_id, cpu, utid});
-  uint32_t row = *context_->storage->raw_table().id().IndexOf(id);
+  auto inserter = context_->args_tracker->AddArgsTo(id);
 
   for (auto it = evt.field(); it; ++it) {
     protos::pbzero::GenericFtraceEvent::Field::Decoder fld(*it);
     auto field_name_id = context_->storage->InternString(fld.name());
     if (fld.has_int_value()) {
-      context_->args_tracker->AddArg(TableId::kRawEvents, row, field_name_id,
-                                     field_name_id,
-                                     Variadic::Integer(fld.int_value()));
+      inserter.AddArg(field_name_id, Variadic::Integer(fld.int_value()));
     } else if (fld.has_uint_value()) {
-      context_->args_tracker->AddArg(
-          TableId::kRawEvents, row, field_name_id, field_name_id,
+      inserter.AddArg(
+          field_name_id,
           Variadic::Integer(static_cast<int64_t>(fld.uint_value())));
     } else if (fld.has_str_value()) {
       StringId str_value = context_->storage->InternString(fld.str_value());
-      context_->args_tracker->AddArg(TableId::kRawEvents, row, field_name_id,
-                                     field_name_id,
-                                     Variadic::String(str_value));
+      inserter.AddArg(field_name_id, Variadic::String(str_value));
     }
   }
 }
@@ -399,7 +395,7 @@
   UniqueTid utid = context_->process_tracker->GetOrCreateThread(tid);
   RawId id = context_->storage->mutable_raw_table()->Insert(
       {ts, message_strings.message_name_id, cpu, utid});
-  uint32_t raw_event_row = *context_->storage->raw_table().id().IndexOf(id);
+  auto inserter = context_->args_tracker->AddArgsTo(id);
 
   for (auto fld = decoder.ReadField(); fld.valid(); fld = decoder.ReadField()) {
     if (PERFETTO_UNLIKELY(fld.id() >= kMaxFtraceEventFields)) {
@@ -419,9 +415,7 @@
       case ProtoSchemaType::kSint64:
       case ProtoSchemaType::kBool:
       case ProtoSchemaType::kEnum: {
-        context_->args_tracker->AddArg(TableId::kRawEvents, raw_event_row,
-                                       name_id, name_id,
-                                       Variadic::Integer(fld.as_int64()));
+        inserter.AddArg(name_id, Variadic::Integer(fld.as_int64()));
         break;
       }
       case ProtoSchemaType::kUint32:
@@ -431,29 +425,22 @@
         // Note that SQLite functions will still treat unsigned values
         // as a signed 64 bit integers (but the translation back to ftrace
         // refers to this storage directly).
-        context_->args_tracker->AddArg(
-            TableId::kRawEvents, raw_event_row, name_id, name_id,
-            Variadic::UnsignedInteger(fld.as_uint64()));
+        inserter.AddArg(name_id, Variadic::UnsignedInteger(fld.as_uint64()));
         break;
       }
       case ProtoSchemaType::kString:
       case ProtoSchemaType::kBytes: {
         StringId value = context_->storage->InternString(fld.as_string());
-        context_->args_tracker->AddArg(TableId::kRawEvents, raw_event_row,
-                                       name_id, name_id,
-                                       Variadic::String(value));
+        inserter.AddArg(name_id, Variadic::String(value));
         break;
       }
       case ProtoSchemaType::kDouble: {
-        context_->args_tracker->AddArg(TableId::kRawEvents, raw_event_row,
-                                       name_id, name_id,
-                                       Variadic::Real(fld.as_double()));
+        inserter.AddArg(name_id, Variadic::Real(fld.as_double()));
         break;
       }
       case ProtoSchemaType::kFloat: {
-        context_->args_tracker->AddArg(
-            TableId::kRawEvents, raw_event_row, name_id, name_id,
-            Variadic::Real(static_cast<double>(fld.as_float())));
+        inserter.AddArg(name_id,
+                        Variadic::Real(static_cast<double>(fld.as_float())));
         break;
       }
       case ProtoSchemaType::kUnknown:
@@ -618,10 +605,9 @@
       static_cast<uint32_t>(sig.pid()));
   InstantId id = context_->event_tracker->PushInstant(ts, signal_generate_id_,
                                                       utid, RefType::kRefUtid);
-  uint32_t row = *context_->storage->instant_table().id().IndexOf(id);
 
-  context_->args_tracker->AddArg(TableId::kInstants, row, signal_name_id_,
-                                 signal_name_id_, Variadic::Integer(sig.sig()));
+  context_->args_tracker->AddArgsTo(id).AddArg(signal_name_id_,
+                                               Variadic::Integer(sig.sig()));
 }
 
 void FtraceParser::ParseSignalDeliver(int64_t ts,
@@ -631,10 +617,9 @@
   UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
   InstantId id = context_->event_tracker->PushInstant(ts, signal_deliver_id_,
                                                       utid, RefType::kRefUtid);
-  uint32_t row = *context_->storage->instant_table().id().IndexOf(id);
 
-  context_->args_tracker->AddArg(TableId::kInstants, row, signal_name_id_,
-                                 signal_name_id_, Variadic::Integer(sig.sig()));
+  context_->args_tracker->AddArgsTo(id).AddArg(signal_name_id_,
+                                               Variadic::Integer(sig.sig()));
 }
 
 void FtraceParser::ParseLowmemoryKill(int64_t ts, ConstBytes blob) {
@@ -653,13 +638,12 @@
 
   InstantId id = context_->event_tracker->PushInstant(
       ts, lmk_id_, opt_utid.value(), RefType::kRefUtid, true);
-  uint32_t row = *context_->storage->instant_table().id().IndexOf(id);
 
   // Store the comm as an arg.
   auto comm_id = context_->storage->InternString(
       lmk.has_comm() ? lmk.comm() : base::StringView());
-  context_->args_tracker->AddArg(TableId::kInstants, row, comm_name_id_,
-                                 comm_name_id_, Variadic::String(comm_id));
+  context_->args_tracker->AddArgsTo(id).AddArg(comm_name_id_,
+                                               Variadic::String(comm_id));
 }
 
 void FtraceParser::ParseOOMScoreAdjUpdate(int64_t ts, ConstBytes blob) {
diff --git a/src/trace_processor/importers/ftrace/sched_event_tracker.cc b/src/trace_processor/importers/ftrace/sched_event_tracker.cc
index 4bf01c2..79b3666 100644
--- a/src/trace_processor/importers/ftrace/sched_event_tracker.cc
+++ b/src/trace_processor/importers/ftrace/sched_event_tracker.cc
@@ -196,15 +196,13 @@
   // not insert sched_switch.
   RawId id = context_->storage->mutable_raw_table()->Insert(
       {ts, sched_switch_id_, cpu, prev_utid});
-  uint32_t row = *context_->storage->raw_table().id().IndexOf(id);
 
   // Note: this ordering is important. The events should be pushed in the same
   // order as the order of fields in the proto; this is used by the raw table to
   // index these events using the field ids.
   using SS = protos::pbzero::SchedSwitchFtraceEvent;
 
-  ArgsTracker::BoundInserter inserter(context_->args_tracker.get(),
-                                      TableId::kRawEvents, row);
+  auto inserter = context_->args_tracker->AddArgsTo(id);
   auto add_raw_arg = [this, &inserter](int field_num, Variadic var) {
     StringId key = sched_switch_field_ids_[static_cast<size_t>(field_num)];
     inserter.AddArg(key, var);
@@ -276,15 +274,15 @@
   // Add an entry to the raw table.
   RawId id = context_->storage->mutable_raw_table()->Insert(
       {ts, sched_waking_id_, cpu, curr_utid});
-  uint32_t row = *context_->storage->raw_table().id().IndexOf(id);
 
   // "success" is hardcoded as always 1 by the kernel, with a TODO to remove it.
   static constexpr int32_t kHardcodedSuccess = 1;
 
   using SW = protos::pbzero::SchedWakingFtraceEvent;
-  auto add_raw_arg = [this, row](int field_num, Variadic var) {
+  auto inserter = context_->args_tracker->AddArgsTo(id);
+  auto add_raw_arg = [this, &inserter](int field_num, Variadic var) {
     StringId key = sched_waking_field_ids_[static_cast<size_t>(field_num)];
-    context_->args_tracker->AddArg(TableId::kRawEvents, row, key, key, var);
+    inserter.AddArg(key, var);
   };
   add_raw_arg(SW::kCommFieldNumber, Variadic::String(comm_id));
   add_raw_arg(SW::kPidFieldNumber, Variadic::Integer(wakee_pid));
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc b/src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc
index 660c680..46f0815 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc
+++ b/src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc
@@ -253,11 +253,10 @@
                                   static_cast<uint32_t>(tinfo.pid));
           InstantId id = context_->event_tracker->PushInstant(
               ts, name, utid, RefType::kRefUtid);
-          uint32_t row = *context_->storage->instant_table().id().IndexOf(id);
+          auto inserter = context_->args_tracker->AddArgsTo(id);
           for (const Arg& arg : args) {
-            context_->args_tracker->AddArg(
-                TableId::kInstants, row, arg.name, arg.name,
-                arg.value.ToStorageVariadic(context_->storage.get()));
+            inserter.AddArg(
+                arg.name, arg.value.ToStorageVariadic(context_->storage.get()));
           }
           context_->args_tracker->Flush();
           break;
@@ -379,10 +378,10 @@
               name, correlation_id);
           InstantId id = context_->event_tracker->PushInstant(
               ts, name, track_id.value, RefType::kRefTrack);
-          uint32_t row = *context_->storage->instant_table().id().IndexOf(id);
+          auto inserter = context_->args_tracker->AddArgsTo(id);
           for (const Arg& arg : args) {
-            context_->args_tracker->AddArg(
-                TableId::kInstants, row, arg.name, arg.name,
+            inserter.AddArg(
+                arg.name, arg.name,
                 arg.value.ToStorageVariadic(context_->storage.get()));
           }
           context_->args_tracker->Flush();
diff --git a/src/trace_processor/importers/proto/android_probes_parser.cc b/src/trace_processor/importers/proto/android_probes_parser.cc
index 178be15..1952fef 100644
--- a/src/trace_processor/importers/proto/android_probes_parser.cc
+++ b/src/trace_processor/importers/proto/android_probes_parser.cc
@@ -229,11 +229,9 @@
     // arg_set_id when the arg tracker is flushed.
     auto id = context_->metadata_tracker->AppendMetadata(
         metadata::android_packages_list, Variadic::Integer(0));
-    uint32_t row = *context_->storage->metadata_table().id().IndexOf(id);
-    auto add_arg = [this, row](base::StringView name, Variadic value) {
+    auto add_arg = [this, id](base::StringView name, Variadic value) {
       StringId key_id = context_->storage->InternString(name);
-      context_->args_tracker->AddArg(TableId::kMetadataTable, row, key_id,
-                                     key_id, value);
+      context_->args_tracker->AddArgsTo(id).AddArg(key_id, value);
     };
     protos::pbzero::PackagesList_PackageInfo::Decoder pkg(*it);
     add_arg("name",
diff --git a/src/trace_processor/importers/proto/args_table_utils_unittest.cc b/src/trace_processor/importers/proto/args_table_utils_unittest.cc
index d5e3eb1..df023b4 100644
--- a/src/trace_processor/importers/proto/args_table_utils_unittest.cc
+++ b/src/trace_processor/importers/proto/args_table_utils_unittest.cc
@@ -130,8 +130,7 @@
   ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
                            << status.message();
 
-  ArgsTracker::BoundInserter inserter(context_.args_tracker.get(),
-                                      TableId::kTrack, 0);
+  auto inserter = context_.args_tracker->AddArgsTo(TrackId(0));
   status = helper.InternProtoIntoArgsTable(
       protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
       ".protozero.test.protos.EveryField", &inserter);
@@ -203,8 +202,7 @@
   ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
                            << status.message();
 
-  ArgsTracker::BoundInserter inserter(context_.args_tracker.get(),
-                                      TableId::kTrack, 0);
+  auto inserter = context_.args_tracker->AddArgsTo(TrackId(0));
   status = helper.InternProtoIntoArgsTable(
       protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
       ".protozero.test.protos.NestedA", &inserter);
@@ -232,8 +230,7 @@
   ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
                            << status.message();
 
-  ArgsTracker::BoundInserter inserter(context_.args_tracker.get(),
-                                      TableId::kTrack, 0);
+  auto inserter = context_.args_tracker->AddArgsTo(TrackId(0));
   status = helper.InternProtoIntoArgsTable(
       protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
       ".protozero.test.protos.CamelCaseFields", &inserter);
@@ -276,8 +273,7 @@
         return true;
       });
 
-  ArgsTracker::BoundInserter inserter(context_.args_tracker.get(),
-                                      TableId::kTrack, 0);
+  auto inserter = context_.args_tracker->AddArgsTo(TrackId(0));
   status = helper.InternProtoIntoArgsTable(
       protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
       ".protozero.test.protos.NestedA", &inserter);
@@ -317,8 +313,7 @@
         return false;
       });
 
-  ArgsTracker::BoundInserter inserter(context_.args_tracker.get(),
-                                      TableId::kTrack, 0);
+  auto inserter = context_.args_tracker->AddArgsTo(TrackId(0));
   status = helper.InternProtoIntoArgsTable(
       protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
       ".protozero.test.protos.NestedA", &inserter);
@@ -383,8 +378,7 @@
   ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
                            << status.message();
 
-  ArgsTracker::BoundInserter inserter(context_.args_tracker.get(),
-                                      TableId::kTrack, 0);
+  auto inserter = context_.args_tracker->AddArgsTo(TrackId(0));
   status = helper.InternProtoIntoArgsTable(
       protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
       ".protozero.test.protos.NestedA", &inserter);
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.cc b/src/trace_processor/importers/proto/graphics_event_parser.cc
index 12d2895..5d55216 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_event_parser.cc
@@ -746,12 +746,10 @@
                                        vulkan_memory_event);
 
   auto* allocs = context_->storage->mutable_vulkan_memory_allocations_table();
-  auto id = allocs->Insert(vulkan_memory_event_row);
-  uint32_t row = *allocs->id().IndexOf(id);
+  VulkanAllocId id = allocs->Insert(vulkan_memory_event_row);
 
   if (vulkan_memory_event.has_annotations()) {
-    ArgsTracker::BoundInserter inserter(context_->args_tracker.get(),
-                                        TableId::kVulkanMemoryAllocation, row);
+    auto inserter = context_->args_tracker->AddArgsTo(id);
 
     for (auto it = vulkan_memory_event.annotations(); it; ++it) {
       protos::pbzero::VulkanMemoryEventAnnotation::Decoder annotation(*it);
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index eab7895..ce48d17 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -517,7 +517,7 @@
   if (bundle.has_metadata()) {
     RawId id = storage->mutable_raw_table()->Insert(
         {ts, raw_chrome_metadata_event_id_, 0, 0});
-    uint32_t row = *storage->raw_table().id().IndexOf(id);
+    auto inserter = args.AddArgsTo(id);
 
     // Metadata is proxied via a special event in the raw table to JSON export.
     for (auto it = bundle.metadata(); it; ++it) {
@@ -537,14 +537,13 @@
         context_->storage->IncrementStats(stats::empty_chrome_metadata);
         continue;
       }
-      args.AddArg(TableId::kRawEvents, row, name_id, name_id, value);
+      args.AddArgsTo(id).AddArg(name_id, value);
     }
   }
 
   if (bundle.has_legacy_ftrace_output()) {
     RawId id = storage->mutable_raw_table()->Insert(
         {ts, raw_chrome_legacy_system_trace_event_id_, 0, 0});
-    uint32_t row = *storage->raw_table().id().IndexOf(id);
 
     std::string data;
     for (auto it = bundle.legacy_ftrace_output(); it; ++it) {
@@ -552,7 +551,7 @@
     }
     Variadic value =
         Variadic::String(storage->InternString(base::StringView(data)));
-    args.AddArg(TableId::kRawEvents, row, data_name_id_, data_name_id_, value);
+    args.AddArgsTo(id).AddArg(data_name_id_, value);
   }
 
   if (bundle.has_legacy_json_trace()) {
@@ -564,11 +563,9 @@
       }
       RawId id = storage->mutable_raw_table()->Insert(
           {ts, raw_chrome_legacy_user_trace_event_id_, 0, 0});
-      uint32_t row = *storage->raw_table().id().IndexOf(id);
       Variadic value =
           Variadic::String(storage->InternString(legacy_trace.data()));
-      args.AddArg(TableId::kRawEvents, row, data_name_id_, data_name_id_,
-                  value);
+      args.AddArgsTo(id).AddArg(data_name_id_, value);
     }
   }
 }
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
index 6573122..c6b789d 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -80,6 +80,7 @@
 using ::testing::NiceMock;
 using ::testing::Pointwise;
 using ::testing::Return;
+using ::testing::ReturnRef;
 using ::testing::UnorderedElementsAreArray;
 
 namespace {
@@ -175,10 +176,14 @@
 
 class MockBoundInserter : public ArgsTracker::BoundInserter {
  public:
-  MockBoundInserter()
-      : ArgsTracker::BoundInserter(nullptr, TableId::kSched, 0u) {}
+  MockBoundInserter() : ArgsTracker::BoundInserter(nullptr, nullptr, 0u) {
+    ON_CALL(*this, AddArg(_, _, _)).WillByDefault(ReturnRef(*this));
+  }
 
-  MOCK_METHOD3(AddArg, void(StringId flat_key, StringId key, Variadic v));
+  MOCK_METHOD3(AddArg,
+               ArgsTracker::BoundInserter&(StringId flat_key,
+                                           StringId key,
+                                           Variadic v));
 };
 
 class MockSliceTracker : public SliceTracker {
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index c44238c..650156f 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -899,13 +899,12 @@
 
   RawId id = context_->storage->mutable_raw_table()->Insert(
       {ts, raw_legacy_event_id_, 0, *utid});
-  uint32_t row = *context_->storage->raw_table().id().IndexOf(id);
 
   ArgsTracker args(context_);
-  ArgsTracker::BoundInserter inserter(&args, TableId::kRawEvents, row);
+  auto inserter = args.AddArgsTo(id);
 
-  inserter.AddArg(legacy_event_category_key_id_, Variadic::String(category_id));
-  inserter.AddArg(legacy_event_name_key_id_, Variadic::String(name_id));
+  inserter.AddArg(legacy_event_category_key_id_, Variadic::String(category_id))
+      .AddArg(legacy_event_name_key_id_, Variadic::String(name_id));
 
   std::string phase_string(1, static_cast<char>(legacy_event.phase()));
   StringId phase_id = context_->storage->InternString(phase_string.c_str());
diff --git a/src/trace_processor/slice_tracker.cc b/src/trace_processor/slice_tracker.cc
index 63d1573..a9323f5 100644
--- a/src/trace_processor/slice_tracker.cc
+++ b/src/trace_processor/slice_tracker.cc
@@ -142,8 +142,7 @@
 
   if (args_callback) {
     ArgsTracker* tracker = &stack->back().second;
-    ArgsTracker::BoundInserter bound_inserter(tracker, TableId::kNestableSlices,
-                                              slice_idx);
+    auto bound_inserter = tracker->AddArgsTo(id);
     args_callback(&bound_inserter);
   }
   return slice_idx;
@@ -180,9 +179,8 @@
 
   if (args_callback) {
     ArgsTracker* tracker = &stack.back().second;
-    ArgsTracker::BoundInserter inserter(tracker, TableId::kNestableSlices,
-                                        slice_idx);
-    args_callback(&inserter);
+    auto bound_inserter = tracker->AddArgsTo(slices->id()[slice_idx]);
+    args_callback(&bound_inserter);
   }
 
   // If this slice is the top slice on the stack, pop it off.
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index 146d260..da7d12a 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -60,19 +60,6 @@
 using StringId = StringPool::Id;
 static const StringId kNullStringId = StringId(0);
 
-// Identifiers for all the tables in the database.
-enum class TableId : uint8_t {
-  kInvalid = 0,
-  kCounterValues = 1,
-  kRawEvents = 2,
-  kInstants = 3,
-  kSched = 4,
-  kNestableSlices = 5,
-  kMetadataTable = 6,
-  kTrack = 7,
-  kVulkanMemoryAllocation = 8,
-};
-
 using ArgSetId = uint32_t;
 static const ArgSetId kInvalidArgSetId = 0;
 
@@ -90,6 +77,8 @@
 
 using RawId = tables::RawTable::Id;
 
+using VulkanAllocId = tables::VulkanMemoryAllocationsTable::Id;
+
 // TODO(lalitm): this is a temporary hack while migrating the counters table and
 // will be removed when the migration is complete.
 static const TrackId kInvalidTrackId =
diff --git a/src/trace_processor/track_tracker.cc b/src/trace_processor/track_tracker.cc
index 0a35102..390fea4 100644
--- a/src/trace_processor/track_tracker.cc
+++ b/src/trace_processor/track_tracker.cc
@@ -73,10 +73,10 @@
   auto id = context_->storage->mutable_track_table()->Insert(row);
   fuchsia_async_tracks_[correlation_id] = id;
 
-  ArgsTracker::BoundInserter inserter(context_->args_tracker.get(),
-                                      TableId::kTrack, id.value);
-  inserter.AddArg(source_key_, Variadic::String(fuchsia_source_));
-  inserter.AddArg(source_id_key_, Variadic::Integer(correlation_id));
+  context_->args_tracker->AddArgsTo(id)
+      .AddArg(source_key_, Variadic::String(fuchsia_source_))
+      .AddArg(source_id_key_, Variadic::Integer(correlation_id));
+
   return id;
 }
 
@@ -115,13 +115,13 @@
   TrackId id = context_->storage->mutable_process_track_table()->Insert(track);
   chrome_tracks_[tuple] = id;
 
-  ArgsTracker::BoundInserter inserter(context_->args_tracker.get(),
-                                      TableId::kTrack, id.value);
-  inserter.AddArg(source_key_, Variadic::String(chrome_source_));
-  inserter.AddArg(source_id_key_, Variadic::Integer(source_id));
-  inserter.AddArg(source_id_is_process_scoped_key_,
-                  Variadic::Boolean(source_id_is_process_scoped));
-  inserter.AddArg(source_scope_key_, Variadic::String(source_scope));
+  context_->args_tracker->AddArgsTo(id)
+      .AddArg(source_key_, Variadic::String(chrome_source_))
+      .AddArg(source_id_key_, Variadic::Integer(source_id))
+      .AddArg(source_id_is_process_scoped_key_,
+              Variadic::Boolean(source_id_is_process_scoped))
+      .AddArg(source_scope_key_, Variadic::String(source_scope));
+
   return id;
 }
 
@@ -139,10 +139,10 @@
   auto id = context_->storage->mutable_process_track_table()->Insert(row);
   android_async_tracks_[tuple] = id;
 
-  ArgsTracker::BoundInserter inserter(context_->args_tracker.get(),
-                                      TableId::kTrack, id.value);
-  inserter.AddArg(source_key_, Variadic::String(android_source_));
-  inserter.AddArg(source_id_key_, Variadic::Integer(cookie));
+  context_->args_tracker->AddArgsTo(id)
+      .AddArg(source_key_, Variadic::String(android_source_))
+      .AddArg(source_id_key_, Variadic::Integer(cookie));
+
   return id;
 }
 
@@ -156,8 +156,9 @@
   auto id = context_->storage->mutable_process_track_table()->Insert(row);
   chrome_process_instant_tracks_[upid] = id;
 
-  context_->args_tracker->AddArg(TableId::kTrack, id.value, source_key_,
-                                 source_key_, Variadic::String(chrome_source_));
+  context_->args_tracker->AddArgsTo(id).AddArg(
+      source_key_, Variadic::String(chrome_source_));
+
   return id;
 }
 
@@ -166,9 +167,8 @@
     chrome_global_instant_track_id_ =
         context_->storage->mutable_track_table()->Insert({});
 
-    context_->args_tracker->AddArg(
-        TableId::kTrack, chrome_global_instant_track_id_->value, source_key_,
-        source_key_, Variadic::String(chrome_source_));
+    context_->args_tracker->AddArgsTo(*chrome_global_instant_track_id_)
+        .AddArg(source_key_, Variadic::String(chrome_source_));
   }
   return *chrome_global_instant_track_id_;
 }
@@ -363,12 +363,9 @@
     track_id = context_->storage->mutable_track_table()->Insert(track);
   }
 
-  ArgsTracker::BoundInserter inserter(context_->args_tracker.get(),
-                                      TableId::kTrack, track_id->value);
-  inserter.AddArg(source_key_, Variadic::String(descriptor_source_));
-  inserter.AddArg(source_id_key_,
-                  Variadic::Integer(static_cast<int64_t>(uuid)));
-
+  context_->args_tracker->AddArgsTo(*track_id)
+      .AddArg(source_key_, Variadic::String(descriptor_source_))
+      .AddArg(source_id_key_, Variadic::Integer(static_cast<int64_t>(uuid)));
   return *track_id;
 }