tp: cleanup and reorganize docs
Change-Id: I4a5f118777b80b87e56ea9f04bae079a4a6cfe62
diff --git a/docs/toc.md b/docs/toc.md
index 0ed6a88..450e4dd 100644
--- a/docs/toc.md
+++ b/docs/toc.md
@@ -41,21 +41,20 @@
* [Trace analysis](#)
* [Trace Processor](analysis/trace-processor.md)
- * [PerfettoSQL Syntax](analysis/perfetto-sql-syntax.md)
* [PerfettoSQL Standard Library](analysis/stdlib-docs.autogen)
- * [PerfettoSQL Tables](analysis/sql-tables.autogen)
- * [PerfettoSQL Built-ins](analysis/builtin.md)
+ * [PerfettoSQL Syntax](analysis/perfetto-sql-syntax.md)
+ * [PerfettoSQL Prelude](analysis/sql-tables.autogen)
* [PerfettoSQL Common Queries](analysis/common-queries.md)
+ * [PerfettoSQL Built-ins](analysis/builtin.md)
* [Trace-based metrics](analysis/metrics.md)
* [Batch Trace Processor](analysis/batch-trace-processor.md)
- * [Stats table](analysis/sql-stats.autogen)
- * [Pivot tables](analysis/pivot-tables.md)
* [Trace visualization](#)
* [Perfetto UI](visualization/perfetto-ui.md)
* [Visualising large traces](visualization/large-traces.md)
* [Deep linking to Perfetto UI](visualization/deep-linking-to-perfetto-ui.md)
* [Perfetto UI release process](visualization/perfetto-ui-release-process.md)
+ * [Pivot tables](analysis/pivot-tables.md)
* [Core concepts](#)
* [Trace configuration](concepts/config.md)
@@ -71,6 +70,7 @@
* [heap_profile cmdline](reference/heap_profile-cli.md)
* [Synthetic TrackEvent](reference/synthetic-track-event.md)
* [Android Version Notes](reference/android-version-notes.md)
+ * [Stats table](analysis/sql-stats.autogen)
* [Contributing](#)
* [Getting started](contributing/getting-started.md)
diff --git a/infra/perfetto.dev/src/gen_sql_tables_reference.js b/infra/perfetto.dev/src/gen_sql_tables_reference.js
index 72800b5..5dbaca3 100644
--- a/infra/perfetto.dev/src/gen_sql_tables_reference.js
+++ b/infra/perfetto.dev/src/gen_sql_tables_reference.js
@@ -31,180 +31,10 @@
return comment;
}
-// Returns an object describing the table as follows:
-// { name: 'HeapGraphObjectTable',
-// cols: [ {name: 'upid', type: 'uint32_t', optional: false },
-// {name: 'graph_sample_ts', type: 'int64_t', optional: false },
-function parseTableDef(tableDefName, tableDef) {
- const tableDesc = {
- name: '', // The SQL table name, e.g. stack_profile_mapping.
- cppClassName: '', // e.g., StackProfileMappingTable.
- defMacro: tableDefName, // e.g., PERFETTO_TP_STACK_PROFILE_MAPPING_DEF.
- comment: '',
- parent: undefined, // Will be filled afterwards in the resolution phase.
- parentDefName: '', // e.g., PERFETTO_TP_STACK_PROFILE_MAPPING_DEF.
- tablegroup: 'Misc', // From @tablegroup in comments.
- cols: {},
- };
- const getOrCreateColumn = (name) => {
- if (name in tableDesc.cols)
- return tableDesc.cols[name];
- tableDesc.cols[name] = {
- name: name,
- type: '',
- comment: '',
- optional: false,
- refTableCppName: undefined,
- joinTable: undefined,
- joinCol: undefined,
- };
- return tableDesc.cols[name];
- };
-
- // Reserve the id and type columns so they appear first in the column list
- // They will only be kept in case this is a root table - otherwise they will
- // be deleted below..
- const id = getOrCreateColumn('id');
- const type = getOrCreateColumn('type');
-
- let lastColumn = undefined;
- for (const line of tableDef.split('\n')) {
- if (line.startsWith('#define'))
- continue; // Skip the first line.
- let m;
- if (line.startsWith('//')) {
- let comm = line.replace(/^\s*\/\/\s*/, '');
- if (m = comm.match(/@tablegroup (.*)/)) {
- tableDesc.tablegroup = m[1];
- continue;
- }
- if (m = comm.match(/@name (\w+)/)) {
- tableDesc.name = m[1];
- continue;
- }
- if (m = comm.match(/@param\s+([^ ]+)\s*({\w+})?\s*(.*)/)) {
- lastColumn = getOrCreateColumn(/*name=*/ m[1]);
- lastColumn.type = (m[2] || '').replace(/(^{)|(}$)/g, '');
- lastColumn.comment = m[3];
- continue;
- }
- if (lastColumn === undefined) {
- tableDesc.comment += `${comm}\n`;
- } else {
- lastColumn.comment = `${lastColumn.comment}\n${comm}`;
- }
- continue;
- }
- if (m = line.match(/^\s*NAME\((\w+)\s*,\s*"(\w+)"/)) {
- tableDesc.cppClassName = m[1];
- if (tableDesc.name === '') {
- tableDesc.name = m[2]; // Set only if not overridden by @name.
- }
- continue;
- }
- if (m = line.match(/(PERFETTO_TP_ROOT_TABLE|PARENT)\((\w+)/)) {
- if (m[1] === 'PARENT') {
- tableDesc.parentDefName = m[2];
- }
- continue;
- }
- if (m = line.match(/^\s*C\(([^,]+)\s*,\s*(\w+)/)) {
- const col = getOrCreateColumn(/*name=*/ m[2]);
- col.type = m[1];
- if (m = col.type.match(/std::optional<(.*)>/)) {
- col.type = m[1];
- col.optional = true;
- }
- if (col.type === 'StringPool::Id') {
- col.type = 'string';
- }
- const sep = col.type.indexOf('::');
- if (sep > 0) {
- col.refTableCppName = col.type.substr(0, sep);
- }
- continue;
- }
- throw new Error(`Cannot parse line "${line}" from ${tableDefName}`);
- }
-
- if (tableDesc.parentDefName === '') {
- id.type = `${tableDesc.cppClassName}::Id`;
- type.type = 'string';
- } else {
- delete tableDesc.cols['id'];
- delete tableDesc.cols['type'];
- }
-
- // Process {@joinable xxx} annotations.
- const regex = /\s?\{@joinable\s*(\w+)\.(\w+)\s*\}/;
- for (const col of Object.values(tableDesc.cols)) {
- const m = col.comment.match(regex)
- if (m) {
- col.joinTable = m[1];
- col.joinCol = m[2];
- col.comment = col.comment.replace(regex, '');
- }
- }
- return tableDesc;
-}
-
-
-function parseTablesInCppFile(filePath) {
- const hdr = fs.readFileSync(filePath, 'UTF8');
- const regex = /^\s*PERFETTO_TP_TABLE\((\w+)\)/mg;
- let match = regex.exec(hdr);
- const tables = [];
- while (match != null) {
- const tableDefName = match[1];
- match = regex.exec(hdr);
-
- // Now let's extract the table definition, that looks like this:
- // // Some
- // // Multiline
- // // Comment
- // #define PERFETTO_TP_STACK_PROFILE_FRAME_DEF(NAME, PARENT, C) \
- // NAME(StackProfileFrameTable, "stack_profile_frame") \
- // PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- // C(StringPool::Id, name) \
- // C(StackProfileMappingTable::Id, mapping) \
- // C(int64_t, rel_pc) \
- // C(std::optional<uint32_t>, symbol_set_id)
- //
- // Where PERFETTO_TP_STACK_PROFILE_FRAME_DEF is |tableDefName|.
- let pattern = `(^[ ]*//.*\n)*`;
- pattern += `^\s*#define\\s+${tableDefName}\\s*\\(`;
- pattern += `(.*\\\\\\s*\n)+`;
- pattern += `.+`;
- const r = new RegExp(pattern, 'mi');
- const tabMatch = r.exec(hdr);
- if (!tabMatch) {
- console.error(`could not find table ${tableDefName}`);
- continue;
- }
- tables.push(parseTableDef(tableDefName, tabMatch[0]));
- }
- return tables;
-}
-
function parseTablesInJson(filePath) {
return JSON.parse(fs.readFileSync(filePath, 'UTF8'));
}
-function overrideCppTablesWithJsonTables(cpp, json) {
- const out = [];
- const jsonAdded = new Set();
- for (const table of json) {
- out.push(table);
- jsonAdded.add(table.name);
- }
- for (const table of cpp) {
- if (!jsonAdded.has(table.name)) {
- out.push(table);
- }
- }
- return out;
-}
-
function genLink(table) {
return `[${table.name}](#${table.name})`;
}
@@ -239,31 +69,24 @@
}
function main() {
- const inFile = argv['i'];
const outFile = argv['o'];
const jsonFile = argv['j'];
- if (!inFile) {
- console.error('Usage: -i hdr1.h -i hdr2.h -j tbls.json -[-o out.md]');
+ if (!jsonFile) {
+ console.error('Usage: -j tbls.json -[-o out.md]');
process.exit(1);
}
- // Can be either a string (-i single) or an array (-i one -i two).
- const inFiles = (inFile instanceof Array) ? inFile : [inFile];
- const cppTables =
- Array.prototype.concat(...inFiles.map(parseTablesInCppFile));
-
// Can be either a string (-j single) or an array (-j one -j two).
const jsonFiles = (jsonFile instanceof Array) ? jsonFile : [jsonFile];
const jsonTables =
Array.prototype.concat(...jsonFiles.map(parseTablesInJson));
- const tables = overrideCppTablesWithJsonTables(cppTables, jsonTables)
// Resolve parents.
const tablesIndex = {}; // 'TP_SCHED_SLICE_TABLE_DEF' -> table
const tablesByGroup = {}; // 'profilers' => [table1, table2]
const tablesCppName = {}; // 'StackProfileMappingTable' => table
const tablesByName = {}; // 'profile_mapping' => table
- for (const table of tables) {
+ for (const table of jsonTables) {
tablesIndex[table.defMacro] = table;
if (tablesByGroup[table.tablegroup] === undefined) {
tablesByGroup[table.tablegroup] = [];
@@ -279,7 +102,7 @@
return a.localeCompare(b);
});
- for (const table of tables) {
+ for (const table of jsonTables) {
if (table.parentDefName) {
table.parent = tablesIndex[table.parentDefName];
}
@@ -325,7 +148,7 @@
graph += '\n```\n';
}
- let title = '# PerfettoSQL Tables\n'
+ let title = '# PerfettoSQL Prelude\n'
let md = title + graph;
for (const tableGroup of tableGroups) {
md += `## ${tableGroup}\n`
diff --git a/infra/perfetto.dev/src/gen_stdlib_docs_md.py b/infra/perfetto.dev/src/gen_stdlib_docs_md.py
index 7959053..c82f641 100644
--- a/infra/perfetto.dev/src/gen_stdlib_docs_md.py
+++ b/infra/perfetto.dev/src/gen_stdlib_docs_md.py
@@ -29,9 +29,9 @@
def __init__(self, module_name: str, module_files: List[Dict[str,
Any]]) -> None:
self.module_name = module_name
- self.files_md = [
+ self.files_md = sorted([
FileMd(module_name, file_dict) for file_dict in module_files
- ]
+ ], key=lambda x: x.import_key)
self.summary_objs = '\n'.join(
file.summary_objs for file in self.files_md if file.summary_objs)
self.summary_funs = '\n'.join(
@@ -41,10 +41,16 @@
if file.summary_view_funs)
def print_description(self):
+ if not self.files_md:
+ return ''
+
long_s = []
long_s.append(f'## Module: {self.module_name}')
for file in self.files_md:
+ if not file.objs and not file.funs and not file.view_funs:
+ continue
+
long_s.append(f'### {file.import_key}')
if file.objs:
long_s.append('#### Views/Tables')