Skip to content

Commit a156161

Browse files
committed
tp: add In filter support to TypedCursor and optimize In bytecode
Add SetFilterValueListUnchecked to TypedCursor allowing callers to pass a pointer+size array of FilterValue for In filters without allocation. Plumb this through the codegen'd ConstCursor/Cursor. Optimize the In bytecode by pre-building lookup structures during CastFilterValueList instead of rebuilding on every Execute(): - For dense Id/Uint32: BitVector (built once, not per-call) - For large sparse integer/string lists: FlatHashMapV2 for O(1) - For small lists (<=16): linear scan (cache-friendly) The lookup is stored as a variant in CastFilterValueListResult, replacing the separate value_list field. Migrate experimental_slice_layout to use In filter on track_id.
1 parent 1ffa896 commit a156161

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_slice_layout.cc

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <string>
2828
#include <tuple>
2929
#include <unordered_map>
30-
#include <unordered_set>
3130
#include <utility>
3231
#include <vector>
3332

@@ -39,6 +38,7 @@
3938
#include "perfetto/trace_processor/basic_types.h"
4039
#include "src/trace_processor/containers/string_pool.h"
4140
#include "src/trace_processor/core/dataframe/specs.h"
41+
#include "src/trace_processor/core/dataframe/typed_cursor.h"
4242
#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/static_table_function.h"
4343
#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/tables_py.h"
4444
#include "src/trace_processor/storage/trace_storage.h"
@@ -78,11 +78,12 @@ bool ExperimentalSliceLayout::Cursor::Run(
7878
}
7979

8080
const char* filter_string = arguments[0].string_value;
81-
std::unordered_set<TrackId> selected_tracks;
81+
using FilterValue = dataframe::TypedCursor::FilterValue;
82+
std::vector<FilterValue> selected_track_ids;
8283
for (base::StringSplitter sp(filter_string, ','); sp.Next();) {
8384
std::optional<uint32_t> maybe = base::CStringToUInt32(sp.cur_token());
8485
if (maybe) {
85-
selected_tracks.insert(TrackId{maybe.value()});
86+
selected_track_ids.emplace_back(static_cast<int64_t>(maybe.value()));
8687
}
8788
}
8889

@@ -96,13 +97,18 @@ bool ExperimentalSliceLayout::Cursor::Run(
9697
return OnSuccess(&table_.dataframe());
9798
}
9899

99-
// Find all the slices for the tracks we want to filter and create a vector of
100-
// row numbers out of them.
100+
// Find all the slices for the tracks we want to filter using an In filter
101+
// on track_id to avoid a full table scan.
102+
auto track_cursor = slice_table_->CreateCursor(
103+
{dataframe::FilterSpec{tables::SliceTable::ColumnIndex::track_id, 0,
104+
dataframe::In{}, std::nullopt}});
105+
track_cursor.SetFilterValueListUnchecked(
106+
0, selected_track_ids.data(),
107+
static_cast<uint32_t>(selected_track_ids.size()));
108+
101109
std::vector<tables::SliceTable::RowNumber> rows;
102-
for (auto it = slice_table_->IterateRows(); it; ++it) {
103-
if (selected_tracks.count(it.track_id())) {
104-
rows.emplace_back(it.row_number());
105-
}
110+
for (track_cursor.Execute(); !track_cursor.Eof(); track_cursor.Next()) {
111+
rows.emplace_back(track_cursor.ToRowNumber());
106112
}
107113

108114
// Compute the table and add it to the cache for future use.

0 commit comments

Comments
 (0)