Merge "Reland: Add proto for recording VkDebugMarkerSetObjectNameEXT"
diff --git a/Android.bp b/Android.bp
index f3c60ad..ef8d66b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -4725,7 +4725,6 @@
"src/trace_processor/read_trace.cc",
"src/trace_processor/row_iterators.cc",
"src/trace_processor/sched_slice_table.cc",
- "src/trace_processor/slice_table.cc",
"src/trace_processor/span_join_operator_table.cc",
"src/trace_processor/sql_stats_table.cc",
"src/trace_processor/stack_profile_frame_table.cc",
@@ -4791,6 +4790,8 @@
"src/trace_processor/gzip_trace_parser.cc",
"src/trace_processor/heap_profile_tracker.cc",
"src/trace_processor/importers/ftrace/ftrace_descriptors.cc",
+ "src/trace_processor/importers/ftrace/ftrace_module.cc",
+ "src/trace_processor/importers/ftrace/ftrace_module_impl.cc",
"src/trace_processor/importers/ftrace/ftrace_parser.cc",
"src/trace_processor/importers/ftrace/ftrace_tokenizer.cc",
"src/trace_processor/importers/ftrace/sched_event_tracker.cc",
@@ -4798,6 +4799,7 @@
"src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc",
"src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc",
"src/trace_processor/importers/fuchsia/fuchsia_trace_utils.cc",
+ "src/trace_processor/importers/proto/android_probes_module.cc",
"src/trace_processor/importers/proto/android_probes_parser.cc",
"src/trace_processor/importers/proto/args_table_utils.cc",
"src/trace_processor/importers/proto/graphics_event_module.cc",
@@ -4808,7 +4810,9 @@
"src/trace_processor/importers/proto/proto_importer_module.cc",
"src/trace_processor/importers/proto/proto_trace_parser.cc",
"src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
+ "src/trace_processor/importers/proto/system_probes_module.cc",
"src/trace_processor/importers/proto/system_probes_parser.cc",
+ "src/trace_processor/importers/proto/track_event_module.cc",
"src/trace_processor/importers/proto/track_event_parser.cc",
"src/trace_processor/importers/proto/track_event_tokenizer.cc",
"src/trace_processor/importers/systrace/systrace_parser.cc",
diff --git a/BUILD b/BUILD
index 7f7e153..882900a 100644
--- a/BUILD
+++ b/BUILD
@@ -101,6 +101,7 @@
perfetto_cc_library(
name = "libprotozero",
srcs = [
+ ":src_base_base",
":src_protozero_protozero",
],
hdrs = [
@@ -743,8 +744,6 @@
"src/trace_processor/row_iterators.h",
"src/trace_processor/sched_slice_table.cc",
"src/trace_processor/sched_slice_table.h",
- "src/trace_processor/slice_table.cc",
- "src/trace_processor/slice_table.h",
"src/trace_processor/span_join_operator_table.cc",
"src/trace_processor/span_join_operator_table.h",
"src/trace_processor/sql_stats_table.cc",
@@ -794,7 +793,9 @@
"src/trace_processor/heap_profile_tracker.h",
"src/trace_processor/importers/ftrace/ftrace_descriptors.cc",
"src/trace_processor/importers/ftrace/ftrace_descriptors.h",
+ "src/trace_processor/importers/ftrace/ftrace_module.cc",
"src/trace_processor/importers/ftrace/ftrace_module.h",
+ "src/trace_processor/importers/ftrace/ftrace_module_impl.cc",
"src/trace_processor/importers/ftrace/ftrace_parser.cc",
"src/trace_processor/importers/ftrace/ftrace_parser.h",
"src/trace_processor/importers/ftrace/ftrace_tokenizer.cc",
@@ -815,6 +816,7 @@
"src/trace_processor/importers/json/json_trace_tokenizer.h",
"src/trace_processor/importers/json/json_trace_utils.cc",
"src/trace_processor/importers/json/json_trace_utils.h",
+ "src/trace_processor/importers/proto/android_probes_module.cc",
"src/trace_processor/importers/proto/android_probes_module.h",
"src/trace_processor/importers/proto/android_probes_parser.cc",
"src/trace_processor/importers/proto/android_probes_parser.h",
@@ -839,9 +841,11 @@
"src/trace_processor/importers/proto/proto_trace_parser.h",
"src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
"src/trace_processor/importers/proto/proto_trace_tokenizer.h",
+ "src/trace_processor/importers/proto/system_probes_module.cc",
"src/trace_processor/importers/proto/system_probes_module.h",
"src/trace_processor/importers/proto/system_probes_parser.cc",
"src/trace_processor/importers/proto/system_probes_parser.h",
+ "src/trace_processor/importers/proto/track_event_module.cc",
"src/trace_processor/importers/proto/track_event_module.h",
"src/trace_processor/importers/proto/track_event_parser.cc",
"src/trace_processor/importers/proto/track_event_parser.h",
diff --git a/README.md b/README.md
index 27f653a..be4c683 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,13 @@
See [www.perfetto.dev](https://www.perfetto.dev) for docs.
+Contributing
+------------
+See [/docs/contributing.md](docs/contributing.md) for instructions.
+
+The source-of-truth repo is [Android's Gerrit][aosp].
+The [GitHub repo](https://github.com/google/perfetto) is a read-only mirror.
+
Bugs
----
* For bugs affecting Android or the tracing internals use the internal
@@ -16,4 +23,6 @@
---------
You can reach us on our [Discord channel](https://discord.gg/35ShE3A).
If you prefer using IRC we have an experimental Discord <> IRC bridge
-synced with `#perfetto-dev` on [Freenode](https://webchat.freenode.net/).
\ No newline at end of file
+synced with `#perfetto-dev` on [Freenode](https://webchat.freenode.net/).
+
+[aosp]: https://android.googlesource.com/platform/external/perfetto/
diff --git a/docs/heapprofd.md b/docs/heapprofd.md
index fa2d2ff..1e46ce4 100644
--- a/docs/heapprofd.md
+++ b/docs/heapprofd.md
@@ -19,7 +19,7 @@
On Linux / MacOS, use the `tools/heap_profile` script to heap profile a
process. If you are having trouble make sure you are using the
[latest version](
-https://raw.githubusercontent.com/catapult-project/perfetto/master/tools/heap_profile).
+https://raw.githubusercontent.com/google/perfetto/master/tools/heap_profile).
See all the arguments using `tools/heap_profile -h`, or use the defaults
and just profile a process (e.g. `system_server`):
diff --git a/include/perfetto/trace_processor/trace_processor.h b/include/perfetto/trace_processor/trace_processor.h
index d469937..adf770e 100644
--- a/include/perfetto/trace_processor/trace_processor.h
+++ b/include/perfetto/trace_processor/trace_processor.h
@@ -60,7 +60,7 @@
// Returns the name of the column at index |col|. Can be called even before
// calling |Next()|.
- std::string GetColumName(uint32_t col);
+ std::string GetColumnName(uint32_t col);
// Returns the number of columns in this iterator's query. Can be called
// even before calling |Next()|.
diff --git a/infra/ci/frontend/static/script.js b/infra/ci/frontend/static/script.js
index d6fe73e..4a537c6 100644
--- a/infra/ci/frontend/static/script.js
+++ b/infra/ci/frontend/static/script.js
@@ -130,7 +130,7 @@
const logUrl = 'https://goto.google.com/perfetto-ci-logs-';
const docsUrl = 'https://docs.perfetto.dev/#/continuous-integration';
return m('header',
- m('h1', 'Perfetto ', m('span', 'CI')),
+ m('a[href=/#!/cls]', m('h1', 'Perfetto ', m('span', 'CI'))),
m('nav',
m(`div${active('cls')}`, m('a[href=/#!/cls]', 'CLs')),
m(`div${active('jobs')}`, m('a[href=/#!/jobs]', 'Jobs')),
diff --git a/infra/git_mirror_bot/Makefile b/infra/git_mirror_bot/Makefile
index dedaad9..be1af35 100644
--- a/infra/git_mirror_bot/Makefile
+++ b/infra/git_mirror_bot/Makefile
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-PROJECT="perfetto-ci"
-VM_NAME="perfetto-ci-git-mirror-bot"
+PROJECT="perfetto-aosp-to-github-bot"
+VM_NAME="perfetto-aosp-to-github-bot"
ZONE="us-central1-c"
ssh:
@@ -26,23 +26,19 @@
instances delete $(VM_NAME) \
--zone $(ZONE)
-deploy_key:
- @echo "Download the deploy_key from the teams drive (go/perfetto_deploy_key)"
- @exit 1
-
-start: deploy_key
+start:
gcloud compute \
--project $(PROJECT) \
instances create $(VM_NAME) \
--zone $(ZONE) \
- --machine-type "n1-highcpu-16" \
+ --machine-type "n1-standard-2" \
--subnet "default" \
--maintenance-policy "MIGRATE" \
- --image "debian-9-stretch-v20170918" \
- --image-project "debian-cloud" \
+ --image "debian-9-drawfork-v20191004" \
+ --image-project "eip-images" \
--boot-disk-size "10" \
--boot-disk-type "pd-standard" \
--boot-disk-device-name "perfetto-ci-git-mirror-bot" \
- --metadata-from-file=startup-script=startup-script.sh,deploy_key=deploy_key,main=mirror_aosp_to_ghub_repo.py
+ --metadata-from-file=startup-script=startup-script.sh,main=mirror_aosp_to_ghub_repo.py
.PHONY: ssh stop start
diff --git a/infra/git_mirror_bot/mirror_aosp_to_ghub_repo.py b/infra/git_mirror_bot/mirror_aosp_to_ghub_repo.py
index fa17382..e254014 100644
--- a/infra/git_mirror_bot/mirror_aosp_to_ghub_repo.py
+++ b/infra/git_mirror_bot/mirror_aosp_to_ghub_repo.py
@@ -34,14 +34,14 @@
CUR_DIR = os.path.dirname(os.path.abspath(__file__))
GIT_UPSTREAM = 'https://android.googlesource.com/platform/external/perfetto/'
-GIT_MIRROR = 'git@github.com:catapult-project/perfetto.git'
+GIT_MIRROR = 'git@github.com:google/perfetto.git'
WORKDIR = os.path.join(CUR_DIR, 'repo')
# Min delay (in seconds) between two consecutive git poll cycles. This is to
# avoid hitting gerrit API quota limits.
POLL_PERIOD_SEC = 60
-# The actual deploy_key is stored into the internal team drive, undef /infra/.
+# The actual key is stored into the Google Cloud project metadata.
ENV = {'GIT_SSH_COMMAND': 'ssh -i ' + os.path.join(CUR_DIR, 'deploy_key')}
@@ -68,7 +68,11 @@
os.makedirs(WORKDIR)
GitCmd('init', '--bare', '--quiet')
GitCmd('remote', 'add', 'upstream', GIT_UPSTREAM)
- GitCmd('config', 'remote.upstream.fetch', '+refs/*:refs/remotes/upstream/*')
+ GitCmd('config', 'remote.upstream.tagOpt', '--no-tags')
+ GitCmd('config', '--add', 'remote.upstream.fetch',
+ '+refs/heads/*:refs/remotes/upstream/heads/*')
+ GitCmd('config', '--add', 'remote.upstream.fetch',
+ '+refs/tags/*:refs/remotes/upstream/tags/*')
GitCmd('remote', 'add', 'mirror', GIT_MIRROR, '--mirror=fetch')
@@ -90,16 +94,17 @@
for line in all_refs.splitlines():
ref_sha1, ref = line.split()
- PREFIX = 'refs/heads/'
- if ref.startswith(PREFIX):
- branch = ref[len(PREFIX):]
- current_heads['refs/heads/' + branch] = ref_sha1
+ FILTER_REGEX = r'(heads/master|heads/releases/.*|tags/v\d+\.\d+)$'
+ m = re.match('refs/' + FILTER_REGEX, ref)
+ if m is not None:
+ branch = m.group(1)
+ current_heads['refs/' + branch] = ref_sha1
continue
- PREFIX = 'refs/remotes/upstream/heads/'
- if ref.startswith(PREFIX):
- branch = ref[len(PREFIX):]
- future_heads['refs/heads/' + branch] = ref_sha1
+ m = re.match('refs/remotes/upstream/' + FILTER_REGEX, ref)
+ if m is not None:
+ branch = m.group(1)
+ future_heads['refs/' + branch] = ref_sha1
continue
deleted_heads = set(current_heads) - set(future_heads)
@@ -121,7 +126,7 @@
if args.push:
logging.info('Pushing updates')
- GitCmd('push', 'mirror', '--all', '--prune', '--force')
+ GitCmd('push', 'mirror', '--all', '--prune', '--force', '--follow-tags')
GitCmd('gc', '--prune=all', '--aggressive', '--quiet')
else:
logging.info('Dry-run mode, skipping git push. Pass --push for prod mode.')
diff --git a/infra/git_mirror_bot/startup-script.sh b/infra/git_mirror_bot/startup-script.sh
index cba2d93..2ae7143 100644
--- a/infra/git_mirror_bot/startup-script.sh
+++ b/infra/git_mirror_bot/startup-script.sh
@@ -39,7 +39,8 @@
redirect_stderr=true
EOF
-curl -H Metadata-Flavor:Google "http://metadata.google.internal/computeMetadata/v1/instance/attributes/deploy_key" > /home/gitbot/deploy_key
+curl -H Metadata-Flavor:Google "http://metadata.google.internal/computeMetadata/v1/project/attributes/deploy_key" > /home/gitbot/deploy_key
+echo >> /home/gitbot/deploy_key # metadata server strips trailing \n.
chown gitbot /home/gitbot/deploy_key
chmod 400 /home/gitbot/deploy_key
@@ -50,8 +51,3 @@
cd /home/gitbot
sudo -u gitbot bash -c "mkdir -p .ssh; ssh-keyscan github.com >> .ssh/known_hosts;"
/usr/bin/supervisord -c /etc/supervisord.conf
-
-dd if=/dev/zero of=/swap bs=1M count=4k
-chmod 600 /swap
-mkswap /swap
-swapon /swap
diff --git a/infra/perfetto-site.appspot.com/index.yaml b/infra/perfetto-site.appspot.com/index.yaml
new file mode 100644
index 0000000..eb9fd6f
--- /dev/null
+++ b/infra/perfetto-site.appspot.com/index.yaml
@@ -0,0 +1,16 @@
+# 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.
+
+indexes:
+# AUTOGENERATED
diff --git a/infra/perfetto-site.appspot.com/main.py b/infra/perfetto-site.appspot.com/main.py
index b42dd96..4a3618a 100644
--- a/infra/perfetto-site.appspot.com/main.py
+++ b/infra/perfetto-site.appspot.com/main.py
@@ -19,7 +19,7 @@
import webapp2
MEMCACHE_TTL_SEC = 60 * 60 * 24
-BASE = 'https://catapult-project.github.io/perfetto/%s'
+BASE = 'https://google.github.io/perfetto/%s'
HEADERS = {
'last-modified', 'content-type', 'content-length', 'content-encoding',
'etag'
diff --git a/src/protozero/BUILD.gn b/src/protozero/BUILD.gn
index 3161670..e4cbd82 100644
--- a/src/protozero/BUILD.gn
+++ b/src/protozero/BUILD.gn
@@ -20,12 +20,12 @@
source_set("protozero") {
public_configs = [ "../../gn:default_config" ]
public_deps = [
+ "../../include/perfetto/base",
"../../include/perfetto/protozero",
]
deps = [
"../../gn:default_deps",
- "../../include/perfetto/base",
- "../../include/perfetto/ext/base", # TODO(primiano): remove this
+ "../base",
]
sources = [
"field.cc",
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index fe0a7ea..1051a81 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -77,6 +77,7 @@
"heap_profile_tracker.cc",
"heap_profile_tracker.h",
"importers/ftrace/ftrace_descriptors.h",
+ "importers/ftrace/ftrace_module.cc",
"importers/ftrace/ftrace_module.h",
"importers/ftrace/ftrace_parser.h",
"importers/ftrace/ftrace_tokenizer.h",
@@ -102,6 +103,7 @@
"importers/proto/proto_trace_tokenizer.h",
"importers/proto/system_probes_module.h",
"importers/proto/system_probes_parser.h",
+ "importers/proto/track_event_module.cc",
"importers/proto/track_event_module.h",
"importers/proto/track_event_parser.cc",
"importers/proto/track_event_parser.h",
@@ -177,6 +179,7 @@
if (enable_perfetto_trace_processor_ftrace) {
sources += [
"importers/ftrace/ftrace_descriptors.cc",
+ "importers/ftrace/ftrace_module_impl.cc",
"importers/ftrace/ftrace_parser.cc",
"importers/ftrace/ftrace_tokenizer.cc",
"importers/ftrace/sched_event_tracker.cc",
@@ -189,11 +192,17 @@
sources += [ "ftrace_utils.cc" ]
}
if (enable_perfetto_trace_processor_system_probes) {
- sources += [ "importers/proto/system_probes_parser.cc" ]
+ sources += [
+ "importers/proto/system_probes_module.cc",
+ "importers/proto/system_probes_parser.cc",
+ ]
deps += [ "../../include/perfetto/ext/traced:sys_stats_counters" ]
}
if (enable_perfetto_trace_processor_android_probes) {
- sources += [ "importers/proto/android_probes_parser.cc" ]
+ sources += [
+ "importers/proto/android_probes_module.cc",
+ "importers/proto/android_probes_parser.cc",
+ ]
}
if (enable_perfetto_trace_processor_heap_graphs) {
sources += [
@@ -276,8 +285,6 @@
"row_iterators.cc",
"row_iterators.h",
"sched_slice_table.h",
- "slice_table.cc",
- "slice_table.h",
"span_join_operator_table.cc",
"span_join_operator_table.h",
"sql_stats_table.cc",
diff --git a/src/trace_processor/args_tracker.cc b/src/trace_processor/args_tracker.cc
index c3e1bca..a28336c 100644
--- a/src/trace_processor/args_tracker.cc
+++ b/src/trace_processor/args_tracker.cc
@@ -79,7 +79,7 @@
storage->mutable_instants()->set_arg_set_id(row, set_id);
break;
case TableId::kNestableSlices:
- storage->mutable_nestable_slices()->set_arg_set_id(row, set_id);
+ storage->mutable_slice_table()->mutable_arg_set_id()->Set(row, set_id);
break;
// Special case: overwrites the metadata table row.
case TableId::kMetadataTable:
diff --git a/src/trace_processor/db/column.cc b/src/trace_processor/db/column.cc
index b957d3d..e06258c 100644
--- a/src/trace_processor/db/column.cc
+++ b/src/trace_processor/db/column.cc
@@ -21,6 +21,35 @@
namespace perfetto {
namespace trace_processor {
+namespace {
+
+// This code mathces the behaviour of sqlite3IntFloatCompare to ensure that
+// we are consistent with SQLite.
+int CompareIntToDouble(int64_t i, double d) {
+ // First check if we are out of range for a int64_t. We use the constants
+ // directly instead of using numeric_limits as the casts introduces rounding
+ // in the doubles as a double cannot exactly represent int64::max().
+ if (d >= 9223372036854775808.0)
+ return -1;
+ if (d < -9223372036854775808.0)
+ return 1;
+
+ // Then, try to compare in int64 space to try and keep as much precision as
+ // possible.
+ int64_t d_i = static_cast<int64_t>(d);
+ if (i < d_i)
+ return -1;
+ if (i > d_i)
+ return 1;
+
+ // Finally, try and compare in double space, sacrificing precision if
+ // necessary.
+ double i_d = static_cast<double>(i);
+ return (i_d < d) ? -1 : (i_d > d ? 1 : 0);
+}
+
+} // namespace
+
Column::Column(const Column& column,
Table* table,
uint32_t col_idx,
@@ -54,6 +83,386 @@
col_idx, row_map_idx, nullptr);
}
+void Column::StableSort(bool desc, std::vector<uint32_t>* idx) const {
+ if (desc) {
+ StableSort<true /* desc */>(idx);
+ } else {
+ StableSort<false /* desc */>(idx);
+ }
+}
+
+void Column::FilterIntoSlow(FilterOp op, SqlValue value, RowMap* rm) const {
+ switch (type_) {
+ case ColumnType::kInt32: {
+ if (IsNullable()) {
+ FilterIntoNumericSlow<int32_t, true /* is_nullable */>(op, value, rm);
+ } else {
+ FilterIntoNumericSlow<int32_t, false /* is_nullable */>(op, value, rm);
+ }
+ break;
+ }
+ case ColumnType::kUint32: {
+ if (IsNullable()) {
+ FilterIntoNumericSlow<uint32_t, true /* is_nullable */>(op, value, rm);
+ } else {
+ FilterIntoNumericSlow<uint32_t, false /* is_nullable */>(op, value, rm);
+ }
+ break;
+ }
+ case ColumnType::kInt64: {
+ if (IsNullable()) {
+ FilterIntoNumericSlow<int64_t, true /* is_nullable */>(op, value, rm);
+ } else {
+ FilterIntoNumericSlow<int64_t, false /* is_nullable */>(op, value, rm);
+ }
+ break;
+ }
+ case ColumnType::kDouble: {
+ if (IsNullable()) {
+ FilterIntoNumericSlow<double, true /* is_nullable */>(op, value, rm);
+ } else {
+ FilterIntoNumericSlow<double, false /* is_nullable */>(op, value, rm);
+ }
+ break;
+ }
+ case ColumnType::kString: {
+ FilterIntoStringSlow(op, value, rm);
+ break;
+ }
+ case ColumnType::kId: {
+ FilterIntoIdSlow(op, value, rm);
+ break;
+ }
+ }
+}
+
+template <typename T, bool is_nullable>
+void Column::FilterIntoNumericSlow(FilterOp op,
+ SqlValue value,
+ RowMap* rm) const {
+ PERFETTO_DCHECK(IsNullable() == is_nullable);
+ PERFETTO_DCHECK(type_ == ToColumnType<T>());
+ PERFETTO_DCHECK(std::is_arithmetic<T>::value);
+
+ if (op == FilterOp::kIsNull) {
+ PERFETTO_DCHECK(value.is_null());
+ if (is_nullable) {
+ row_map().FilterInto(rm, [this](uint32_t row) {
+ return !sparse_vector<T>().Get(row).has_value();
+ });
+ } else {
+ rm->Intersect(RowMap());
+ }
+ return;
+ } else if (op == FilterOp::kIsNotNull) {
+ PERFETTO_DCHECK(value.is_null());
+ if (is_nullable) {
+ row_map().FilterInto(rm, [this](uint32_t row) {
+ return sparse_vector<T>().Get(row).has_value();
+ });
+ }
+ return;
+ }
+
+ if (value.type == SqlValue::Type::kDouble) {
+ double double_value = value.double_value;
+ if (std::is_same<T, double>::value) {
+ auto fn = [double_value](T v) {
+ return v < double_value ? -1 : (v > double_value ? 1 : 0);
+ };
+ FilterIntoNumericWithComparatorSlow<T, is_nullable>(op, rm, fn);
+ } else {
+ auto fn = [double_value](T v) {
+ // We static cast here as this code will be compiled even when T ==
+ // double as we don't have if constexpr in C++11. In reality the cast is
+ // a noop but we cannot statically verify that for the compiler.
+ return CompareIntToDouble(static_cast<int64_t>(v), double_value);
+ };
+ FilterIntoNumericWithComparatorSlow<T, is_nullable>(op, rm, fn);
+ }
+ } else if (value.type == SqlValue::Type::kLong) {
+ int64_t long_value = value.long_value;
+ if (std::is_same<T, double>::value) {
+ auto fn = [long_value](T v) {
+ // We negate the return value as the long is always the first parameter
+ // for this function even though the LHS of the comparator should
+ // actually be |v|. This saves us having a duplicate implementation of
+ // the comparision function.
+ return -CompareIntToDouble(long_value, v);
+ };
+ FilterIntoNumericWithComparatorSlow<T, is_nullable>(op, rm, fn);
+ } else {
+ auto fn = [long_value](T v) {
+ return v < long_value ? -1 : (v > long_value ? 1 : 0);
+ };
+ FilterIntoNumericWithComparatorSlow<T, is_nullable>(op, rm, fn);
+ }
+ } else {
+ rm->Intersect(RowMap());
+ }
+}
+
+template <typename T, bool is_nullable, typename Comparator>
+void Column::FilterIntoNumericWithComparatorSlow(FilterOp op,
+ RowMap* rm,
+ Comparator cmp) const {
+ switch (op) {
+ case FilterOp::kLt:
+ row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
+ if (is_nullable) {
+ auto opt_value = sparse_vector<T>().Get(idx);
+ return opt_value && cmp(*opt_value) < 0;
+ }
+ return cmp(sparse_vector<T>().GetNonNull(idx)) < 0;
+ });
+ break;
+ case FilterOp::kEq:
+ row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
+ if (is_nullable) {
+ auto opt_value = sparse_vector<T>().Get(idx);
+ return opt_value && cmp(*opt_value) == 0;
+ }
+ return cmp(sparse_vector<T>().GetNonNull(idx)) == 0;
+ });
+ break;
+ case FilterOp::kGt:
+ row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
+ if (is_nullable) {
+ auto opt_value = sparse_vector<T>().Get(idx);
+ return opt_value && cmp(*opt_value) > 0;
+ }
+ return cmp(sparse_vector<T>().GetNonNull(idx)) > 0;
+ });
+ break;
+ case FilterOp::kNe:
+ row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
+ if (is_nullable) {
+ auto opt_value = sparse_vector<T>().Get(idx);
+ return opt_value && cmp(*opt_value) != 0;
+ }
+ return cmp(sparse_vector<T>().GetNonNull(idx)) != 0;
+ });
+ break;
+ case FilterOp::kLe:
+ row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
+ if (is_nullable) {
+ auto opt_value = sparse_vector<T>().Get(idx);
+ return opt_value && cmp(*opt_value) <= 0;
+ }
+ return cmp(sparse_vector<T>().GetNonNull(idx)) <= 0;
+ });
+ break;
+ case FilterOp::kGe:
+ row_map().FilterInto(rm, [this, &cmp](uint32_t idx) {
+ if (is_nullable) {
+ auto opt_value = sparse_vector<T>().Get(idx);
+ return opt_value && cmp(*opt_value) >= 0;
+ }
+ return cmp(sparse_vector<T>().GetNonNull(idx)) >= 0;
+ });
+ break;
+ case FilterOp::kLike:
+ rm->Intersect(RowMap());
+ break;
+ case FilterOp::kIsNull:
+ case FilterOp::kIsNotNull:
+ PERFETTO_FATAL("Should be handled above");
+ }
+}
+
+void Column::FilterIntoStringSlow(FilterOp op,
+ SqlValue value,
+ RowMap* rm) const {
+ PERFETTO_DCHECK(type_ == ColumnType::kString);
+
+ if (op == FilterOp::kIsNull) {
+ PERFETTO_DCHECK(value.is_null());
+ row_map().FilterInto(rm, [this](uint32_t row) {
+ return GetStringPoolStringAtIdx(row).data() == nullptr;
+ });
+ return;
+ } else if (op == FilterOp::kIsNotNull) {
+ PERFETTO_DCHECK(value.is_null());
+ row_map().FilterInto(rm, [this](uint32_t row) {
+ return GetStringPoolStringAtIdx(row).data() != nullptr;
+ });
+ return;
+ }
+
+ if (value.type != SqlValue::Type::kString) {
+ rm->Intersect(RowMap());
+ return;
+ }
+
+ NullTermStringView str_value = value.string_value;
+ switch (op) {
+ case FilterOp::kLt:
+ row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
+ auto v = GetStringPoolStringAtIdx(idx);
+ return v.data() != nullptr && v < str_value;
+ });
+ break;
+ case FilterOp::kEq:
+ row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
+ auto v = GetStringPoolStringAtIdx(idx);
+ return v.data() != nullptr && v == str_value;
+ });
+ break;
+ case FilterOp::kGt:
+ row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
+ auto v = GetStringPoolStringAtIdx(idx);
+ return v.data() != nullptr && v > str_value;
+ });
+ break;
+ case FilterOp::kNe:
+ row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
+ auto v = GetStringPoolStringAtIdx(idx);
+ return v.data() != nullptr && v != str_value;
+ });
+ break;
+ case FilterOp::kLe:
+ row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
+ auto v = GetStringPoolStringAtIdx(idx);
+ return v.data() != nullptr && v <= str_value;
+ });
+ break;
+ case FilterOp::kGe:
+ row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
+ auto v = GetStringPoolStringAtIdx(idx);
+ return v.data() != nullptr && v >= str_value;
+ });
+ break;
+ case FilterOp::kLike:
+ // TODO(lalitm): either call through to SQLite or reimplement
+ // like ourselves.
+ PERFETTO_DLOG("Ignoring like constraint on string column");
+ break;
+ case FilterOp::kIsNull:
+ case FilterOp::kIsNotNull:
+ PERFETTO_FATAL("Should be handled above");
+ }
+}
+
+void Column::FilterIntoIdSlow(FilterOp op, SqlValue value, RowMap* rm) const {
+ PERFETTO_DCHECK(type_ == ColumnType::kId);
+
+ if (op == FilterOp::kIsNull) {
+ PERFETTO_DCHECK(value.is_null());
+ rm->Intersect(RowMap());
+ return;
+ } else if (op == FilterOp::kIsNotNull) {
+ PERFETTO_DCHECK(value.is_null());
+ return;
+ }
+
+ if (value.type != SqlValue::Type::kLong) {
+ rm->Intersect(RowMap());
+ return;
+ }
+
+ uint32_t id_value = static_cast<uint32_t>(value.long_value);
+ switch (op) {
+ case FilterOp::kLt:
+ row_map().FilterInto(rm,
+ [id_value](uint32_t idx) { return idx < id_value; });
+ break;
+ case FilterOp::kEq:
+ row_map().FilterInto(
+ rm, [id_value](uint32_t idx) { return idx == id_value; });
+ break;
+ case FilterOp::kGt:
+ row_map().FilterInto(rm,
+ [id_value](uint32_t idx) { return idx > id_value; });
+ break;
+ case FilterOp::kNe:
+ row_map().FilterInto(
+ rm, [id_value](uint32_t idx) { return idx != id_value; });
+ break;
+ case FilterOp::kLe:
+ row_map().FilterInto(
+ rm, [id_value](uint32_t idx) { return idx <= id_value; });
+ break;
+ case FilterOp::kGe:
+ row_map().FilterInto(
+ rm, [id_value](uint32_t idx) { return idx >= id_value; });
+ break;
+ case FilterOp::kLike:
+ rm->Intersect(RowMap());
+ break;
+ case FilterOp::kIsNull:
+ case FilterOp::kIsNotNull:
+ PERFETTO_FATAL("Should be handled above");
+ }
+}
+
+template <bool desc>
+void Column::StableSort(std::vector<uint32_t>* out) const {
+ switch (type_) {
+ case ColumnType::kInt32: {
+ if (IsNullable()) {
+ StableSort<desc, int32_t, true /* is_nullable */>(out);
+ } else {
+ StableSort<desc, int32_t, false /* is_nullable */>(out);
+ }
+ break;
+ }
+ case ColumnType::kUint32: {
+ if (IsNullable()) {
+ StableSort<desc, uint32_t, true /* is_nullable */>(out);
+ } else {
+ StableSort<desc, uint32_t, false /* is_nullable */>(out);
+ }
+ break;
+ }
+ case ColumnType::kInt64: {
+ if (IsNullable()) {
+ StableSort<desc, int64_t, true /* is_nullable */>(out);
+ } else {
+ StableSort<desc, int64_t, false /* is_nullable */>(out);
+ }
+ break;
+ }
+ case ColumnType::kDouble: {
+ if (IsNullable()) {
+ StableSort<desc, double, true /* is_nullable */>(out);
+ } else {
+ StableSort<desc, double, false /* is_nullable */>(out);
+ }
+ break;
+ }
+ case ColumnType::kString: {
+ row_map().StableSort(out, [this](uint32_t a_idx, uint32_t b_idx) {
+ auto a_str = GetStringPoolStringAtIdx(a_idx);
+ auto b_str = GetStringPoolStringAtIdx(b_idx);
+ return desc ? b_str < a_str : a_str < b_str;
+ });
+ break;
+ }
+ case ColumnType::kId:
+ row_map().StableSort(out, [](uint32_t a_idx, uint32_t b_idx) {
+ return desc ? b_idx < a_idx : a_idx < b_idx;
+ });
+ }
+}
+
+template <bool desc, typename T, bool is_nullable>
+void Column::StableSort(std::vector<uint32_t>* out) const {
+ PERFETTO_DCHECK(IsNullable() == is_nullable);
+ PERFETTO_DCHECK(ToColumnType<T>() == type_);
+
+ const auto& sv = sparse_vector<T>();
+ row_map().StableSort(out, [&sv](uint32_t a_idx, uint32_t b_idx) {
+ if (is_nullable) {
+ auto a_val = sv.Get(a_idx);
+ auto b_val = sv.Get(b_idx);
+ return desc ? b_val < a_val : a_val < b_val;
+ }
+ auto a_val = sv.GetNonNull(a_idx);
+ auto b_val = sv.GetNonNull(b_idx);
+ return desc ? b_val < a_val : a_val < b_val;
+ });
+}
+
const RowMap& Column::row_map() const {
return table_->row_maps_[row_map_idx_];
}
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index 662413c..0117539 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -147,13 +147,7 @@
// 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 {
- if (desc) {
- StableSort<true /* desc */>(idx);
- } else {
- StableSort<false /* desc */>(idx);
- }
- }
+ void StableSort(bool desc, std::vector<uint32_t>* idx) const;
// Updates the given RowMap by only keeping rows where this column meets the
// given filter constraint.
@@ -174,85 +168,12 @@
// If the column is sorted and the value has the same type as the column,
// we should be able to just do a binary search to find the range of rows
// instead of a full table scan.
- const Iterator b(this, 0);
- const Iterator e(this, row_map().size());
- switch (op) {
- case FilterOp::kEq: {
- uint32_t beg = std::distance(b, std::lower_bound(b, e, value));
- uint32_t end = std::distance(b, std::upper_bound(b, e, value));
- rm->Intersect(RowMap(beg, end));
- return;
- }
- case FilterOp::kLe: {
- uint32_t end = std::distance(b, std::upper_bound(b, e, value));
- rm->Intersect(RowMap(0, end));
- return;
- }
- case FilterOp::kLt: {
- uint32_t end = std::distance(b, std::lower_bound(b, e, value));
- rm->Intersect(RowMap(0, end));
- return;
- }
- case FilterOp::kGe: {
- uint32_t beg = std::distance(b, std::lower_bound(b, e, value));
- rm->Intersect(RowMap(beg, row_map().size()));
- return;
- }
- case FilterOp::kGt: {
- uint32_t beg = std::distance(b, std::upper_bound(b, e, value));
- rm->Intersect(RowMap(beg, row_map().size()));
- return;
- }
- case FilterOp::kNe:
- case FilterOp::kIsNull:
- case FilterOp::kIsNotNull:
- case FilterOp::kLike:
- break;
- }
+ bool handled = FilterIntoSorted(op, value, rm);
+ if (handled)
+ return;
}
- switch (type_) {
- case ColumnType::kInt32: {
- if (IsNullable()) {
- FilterIntoLongSlow<int32_t, true /* is_nullable */>(op, value, rm);
- } else {
- FilterIntoLongSlow<int32_t, false /* is_nullable */>(op, value, rm);
- }
- break;
- }
- case ColumnType::kUint32: {
- if (IsNullable()) {
- FilterIntoLongSlow<uint32_t, true /* is_nullable */>(op, value, rm);
- } else {
- FilterIntoLongSlow<uint32_t, false /* is_nullable */>(op, value, rm);
- }
- break;
- }
- case ColumnType::kInt64: {
- if (IsNullable()) {
- FilterIntoLongSlow<int64_t, true /* is_nullable */>(op, value, rm);
- } else {
- FilterIntoLongSlow<int64_t, false /* is_nullable */>(op, value, rm);
- }
- break;
- }
- case ColumnType::kDouble: {
- if (IsNullable()) {
- FilterIntoDoubleSlow<true /* is_nullable */>(op, value, rm);
- } else {
- FilterIntoDoubleSlow<false /* is_nullable */>(op, value, rm);
- }
- break;
- }
- case ColumnType::kString: {
- FilterIntoStringSlow(op, value, rm);
- break;
- }
- case ColumnType::kId: {
- FilterIntoIdSlow(op, value, rm);
- break;
- }
- }
+ FilterIntoSlow(op, value, rm);
}
// Returns true if this column is considered an id column.
@@ -264,8 +185,15 @@
// Returns true if this column is a sorted column.
bool IsSorted() const { return (flags_ & Flag::kSorted) != 0; }
+ // Returns the backing RowMap for this Column.
+ // This function is defined out of line because of a circular dependency
+ // between |Table| and |Column|.
const RowMap& row_map() const;
+
+ // Returns the name of the column.
const char* name() const { return name_; }
+
+ // Returns the type of this Column in terms of SqlValue::Type.
SqlValue::Type type() const {
switch (type_) {
case ColumnType::kInt32:
@@ -318,22 +246,30 @@
JoinKey join_key() const { return JoinKey{col_idx_in_table_}; }
protected:
+ // Returns the string at the index |idx|.
+ // Should only be called when |type_| == ColumnType::kString.
NullTermStringView GetStringPoolStringAtIdx(uint32_t idx) const {
+ PERFETTO_DCHECK(type_ == ColumnType::kString);
return string_pool_->Get(sparse_vector<StringPool::Id>().GetNonNull(idx));
}
+ // Returns the backing sparse vector cast to contain data of type T.
+ // Should only be called when |type_| == ToColumnType<T>().
template <typename T>
SparseVector<T>* mutable_sparse_vector() {
PERFETTO_DCHECK(ToColumnType<T>() == type_);
return static_cast<SparseVector<T>*>(sparse_vector_);
}
+ // Returns the backing sparse vector cast to contain data of type T.
+ // Should only be called when |type_| == ToColumnType<T>().
template <typename T>
const SparseVector<T>& sparse_vector() const {
PERFETTO_DCHECK(ToColumnType<T>() == type_);
return *static_cast<const SparseVector<T>*>(sparse_vector_);
}
+ // Converts a primitive numeric value to an SqlValue of the correct type.
template <typename T>
static SqlValue NumericToSqlValue(T value) {
if (std::is_same<T, double>::value) {
@@ -402,6 +338,7 @@
friend class Table;
+ // Base constructor for this class which all other constructors call into.
Column(const char* name,
ColumnType type,
uint32_t flags,
@@ -442,377 +379,78 @@
PERFETTO_FATAL("For GCC");
}
+ // Optimized filter method for sorted columns.
+ // Returns whether the constraint was handled by the method.
+ bool FilterIntoSorted(FilterOp op, SqlValue value, RowMap* rm) const {
+ PERFETTO_DCHECK(IsSorted());
+ PERFETTO_DCHECK(value.type == type());
+
+ Iterator b(this, 0);
+ Iterator e(this, row_map().size());
+ switch (op) {
+ case FilterOp::kEq: {
+ uint32_t beg = std::distance(b, std::lower_bound(b, e, value));
+ uint32_t end = std::distance(b, std::upper_bound(b, e, value));
+ rm->Intersect(RowMap(beg, end));
+ return true;
+ }
+ case FilterOp::kLe: {
+ uint32_t end = std::distance(b, std::upper_bound(b, e, value));
+ rm->Intersect(RowMap(0, end));
+ return true;
+ }
+ case FilterOp::kLt: {
+ uint32_t end = std::distance(b, std::lower_bound(b, e, value));
+ rm->Intersect(RowMap(0, end));
+ return true;
+ }
+ case FilterOp::kGe: {
+ uint32_t beg = std::distance(b, std::lower_bound(b, e, value));
+ rm->Intersect(RowMap(beg, row_map().size()));
+ return true;
+ }
+ case FilterOp::kGt: {
+ uint32_t beg = std::distance(b, std::upper_bound(b, e, value));
+ rm->Intersect(RowMap(beg, row_map().size()));
+ return true;
+ }
+ case FilterOp::kNe:
+ case FilterOp::kIsNull:
+ case FilterOp::kIsNotNull:
+ case FilterOp::kLike:
+ break;
+ }
+ return false;
+ }
+
+ // Slow path filter method which will perform a full table scan.
+ void FilterIntoSlow(FilterOp op, SqlValue value, RowMap* rm) const;
+
+ // Slow path filter method for numerics which will perform a full table scan.
template <typename T, bool is_nullable>
- void FilterIntoLongSlow(FilterOp op, SqlValue value, RowMap* rm) const {
- if (op == FilterOp::kIsNull) {
- PERFETTO_DCHECK(value.is_null());
- if (is_nullable) {
- row_map().FilterInto(rm, [this](uint32_t row) {
- return !sparse_vector<T>().Get(row).has_value();
- });
- } else {
- rm->Intersect(RowMap());
- }
- return;
- } else if (op == FilterOp::kIsNotNull) {
- PERFETTO_DCHECK(value.is_null());
- if (is_nullable) {
- row_map().FilterInto(rm, [this](uint32_t row) {
- return sparse_vector<T>().Get(row).has_value();
- });
- }
- return;
- }
+ void FilterIntoNumericSlow(FilterOp op, SqlValue value, RowMap* rm) const;
- if (value.type != SqlValue::Type::kLong) {
- rm->Intersect(RowMap());
- return;
- }
+ // Slow path filter method for numerics with a comparator which will perform a
+ // full table scan.
+ template <typename T, bool is_nullable, typename Comparator = int(T)>
+ void FilterIntoNumericWithComparatorSlow(FilterOp op,
+ RowMap* rm,
+ Comparator cmp) const;
- int64_t long_value = value.long_value;
- switch (op) {
- case FilterOp::kLt:
- row_map().FilterInto(rm, [this, long_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<T>().Get(idx);
- return opt_value && *opt_value < long_value;
- }
- return sparse_vector<T>().GetNonNull(idx) < long_value;
- });
- break;
- case FilterOp::kEq:
- row_map().FilterInto(rm, [this, long_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<T>().Get(idx);
- return opt_value && opt_value == long_value;
- }
- return sparse_vector<T>().GetNonNull(idx) == long_value;
- });
- break;
- case FilterOp::kGt:
- row_map().FilterInto(rm, [this, long_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<T>().Get(idx);
- return opt_value && opt_value > long_value;
- }
- return sparse_vector<T>().GetNonNull(idx) > long_value;
- });
- break;
- case FilterOp::kNe:
- row_map().FilterInto(rm, [this, long_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<T>().Get(idx);
- return opt_value && opt_value != long_value;
- }
- return sparse_vector<T>().GetNonNull(idx) != long_value;
- });
- break;
- case FilterOp::kLe:
- row_map().FilterInto(rm, [this, long_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<T>().Get(idx);
- return opt_value && opt_value <= long_value;
- }
- return sparse_vector<T>().GetNonNull(idx) <= long_value;
- });
- break;
- case FilterOp::kGe:
- row_map().FilterInto(rm, [this, long_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<T>().Get(idx);
- return opt_value && opt_value >= long_value;
- }
- return sparse_vector<T>().GetNonNull(idx) >= long_value;
- });
- break;
- case FilterOp::kLike:
- rm->Intersect(RowMap());
- break;
- case FilterOp::kIsNull:
- case FilterOp::kIsNotNull:
- PERFETTO_FATAL("Should be handled above");
- }
- }
+ // Slow path filter method for strings which will perform a full table scan.
+ void FilterIntoStringSlow(FilterOp op, SqlValue value, RowMap* rm) const;
- template <bool is_nullable>
- void FilterIntoDoubleSlow(FilterOp op, SqlValue value, RowMap* rm) const {
- if (op == FilterOp::kIsNull) {
- PERFETTO_DCHECK(value.is_null());
- if (is_nullable) {
- row_map().FilterInto(rm, [this](uint32_t row) {
- return !sparse_vector<double>().Get(row).has_value();
- });
- } else {
- rm->Intersect(RowMap());
- }
- return;
- } else if (op == FilterOp::kIsNotNull) {
- PERFETTO_DCHECK(value.is_null());
- if (is_nullable) {
- row_map().FilterInto(rm, [this](uint32_t row) {
- return sparse_vector<double>().Get(row).has_value();
- });
- }
- return;
- }
+ // Slow path filter method for ids which will perform a full table scan.
+ void FilterIntoIdSlow(FilterOp op, SqlValue value, RowMap* rm) const;
- if (value.type != SqlValue::Type::kDouble) {
- rm->Intersect(RowMap());
- return;
- }
-
- double double_value = value.double_value;
- switch (op) {
- case FilterOp::kLt:
- row_map().FilterInto(rm, [this, double_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<double>().Get(idx);
- return opt_value && opt_value < double_value;
- }
- return sparse_vector<double>().GetNonNull(idx) < double_value;
- });
- break;
- case FilterOp::kEq:
- row_map().FilterInto(rm, [this, double_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<double>().Get(idx);
- return opt_value &&
- std::equal_to<double>()(*opt_value, double_value);
- }
- auto v = sparse_vector<double>().GetNonNull(idx);
- return std::equal_to<double>()(v, double_value);
- });
- break;
- case FilterOp::kGt:
- row_map().FilterInto(rm, [this, double_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<double>().Get(idx);
- return opt_value && opt_value > double_value;
- }
- return sparse_vector<double>().GetNonNull(idx) > double_value;
- });
- break;
- case FilterOp::kNe:
- row_map().FilterInto(rm, [this, double_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<double>().Get(idx);
- return opt_value &&
- std::not_equal_to<double>()(*opt_value, double_value);
- }
- auto v = sparse_vector<double>().GetNonNull(idx);
- return std::not_equal_to<double>()(v, double_value);
- });
- break;
- case FilterOp::kLe:
- row_map().FilterInto(rm, [this, double_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<double>().Get(idx);
- return opt_value && opt_value <= double_value;
- }
- return sparse_vector<double>().GetNonNull(idx) <= double_value;
- });
- break;
- case FilterOp::kGe:
- row_map().FilterInto(rm, [this, double_value](uint32_t idx) {
- if (is_nullable) {
- auto opt_value = sparse_vector<double>().Get(idx);
- return opt_value && opt_value >= double_value;
- }
- return sparse_vector<double>().GetNonNull(idx) >= double_value;
- });
- break;
- case FilterOp::kLike:
- rm->Intersect(RowMap());
- break;
- case FilterOp::kIsNull:
- case FilterOp::kIsNotNull:
- PERFETTO_FATAL("Should be handled above");
- }
- }
-
- void FilterIntoStringSlow(FilterOp op, SqlValue value, RowMap* rm) const {
- if (op == FilterOp::kIsNull) {
- PERFETTO_DCHECK(value.is_null());
- row_map().FilterInto(rm, [this](uint32_t row) {
- return GetStringPoolStringAtIdx(row).data() == nullptr;
- });
- return;
- } else if (op == FilterOp::kIsNotNull) {
- PERFETTO_DCHECK(value.is_null());
- row_map().FilterInto(rm, [this](uint32_t row) {
- return GetStringPoolStringAtIdx(row).data() != nullptr;
- });
- return;
- }
-
- if (value.type != SqlValue::Type::kString) {
- rm->Intersect(RowMap());
- return;
- }
-
- NullTermStringView str_value = value.string_value;
- switch (op) {
- case FilterOp::kLt:
- row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
- auto v = GetStringPoolStringAtIdx(idx);
- return v.data() != nullptr && v < str_value;
- });
- break;
- case FilterOp::kEq:
- row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
- auto v = GetStringPoolStringAtIdx(idx);
- return v.data() != nullptr && v == str_value;
- });
- break;
- case FilterOp::kGt:
- row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
- auto v = GetStringPoolStringAtIdx(idx);
- return v.data() != nullptr && v > str_value;
- });
- break;
- case FilterOp::kNe:
- row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
- auto v = GetStringPoolStringAtIdx(idx);
- return v.data() != nullptr && v != str_value;
- });
- break;
- case FilterOp::kLe:
- row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
- auto v = GetStringPoolStringAtIdx(idx);
- return v.data() != nullptr && v <= str_value;
- });
- break;
- case FilterOp::kGe:
- row_map().FilterInto(rm, [this, str_value](uint32_t idx) {
- auto v = GetStringPoolStringAtIdx(idx);
- return v.data() != nullptr && v >= str_value;
- });
- break;
- case FilterOp::kLike:
- // TODO(lalitm): either call through to SQLite or reimplement
- // like ourselves.
- PERFETTO_DLOG("Ignoring like constraint on string column");
- break;
- case FilterOp::kIsNull:
- case FilterOp::kIsNotNull:
- PERFETTO_FATAL("Should be handled above");
- }
- }
-
- void FilterIntoIdSlow(FilterOp op, SqlValue value, RowMap* rm) const {
- if (op == FilterOp::kIsNull) {
- PERFETTO_DCHECK(value.is_null());
- rm->Intersect(RowMap());
- return;
- } else if (op == FilterOp::kIsNotNull) {
- PERFETTO_DCHECK(value.is_null());
- return;
- }
-
- if (value.type != SqlValue::Type::kLong) {
- rm->Intersect(RowMap());
- return;
- }
-
- uint32_t id_value = static_cast<uint32_t>(value.long_value);
- switch (op) {
- case FilterOp::kLt:
- row_map().FilterInto(
- rm, [id_value](uint32_t idx) { return idx < id_value; });
- break;
- case FilterOp::kEq:
- row_map().FilterInto(
- rm, [id_value](uint32_t idx) { return idx == id_value; });
- break;
- case FilterOp::kGt:
- row_map().FilterInto(
- rm, [id_value](uint32_t idx) { return idx > id_value; });
- break;
- case FilterOp::kNe:
- row_map().FilterInto(
- rm, [id_value](uint32_t idx) { return idx != id_value; });
- break;
- case FilterOp::kLe:
- row_map().FilterInto(
- rm, [id_value](uint32_t idx) { return idx <= id_value; });
- break;
- case FilterOp::kGe:
- row_map().FilterInto(
- rm, [id_value](uint32_t idx) { return idx >= id_value; });
- break;
- case FilterOp::kLike:
- rm->Intersect(RowMap());
- break;
- case FilterOp::kIsNull:
- case FilterOp::kIsNotNull:
- PERFETTO_FATAL("Should be handled above");
- }
- }
-
+ // Stable sorts this column storing the result in |out|.
template <bool desc>
- void StableSort(std::vector<uint32_t>* out) const {
- switch (type_) {
- case ColumnType::kInt32: {
- if (IsNullable()) {
- StableSort<desc, int32_t, true /* is_nullable */>(out);
- } else {
- StableSort<desc, int32_t, false /* is_nullable */>(out);
- }
- break;
- }
- case ColumnType::kUint32: {
- if (IsNullable()) {
- StableSort<desc, uint32_t, true /* is_nullable */>(out);
- } else {
- StableSort<desc, uint32_t, false /* is_nullable */>(out);
- }
- break;
- }
- case ColumnType::kInt64: {
- if (IsNullable()) {
- StableSort<desc, int64_t, true /* is_nullable */>(out);
- } else {
- StableSort<desc, int64_t, false /* is_nullable */>(out);
- }
- break;
- }
- case ColumnType::kDouble: {
- if (IsNullable()) {
- StableSort<desc, double, true /* is_nullable */>(out);
- } else {
- StableSort<desc, double, false /* is_nullable */>(out);
- }
- break;
- }
- case ColumnType::kString: {
- row_map().StableSort(out, [this](uint32_t a_idx, uint32_t b_idx) {
- auto a_str = GetStringPoolStringAtIdx(a_idx);
- auto b_str = GetStringPoolStringAtIdx(b_idx);
- return desc ? b_str < a_str : a_str < b_str;
- });
- break;
- }
- case ColumnType::kId:
- row_map().StableSort(out, [](uint32_t a_idx, uint32_t b_idx) {
- return desc ? b_idx < a_idx : a_idx < b_idx;
- });
- }
- }
+ void StableSort(std::vector<uint32_t>* out) const;
+ // Stable sorts this column storing the result in |out|.
+ // |T| and |is_nullable| should match the type and nullability of this column.
template <bool desc, typename T, bool is_nullable>
- void StableSort(std::vector<uint32_t>* out) const {
- const auto& sv = sparse_vector<T>();
- row_map().StableSort(out, [&sv](uint32_t a_idx, uint32_t b_idx) {
- if (is_nullable) {
- auto a_val = sv.Get(a_idx);
- auto b_val = sv.Get(b_idx);
- return desc ? b_val < a_val : a_val < b_val;
- }
- auto a_val = sv.GetNonNull(a_idx);
- auto b_val = sv.GetNonNull(b_idx);
- return desc ? b_val < a_val : a_val < b_val;
- });
- }
+ void StableSort(std::vector<uint32_t>* out) const;
template <typename T>
static ColumnType ToColumnType() {
diff --git a/src/trace_processor/export_json.cc b/src/trace_processor/export_json.cc
index e7affb4..0ed3e7e 100644
--- a/src/trace_processor/export_json.cc
+++ b/src/trace_processor/export_json.cc
@@ -442,19 +442,19 @@
util::Status ExportSlices(const TraceStorage* storage,
const ArgsBuilder& args_builder,
TraceFormatWriter* writer) {
- const auto& slices = storage->nestable_slices();
- for (uint32_t i = 0; i < slices.slice_count(); ++i) {
+ const auto& slices = storage->slice_table();
+ for (uint32_t i = 0; i < slices.size(); ++i) {
Json::Value event;
- event["ts"] = Json::Int64(slices.start_ns()[i] / 1000);
- event["cat"] = GetNonNullString(storage, slices.categories()[i]);
- event["name"] = GetNonNullString(storage, slices.names()[i]);
+ event["ts"] = Json::Int64(slices.ts()[i] / 1000);
+ event["cat"] = GetNonNullString(storage, slices.category()[i]);
+ event["name"] = GetNonNullString(storage, slices.name()[i]);
event["pid"] = 0;
event["tid"] = 0;
int32_t legacy_tid = 0;
event["args"] =
- args_builder.GetArgs(slices.arg_set_ids()[i]); // Makes a copy.
+ args_builder.GetArgs(slices.arg_set_id()[i]); // Makes a copy.
if (event["args"].isMember(kLegacyEventArgsKey)) {
ConvertLegacyFlowEventArgs(event["args"][kLegacyEventArgsKey], &event);
@@ -489,7 +489,7 @@
const auto& thread_slices = storage->thread_slices();
const auto& virtual_track_slices = storage->virtual_track_slices();
- int64_t duration_ns = slices.durations()[i];
+ int64_t duration_ns = slices.dur()[i];
int64_t thread_ts_ns = 0;
int64_t thread_duration_ns = 0;
int64_t thread_instruction_count = 0;
@@ -637,8 +637,7 @@
// write the end event in this case.
if (duration_ns > 0) {
event["ph"] = "e";
- event["ts"] =
- Json::Int64((slices.start_ns()[i] + duration_ns) / 1000);
+ event["ts"] = Json::Int64((slices.ts()[i] + duration_ns) / 1000);
if (thread_ts_ns > 0) {
event["tts"] =
Json::Int64((thread_ts_ns + thread_duration_ns) / 1000);
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index 6acfa96..ded2e75 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -119,9 +119,11 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp, kDuration, track, utid, RefType::kRefUtid, cat_id, name_id, 0,
- 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ context_.storage->mutable_slice_table()->Insert({kTimestamp, kDuration, track,
+ utid, ref_type_id, cat_id,
+ name_id, 0, 0, 0});
context_.storage->mutable_thread_slices()->AddThreadSlice(
0, kThreadTimestamp, kThreadDuration, kThreadInstructionCount,
kThreadInstructionDelta);
@@ -167,9 +169,11 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp, kDuration, track, utid, RefType::kRefUtid, cat_id, name_id, 0,
- 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ context_.storage->mutable_slice_table()->Insert({kTimestamp, kDuration, track,
+ utid, ref_type_id, cat_id,
+ name_id, 0, 0, 0});
context_.storage->mutable_thread_slices()->AddThreadSlice(
0, kThreadTimestamp, kThreadDuration, kThreadInstructionCount,
kThreadInstructionDelta);
@@ -230,8 +234,10 @@
StringId cat_id = context_.storage->InternString("cat");
StringId name_id = context_.storage->InternString("name");
- context_.storage->mutable_nestable_slices()->AddSlice(
- 0, 0, track, track, RefType::kRefTrack, cat_id, name_id, 0, 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefTrack)]);
+ context_.storage->mutable_slice_table()->Insert(
+ {0, 0, track, track, ref_type_id, cat_id, name_id, 0, 0, 0});
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -402,8 +408,10 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- 0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ context_.storage->mutable_slice_table()->Insert(
+ {0, 0, track, utid, ref_type_id, cat_id, name_id, 0, 0, 0});
StringId arg_key_id = context_.storage->InternString(
base::StringView("task.posted_from.file_name"));
@@ -414,7 +422,7 @@
arg.key = arg_key_id;
arg.value = Variadic::String(arg_value_id);
ArgSetId args = context_.storage->mutable_args()->AddArgSet({arg}, 0, 1);
- context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
+ context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -447,10 +455,12 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = storage->InternString(base::StringView(kCategory));
StringId name_id = storage->InternString(base::StringView(kName));
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
RowId row_id = TraceStorage::CreateRowId(
kNestableSlices,
- storage->mutable_nestable_slices()->AddSlice(
- 0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0));
+ storage->mutable_slice_table()->Insert(
+ {0, 0, track, utid, ref_type_id, cat_id, name_id, 0, 0, 0}));
auto add_arg = [&](const char* key, Variadic value) {
StringId key_id = storage->InternString(key);
@@ -497,8 +507,10 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- 0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ context_.storage->mutable_slice_table()->Insert(
+ {0, 0, track, utid, ref_type_id, cat_id, name_id, 0, 0, 0});
StringId arg_flat_key_id = context_.storage->InternString(
base::StringView("debug.draw_duration_ms"));
@@ -516,7 +528,7 @@
arg1.value = Variadic::Real(kValues[1]);
ArgSetId args =
context_.storage->mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
- context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
+ context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -547,8 +559,10 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- 0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ context_.storage->mutable_slice_table()->Insert(
+ {0, 0, track, utid, ref_type_id, cat_id, name_id, 0, 0, 0});
StringId arg_key0_id =
context_.storage->InternString(base::StringView("arg0"));
@@ -564,7 +578,7 @@
arg1.value = Variadic::Pointer(kValue1);
ArgSetId args =
context_.storage->mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
- context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
+ context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -593,8 +607,10 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- 0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ context_.storage->mutable_slice_table()->Insert(
+ {0, 0, track, utid, ref_type_id, cat_id, name_id, 0, 0, 0});
StringId arg_flat_key_id =
context_.storage->InternString(base::StringView("a.b"));
@@ -612,7 +628,7 @@
arg1.value = Variadic::Integer(kValues[1]);
ArgSetId args =
context_.storage->mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
- context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
+ context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -642,8 +658,10 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- 0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ context_.storage->mutable_slice_table()->Insert(
+ {0, 0, track, utid, ref_type_id, cat_id, name_id, 0, 0, 0});
StringId arg_flat_key_id =
context_.storage->InternString(base::StringView("a"));
@@ -661,7 +679,7 @@
arg1.value = Variadic::Integer(kValues[1]);
ArgSetId args =
context_.storage->mutable_args()->AddArgSet({arg0, arg1}, 0, 2);
- context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
+ context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -691,8 +709,10 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- 0, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ context_.storage->mutable_slice_table()->Insert(
+ {0, 0, track, utid, ref_type_id, cat_id, name_id, 0, 0, 0});
StringId arg_key_id = context_.storage->InternString(base::StringView("a"));
StringId arg_value_id =
@@ -702,7 +722,7 @@
arg.key = arg_key_id;
arg.value = Variadic::Json(arg_value_id);
ArgSetId args = context_.storage->mutable_args()->AddArgSet({arg}, 0, 1);
- context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
+ context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -729,8 +749,9 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp, 0, track, 0, RefType::kRefNoRef, cat_id, name_id, 0, 0, 0);
+ StringId ref_type_id = context_.storage->InternString(base::StringView());
+ context_.storage->mutable_slice_table()->Insert(
+ {kTimestamp, 0, track, 0, ref_type_id, cat_id, name_id, 0, 0, 0});
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -761,8 +782,10 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
- context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp, 0, track, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ context_.storage->mutable_slice_table()->Insert(
+ {kTimestamp, 0, track, utid, ref_type_id, cat_id, name_id, 0, 0, 0});
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -794,6 +817,8 @@
UniquePid upid = context_.storage->AddEmptyProcess(kProcessID);
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefTrack)]);
constexpr int64_t kSourceId = 235;
TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
@@ -801,9 +826,9 @@
/*source_scope=*/0);
context_.args_tracker->Flush(); // Flush track args.
- context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp, kDuration, track, track, RefType::kRefTrack, cat_id, name_id,
- 0, 0, 0);
+ context_.storage->mutable_slice_table()->Insert({kTimestamp, kDuration, track,
+ track, ref_type_id, cat_id,
+ name_id, 0, 0, 0});
StringId arg_key_id =
context_.storage->InternString(base::StringView(kArgName));
TraceStorage::Args::Arg arg;
@@ -811,7 +836,7 @@
arg.key = arg_key_id;
arg.value = Variadic::Integer(kArgValue);
ArgSetId args = context_.storage->mutable_args()->AddArgSet({arg}, 0, 1);
- context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
+ context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -858,6 +883,8 @@
UniquePid upid = context_.storage->AddEmptyProcess(kProcessID);
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefTrack)]);
constexpr int64_t kSourceId = 235;
TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
@@ -865,9 +892,9 @@
/*source_scope=*/0);
context_.args_tracker->Flush(); // Flush track args.
- auto slice_id = context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp, kDuration, track, track, RefType::kRefTrack, cat_id, name_id,
- 0, 0, 0);
+ auto slice_id = context_.storage->mutable_slice_table()->Insert(
+ {kTimestamp, kDuration, track, track, ref_type_id, cat_id, name_id, 0, 0,
+ 0});
context_.storage->mutable_virtual_track_slices()->AddVirtualTrackSlice(
slice_id, kThreadTimestamp, kThreadDuration, 0, 0);
@@ -914,6 +941,8 @@
UniquePid upid = context_.storage->AddEmptyProcess(kProcessID);
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefTrack)]);
constexpr int64_t kSourceId = 235;
TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
@@ -921,9 +950,9 @@
/*source_scope=*/0);
context_.args_tracker->Flush(); // Flush track args.
- auto slice_id = context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp, kDuration, track, track, RefType::kRefTrack, cat_id, name_id,
- 0, 0, 0);
+ auto slice_id = context_.storage->mutable_slice_table()->Insert(
+ {kTimestamp, kDuration, track, track, ref_type_id, cat_id, name_id, 0, 0,
+ 0});
context_.storage->mutable_virtual_track_slices()->AddVirtualTrackSlice(
slice_id, kThreadTimestamp, kThreadDuration, 0, 0);
@@ -958,6 +987,8 @@
UniquePid upid = context_.storage->AddEmptyProcess(kProcessID);
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefTrack)]);
constexpr int64_t kSourceId = 235;
TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
@@ -965,9 +996,8 @@
/*source_scope=*/0);
context_.args_tracker->Flush(); // Flush track args.
- context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp, 0, track, track, RefType::kRefTrack, cat_id, name_id, 0, 0,
- 0);
+ context_.storage->mutable_slice_table()->Insert(
+ {kTimestamp, 0, track, track, ref_type_id, cat_id, name_id, 0, 0, 0});
StringId arg_key_id =
context_.storage->InternString(base::StringView("arg_name"));
TraceStorage::Args::Arg arg;
@@ -975,7 +1005,7 @@
arg.key = arg_key_id;
arg.value = Variadic::Integer(kArgValue);
ArgSetId args = context_.storage->mutable_args()->AddArgSet({arg}, 0, 1);
- context_.storage->mutable_nestable_slices()->set_arg_set_id(0, args);
+ context_.storage->mutable_slice_table()->mutable_arg_set_id()->Set(0, args);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
@@ -1220,13 +1250,15 @@
StringId arg1_id = context_.storage->InternString(base::StringView("arg1"));
StringId arg2_id = context_.storage->InternString(base::StringView("arg2"));
StringId val_id = context_.storage->InternString(base::StringView("val"));
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
std::array<RowId, 3> slice_ids;
for (size_t i = 0; i < name_ids.size(); i++) {
slice_ids[i] = TraceStorage::CreateRowId(
- kNestableSlices, context_.storage->mutable_nestable_slices()->AddSlice(
- 0, 0, track, utid, RefType::kRefUtid, cat_id,
- name_ids[i], 0, 0, 0));
+ kNestableSlices,
+ context_.storage->mutable_slice_table()->Insert(
+ {0, 0, track, utid, ref_type_id, cat_id, name_ids[i], 0, 0, 0}));
}
for (RowId row : slice_ids) {
@@ -1326,13 +1358,15 @@
context_.args_tracker->Flush(); // Flush track args.
StringId cat_id = context_.storage->InternString(base::StringView(kCategory));
StringId name_id = context_.storage->InternString(base::StringView(kName));
+ StringId ref_type_id = context_.storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
- context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp1, kDuration, track, utid, RefType::kRefUtid, cat_id, name_id,
- 0, 0, 0);
- context_.storage->mutable_nestable_slices()->AddSlice(
- kTimestamp2, kDuration, track, utid, RefType::kRefUtid, cat_id, name_id,
- 0, 0, 0);
+ context_.storage->mutable_slice_table()->Insert({kTimestamp1, kDuration,
+ track, utid, ref_type_id,
+ cat_id, name_id, 0, 0, 0});
+ context_.storage->mutable_slice_table()->Insert({kTimestamp2, kDuration,
+ track, utid, ref_type_id,
+ cat_id, name_id, 0, 0, 0});
auto label_filter = [](const char* label_name) {
return strcmp(label_name, "traceEvents") == 0;
diff --git a/src/trace_processor/importers/ftrace/ftrace_module.cc b/src/trace_processor/importers/ftrace/ftrace_module.cc
new file mode 100644
index 0000000..840f330
--- /dev/null
+++ b/src/trace_processor/importers/ftrace/ftrace_module.cc
@@ -0,0 +1,26 @@
+/*
+ * 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/importers/ftrace/ftrace_module.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+void FtraceModule::ParseFtracePacket(uint32_t /*cpu*/,
+ const TimestampedTracePiece&) {}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/ftrace/ftrace_module.h b/src/trace_processor/importers/ftrace/ftrace_module.h
index fd1ace0..5f43490 100644
--- a/src/trace_processor/importers/ftrace/ftrace_module.h
+++ b/src/trace_processor/importers/ftrace/ftrace_module.h
@@ -29,44 +29,29 @@
namespace perfetto {
namespace trace_processor {
-class FtraceModule
- : public ProtoImporterModuleBase<PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)> {
+class FtraceModule : public ProtoImporterModule {
public:
- explicit FtraceModule(TraceProcessorContext* context)
- : ProtoImporterModuleBase(context),
- tokenizer_(context),
- parser_(context) {}
+ virtual void ParseFtracePacket(uint32_t cpu,
+ const TimestampedTracePiece& ttp);
+};
+
+class FtraceModuleImpl : public FtraceModule {
+ public:
+ FtraceModuleImpl(TraceProcessorContext* context);
ModuleResult TokenizePacket(
const protos::pbzero::TracePacket::Decoder& decoder,
TraceBlobView* packet,
- int64_t /*packet_timestamp*/,
- PacketSequenceState* /*state*/) {
- if (decoder.has_ftrace_events()) {
- auto ftrace_field = decoder.ftrace_events();
- const size_t fld_off = packet->offset_of(ftrace_field.data);
- tokenizer_.TokenizeFtraceBundle(
- packet->slice(fld_off, ftrace_field.size));
- return ModuleResult::Handled();
- }
- return ModuleResult::Ignored();
- }
+ int64_t packet_timestamp,
+ PacketSequenceState* state,
+ uint32_t field_id) override;
- ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
- const TimestampedTracePiece&) {
- // TODO(eseckler): implement.
- if (decoder.has_ftrace_stats()) {
- parser_.ParseFtraceStats(decoder.ftrace_stats());
- return ModuleResult::Handled();
- }
+ void ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece&,
+ uint32_t field_id) override;
- return ModuleResult::Ignored();
- }
-
- ModuleResult ParseFtracePacket(uint32_t cpu,
- const TimestampedTracePiece& ttp) {
- return parser_.ParseFtraceEvent(cpu, ttp);
- }
+ void ParseFtracePacket(uint32_t cpu,
+ const TimestampedTracePiece& ttp) override;
private:
FtraceTokenizer tokenizer_;
diff --git a/src/trace_processor/importers/ftrace/ftrace_module_impl.cc b/src/trace_processor/importers/ftrace/ftrace_module_impl.cc
new file mode 100644
index 0000000..2347196
--- /dev/null
+++ b/src/trace_processor/importers/ftrace/ftrace_module_impl.cc
@@ -0,0 +1,70 @@
+/*
+ * 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 "perfetto/base/build_config.h"
+#include "src/trace_processor/importers/ftrace/ftrace_module.h"
+#include "src/trace_processor/importers/ftrace/ftrace_parser.h"
+#include "src/trace_processor/importers/ftrace/ftrace_tokenizer.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+#include "src/trace_processor/trace_blob_view.h"
+
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using perfetto::protos::pbzero::TracePacket;
+
+FtraceModuleImpl::FtraceModuleImpl(TraceProcessorContext* context)
+ : tokenizer_(context), parser_(context) {
+ RegisterForField(TracePacket::kFtraceEventsFieldNumber, context);
+ RegisterForField(TracePacket::kFtraceStatsFieldNumber, context);
+}
+
+ModuleResult FtraceModuleImpl::TokenizePacket(
+ const protos::pbzero::TracePacket::Decoder& decoder,
+ TraceBlobView* packet,
+ int64_t /*packet_timestamp*/,
+ PacketSequenceState* /*state*/,
+ uint32_t field_id) {
+ if (field_id == TracePacket::kFtraceEventsFieldNumber) {
+ auto ftrace_field = decoder.ftrace_events();
+ const size_t fld_off = packet->offset_of(ftrace_field.data);
+ tokenizer_.TokenizeFtraceBundle(packet->slice(fld_off, ftrace_field.size));
+ return ModuleResult::Handled();
+ }
+ return ModuleResult::Ignored();
+}
+
+void FtraceModuleImpl::ParsePacket(
+ const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece&,
+ uint32_t field_id) {
+ if (field_id == TracePacket::kFtraceStatsFieldNumber) {
+ parser_.ParseFtraceStats(decoder.ftrace_stats());
+ }
+}
+
+void FtraceModuleImpl::ParseFtracePacket(uint32_t cpu,
+ const TimestampedTracePiece& ttp) {
+ util::Status res = parser_.ParseFtraceEvent(cpu, ttp);
+ if (!res.ok()) {
+ PERFETTO_ELOG("%s", res.message().c_str());
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/android_probes_module.cc b/src/trace_processor/importers/proto/android_probes_module.cc
new file mode 100644
index 0000000..5f6c034
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_probes_module.cc
@@ -0,0 +1,65 @@
+/*
+ * 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/importers/proto/android_probes_module.h"
+#include "perfetto/base/build_config.h"
+#include "src/trace_processor/importers/proto/android_probes_parser.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+
+#include "protos/perfetto/config/trace_config.pbzero.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using perfetto::protos::pbzero::TracePacket;
+
+AndroidProbesModule::AndroidProbesModule(TraceProcessorContext* context)
+ : parser_(context) {
+ RegisterForField(TracePacket::kBatteryFieldNumber, context);
+ RegisterForField(TracePacket::kPowerRailsFieldNumber, context);
+ RegisterForField(TracePacket::kAndroidLogFieldNumber, context);
+ RegisterForField(TracePacket::kPackagesListFieldNumber, context);
+}
+
+void AndroidProbesModule::ParsePacket(const TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) {
+ switch (field_id) {
+ case TracePacket::kBatteryFieldNumber:
+ parser_.ParseBatteryCounters(ttp.timestamp, decoder.battery());
+ return;
+ case TracePacket::kPowerRailsFieldNumber:
+ parser_.ParsePowerRails(ttp.timestamp, decoder.power_rails());
+ return;
+ case TracePacket::kAndroidLogFieldNumber:
+ parser_.ParseAndroidLogPacket(decoder.android_log());
+ return;
+ case TracePacket::kPackagesListFieldNumber:
+ parser_.ParseAndroidPackagesList(decoder.packages_list());
+ return;
+ }
+}
+
+void AndroidProbesModule::ParseTraceConfig(
+ const protos::pbzero::TraceConfig::Decoder& decoder) {
+ if (decoder.has_statsd_metadata()) {
+ parser_.ParseStatsdMetadata(decoder.statsd_metadata());
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/android_probes_module.h b/src/trace_processor/importers/proto/android_probes_module.h
index 94d90a5..2ba7b19 100644
--- a/src/trace_processor/importers/proto/android_probes_module.h
+++ b/src/trace_processor/importers/proto/android_probes_module.h
@@ -28,45 +28,16 @@
namespace perfetto {
namespace trace_processor {
-class AndroidProbesModule : public ProtoImporterModuleBase<PERFETTO_BUILDFLAG(
- PERFETTO_TP_ANDROID_PROBES)> {
+class AndroidProbesModule : public ProtoImporterModule {
public:
- explicit AndroidProbesModule(TraceProcessorContext* context)
- : ProtoImporterModuleBase(context), parser_(context) {}
+ explicit AndroidProbesModule(TraceProcessorContext* context);
- ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
- const TimestampedTracePiece& ttp) {
- if (decoder.has_battery()) {
- parser_.ParseBatteryCounters(ttp.timestamp, decoder.battery());
- return ModuleResult::Handled();
- }
+ void ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) override;
- if (decoder.has_power_rails()) {
- parser_.ParsePowerRails(ttp.timestamp, decoder.power_rails());
- return ModuleResult::Handled();
- }
-
- if (decoder.has_android_log()) {
- parser_.ParseAndroidLogPacket(decoder.android_log());
- return ModuleResult::Handled();
- }
-
- if (decoder.has_packages_list()) {
- parser_.ParseAndroidPackagesList(decoder.packages_list());
- return ModuleResult::Handled();
- }
-
- return ModuleResult::Ignored();
- }
-
- ModuleResult ParseTraceConfig(
- const protos::pbzero::TraceConfig::Decoder& decoder) {
- if (decoder.has_statsd_metadata()) {
- parser_.ParseStatsdMetadata(decoder.statsd_metadata());
- return ModuleResult::Handled();
- }
- return ModuleResult::Ignored();
- }
+ void ParseTraceConfig(
+ const protos::pbzero::TraceConfig::Decoder& decoder) override;
private:
AndroidProbesParser parser_;
diff --git a/src/trace_processor/importers/proto/graphics_event_module.h b/src/trace_processor/importers/proto/graphics_event_module.h
index 6774c62..f7a36dd 100644
--- a/src/trace_processor/importers/proto/graphics_event_module.h
+++ b/src/trace_processor/importers/proto/graphics_event_module.h
@@ -27,7 +27,7 @@
namespace perfetto {
namespace trace_processor {
-class GraphicsEventModule : public NewProtoImporterModule {
+class GraphicsEventModule : public ProtoImporterModule {
public:
explicit GraphicsEventModule(TraceProcessorContext* context);
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.cc b/src/trace_processor/importers/proto/graphics_event_parser.cc
index 7008386..504ea5f 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_event_parser.cc
@@ -381,7 +381,7 @@
if (present_slice_id_end) {
// The slice could have had additional buffers in it, so we need to
// update the name.
- context_->storage->mutable_nestable_slices()->set_name(
+ context_->storage->mutable_slice_table()->mutable_name()->Set(
present_slice_id_end.value(),
context_->storage->InternString(
present_frame_name_.GetStringView()));
diff --git a/src/trace_processor/importers/proto/heap_graph_module.cc b/src/trace_processor/importers/proto/heap_graph_module.cc
index f89aafd..8823010 100644
--- a/src/trace_processor/importers/proto/heap_graph_module.cc
+++ b/src/trace_processor/importers/proto/heap_graph_module.cc
@@ -89,6 +89,29 @@
} // namespace
+using perfetto::protos::pbzero::TracePacket;
+
+HeapGraphModule::HeapGraphModule(TraceProcessorContext* context)
+ : context_(context) {
+ context_->heap_graph_tracker.reset(new HeapGraphTracker(context_));
+ RegisterForField(TracePacket::kHeapGraphFieldNumber, context);
+ RegisterForField(TracePacket::kDeobfuscationMappingFieldNumber, context);
+}
+
+void HeapGraphModule::ParsePacket(
+ const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) {
+ switch (field_id) {
+ case TracePacket::kHeapGraphFieldNumber:
+ ParseHeapGraph(ttp.timestamp, decoder.heap_graph());
+ return;
+ case TracePacket::kDeobfuscationMappingFieldNumber:
+ ParseDeobfuscationMapping(decoder.deobfuscation_mapping());
+ return;
+ }
+}
+
void HeapGraphModule::ParseHeapGraph(int64_t ts, protozero::ConstBytes blob) {
protos::pbzero::HeapGraph::Decoder heap_graph(blob.data, blob.size);
UniquePid upid = context_->process_tracker->GetOrCreateProcess(
diff --git a/src/trace_processor/importers/proto/heap_graph_module.h b/src/trace_processor/importers/proto/heap_graph_module.h
index 5d9755e..6e3bf72 100644
--- a/src/trace_processor/importers/proto/heap_graph_module.h
+++ b/src/trace_processor/importers/proto/heap_graph_module.h
@@ -27,31 +27,19 @@
namespace perfetto {
namespace trace_processor {
-class HeapGraphModule : public ProtoImporterModuleBase<PERFETTO_BUILDFLAG(
- PERFETTO_TP_HEAP_GRAPHS)> {
+class HeapGraphModule : public ProtoImporterModule {
public:
- explicit HeapGraphModule(TraceProcessorContext* context)
- : ProtoImporterModuleBase(context) {
- context_->heap_graph_tracker.reset(new HeapGraphTracker(context_));
- }
+ explicit HeapGraphModule(TraceProcessorContext* context);
- ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
- const TimestampedTracePiece& ttp) {
- if (decoder.has_heap_graph()) {
- ParseHeapGraph(ttp.timestamp, decoder.heap_graph());
- return ModuleResult::Handled();
- }
-
- if (decoder.has_deobfuscation_mapping()) {
- ParseDeobfuscationMapping(decoder.deobfuscation_mapping());
- return ModuleResult::Handled();
- }
- return ModuleResult::Ignored();
- }
+ void ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) override;
private:
void ParseHeapGraph(int64_t ts, protozero::ConstBytes);
void ParseDeobfuscationMapping(protozero::ConstBytes);
+
+ TraceProcessorContext* context_;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/proto_importer_module.cc b/src/trace_processor/importers/proto/proto_importer_module.cc
index 48f41ef..4524384 100644
--- a/src/trace_processor/importers/proto/proto_importer_module.cc
+++ b/src/trace_processor/importers/proto/proto_importer_module.cc
@@ -20,11 +20,11 @@
namespace perfetto {
namespace trace_processor {
-NewProtoImporterModule::NewProtoImporterModule() {}
+ProtoImporterModule::ProtoImporterModule() {}
-NewProtoImporterModule::~NewProtoImporterModule() {}
+ProtoImporterModule::~ProtoImporterModule() {}
-ModuleResult NewProtoImporterModule::TokenizePacket(
+ModuleResult ProtoImporterModule::TokenizePacket(
const protos::pbzero::TracePacket_Decoder&,
TraceBlobView* /*packet*/,
int64_t /*packet_timestamp*/,
@@ -33,16 +33,16 @@
return ModuleResult::Ignored();
}
-void NewProtoImporterModule::ParsePacket(
+void ProtoImporterModule::ParsePacket(
const protos::pbzero::TracePacket_Decoder&,
const TimestampedTracePiece&,
uint32_t /*field_id*/) {}
-void NewProtoImporterModule::ParseTraceConfig(
+void ProtoImporterModule::ParseTraceConfig(
const protos::pbzero::TraceConfig_Decoder&) {}
-void NewProtoImporterModule::RegisterForField(uint32_t field_id,
- TraceProcessorContext* context) {
+void ProtoImporterModule::RegisterForField(uint32_t field_id,
+ TraceProcessorContext* context) {
if (context->modules_by_field.size() <= field_id) {
context->modules_by_field.resize(field_id + 1, nullptr);
}
diff --git a/src/trace_processor/importers/proto/proto_importer_module.h b/src/trace_processor/importers/proto/proto_importer_module.h
index 8579213..60a0218 100644
--- a/src/trace_processor/importers/proto/proto_importer_module.h
+++ b/src/trace_processor/importers/proto/proto_importer_module.h
@@ -36,23 +36,18 @@
struct TimestampedTracePiece;
class TraceProcessorContext;
-// This file contains helper and base class templates for
-// ProtoTraceTokenizer/Parser modules. A module implements support for a subset
-// of features of the TracePacket proto format. Modules inherit from
-// ProtoImporterModuleBase, and should be instantiated using the
-// ProtoImporterModule<> wrapper template in trace_processor_context.h.
-//
+// This file contains a base class for ProtoTraceTokenizer/Parser modules.
+// A module implements support for a subset of features of the TracePacket
+// proto format.
// To add and integrate a new module:
-// (1) Add MyModule as a subclass of ProtoImporterModuleBase<IsEnabled>,
-// defining the TokenizePacket() and/or ParsePacket() methods.
-// Typically, a build-time macro will inform the value of IsEnabled.
-// See ftrace_module.h for an example.
-// (2) Add a member of type std::unique_ptr<ProtoImporterModule<MyModule>> to
-// TraceProcessorContext (trace_processor_context.h) and init it from
-// TraceProcessorImpl() and appropriate tests.
-// (3) Add an include of my_module.h and calls to your module's TokenizePacket /
-// ParsePacket methods in ProtoTraceTokenizer and/or ProtoTraceParser
-// (proxying via the wrapper).
+// (1) Add MyModule as a subclass of ProtoImporterModule,
+// overriding the TokenizePacket(), ParsePacket() and/or ParseTraceConfig()
+// methods.
+// (2) In the constructor call the RegisterForField method for every field
+// that the module knows how to handle.
+// (3) Create a module instance and add it to the |modules| vector in
+// TraceProcessorContext.
+// See GraphicsEventModule for an example.
class ModuleResult {
public:
@@ -96,119 +91,12 @@
base::Optional<std::string> error_;
};
-// Wrapper class for a module. This wrapper allows modules to be disabled
-// disabled at compile time to remove support for its features from the trace
-// processor.
-//
-// The trace processor will instantiate enabled modules for each
-// TraceProcessorContext. The tokenizer and parser notify individual modules
-// about trace data by calling their respective methods via the wrapper class.
-// If the module is enabled, the wrapper will forward the call to the module
-// implementation. This way, we avoid virtual methods, so that calling any of
-// the module's methods is zero overhead - they can be inlined by the compiler
-// at callsites directly.
-template <class ModuleType>
+// Base class for modules.
class ProtoImporterModule {
public:
- ProtoImporterModule(TraceProcessorContext* context) {
- if (ModuleType::kEnabled)
- impl_.reset(new ModuleType(context));
- }
+ ProtoImporterModule();
- // ModuleType may specify methods with the signatures below.
- // ProtoImporterModule<ModuleType> acts as a wrapper for these methods.
- // ModuleType only needs to specify the methods that
- // ProtoTraceParser/Tokenizer actually calls on the respective module.
-
- // Wraps ModuleType::TokenizePacket(). If the module is disabled, compiles
- // into a noop in optimized builds. Called by ProtoTraceTokenizer for each
- // TracePacket during the tokenization stage, i.e. before sorting. If this
- // returns a result other than ModuleResult::Ignored(), tokenization of the
- // packet will be aborted after the module.
- ModuleResult TokenizePacket(
- const protos::pbzero::TracePacket_Decoder& decoder,
- TraceBlobView* packet,
- int64_t packet_timestamp,
- PacketSequenceState* state) {
- if (ModuleType::kEnabled) {
- return impl_->TokenizePacket(decoder, packet, packet_timestamp, state);
- }
- return ModuleResult::Ignored();
- }
-
- // Wraps ModuleType::ParsePacket(). If the module is disabled, compiles into a
- // noop in optimized builds. Called by ProtoTraceParser for each non-ftrace
- // TracePacket after the sorting stage. If this returns a result other than
- // ModuleResult::Ignored(), parsing of the packet will be aborted after the
- // module.
- ModuleResult ParsePacket(const protos::pbzero::TracePacket_Decoder& decoder,
- const TimestampedTracePiece& ttp) {
- if (ModuleType::kEnabled)
- return impl_->ParsePacket(decoder, ttp);
- return ModuleResult::Ignored();
- }
-
- // Wraps ModuleType::ParseTraceConfig(). If the module is disabled, compiles
- // into a noop in optimized builds. Called by ProtoTraceParser for trace
- // config packets after the sorting stage.
- ModuleResult ParseTraceConfig(
- const protos::pbzero::TraceConfig_Decoder& decoder) {
- if (ModuleType::kEnabled)
- return impl_->ParseTraceConfig(decoder);
- return ModuleResult::Ignored();
- }
-
- // For FtraceModule only. Wraps ModuleType::ParseFtracePacket(). If the module
- // is disabled, compiles into a noop in optimized builds. Called by
- // ProtoTraceParser for each ftrace TracePacket after the sorting stage.
- // Ftrace packets are handled specially here because they are sorted in
- // separate queues per CPU. If this returns a result other than
- // ModuleResult::Ignored(), parsing of the packet will be aborted after the
- // module.
- ModuleResult ParseFtracePacket(uint32_t cpu,
- const TimestampedTracePiece& ttp) {
- if (ModuleType::kEnabled)
- return impl_->ParseFtracePacket(cpu, ttp);
- return ModuleResult::Ignored();
- }
-
- private:
- // Only initialized if the module is enabled.
- std::unique_ptr<ModuleType> impl_;
-};
-
-// Base class for a proto trace module that can be disabled at compile time.
-// Typically, a build-time macro will inform the value of IsEnabled.
-template <int IsEnabled>
-class ProtoImporterModuleBase {
- public:
- static constexpr bool kEnabled = static_cast<bool>(IsEnabled);
-
- explicit ProtoImporterModuleBase(TraceProcessorContext* context)
- : context_(context) {}
- ~ProtoImporterModuleBase() {}
-
- // See ProtoTraceModule<> for the public methods subclasses may implement.
-
- protected:
- TraceProcessorContext* context_;
-};
-
-// This is a new module superclass that allows registering modules at runtime.
-// To add and integrate a new module:
-// (1) Add MyModule as a subclass of NewProtoImporterModule,
-// overriding the TokenizePacket(), ParsePacket() and/or ParseTraceConfig()
-// methods.
-// (2) In the constructor call the RegisterForField method for every field
-// that the module knows how to handle.
-// See GraphicsEventModule for an example.
-// TODO(b/141459049): Rename this to ProtoImporterModule after all modules
-// are based on it.
-class NewProtoImporterModule {
- public:
- NewProtoImporterModule();
-
- virtual ~NewProtoImporterModule();
+ virtual ~ProtoImporterModule();
// Called by ProtoTraceTokenizer during the tokenization stage, i.e. before
// sorting. It's called for each TracePacket that contains fields for which
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index b4bbaf9..e6d3e35 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -30,14 +30,11 @@
#include "perfetto/ext/base/uuid.h"
#include "perfetto/trace_processor/status.h"
#include "src/trace_processor/args_tracker.h"
+#include "src/trace_processor/clock_tracker.h"
#include "src/trace_processor/event_tracker.h"
#include "src/trace_processor/heap_profile_tracker.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/proto/android_probes_module.h"
-#include "src/trace_processor/importers/proto/heap_graph_module.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
-#include "src/trace_processor/importers/proto/system_probes_module.h"
-#include "src/trace_processor/importers/proto/track_event_module.h"
#include "src/trace_processor/metadata.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/slice_tracker.h"
@@ -203,21 +200,6 @@
TimestampedTracePiece ttp,
const protos::pbzero::TracePacket::Decoder& packet) {
// TODO(eseckler): Propagate statuses from modules.
- if (!context_->ftrace_module->ParsePacket(packet, ttp).ignored())
- return;
-
- if (!context_->track_event_module->ParsePacket(packet, ttp).ignored())
- return;
-
- if (!context_->system_probes_module->ParsePacket(packet, ttp).ignored())
- return;
-
- if (!context_->android_probes_module->ParsePacket(packet, ttp).ignored())
- return;
-
- if (!context_->heap_graph_module->ParsePacket(packet, ttp).ignored())
- return;
-
auto& modules = context_->modules_by_field;
for (uint32_t field_id = 1; field_id < modules.size(); ++field_id) {
if (modules[field_id] && packet.Get(field_id).valid()) {
@@ -266,13 +248,8 @@
int64_t /*ts*/,
TimestampedTracePiece ttp) {
PERFETTO_DCHECK(ttp.json_value == nullptr);
-
- ModuleResult res = context_->ftrace_module->ParseFtracePacket(cpu, ttp);
- PERFETTO_DCHECK(!res.ignored());
- // TODO(eseckler): Propagate status.
- if (!res.ok()) {
- PERFETTO_ELOG("%s", res.message().c_str());
- }
+ PERFETTO_DCHECK(context_->ftrace_module);
+ context_->ftrace_module->ParseFtracePacket(cpu, ttp);
// TODO(lalitm): maybe move this to the flush method in the trace processor
// once we have it. This may reduce performance in the ArgsTracker though so
@@ -381,6 +358,17 @@
for (auto it = packet.process_dumps(); it; ++it) {
protos::pbzero::ProfilePacket::ProcessHeapSamples::Decoder entry(*it);
+ auto maybe_timestamp = context_->clock_tracker->ToTraceTime(
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC_COARSE,
+ static_cast<int64_t>(entry.timestamp()));
+
+ if (!maybe_timestamp) {
+ context_->storage->IncrementStats(stats::clock_sync_failure);
+ continue;
+ }
+
+ int64_t timestamp = *maybe_timestamp;
+
int pid = static_cast<int>(entry.pid());
if (entry.buffer_corrupted())
@@ -398,7 +386,7 @@
HeapProfileTracker::SourceAllocation src_allocation;
src_allocation.pid = entry.pid();
- src_allocation.timestamp = static_cast<int64_t>(entry.timestamp());
+ src_allocation.timestamp = timestamp;
src_allocation.callstack_id = sample.callstack_id();
src_allocation.self_allocated = sample.self_allocated();
src_allocation.self_freed = sample.self_freed();
@@ -605,8 +593,6 @@
protos::pbzero::TraceConfig::Decoder trace_config(blob.data, blob.size);
// TODO(eseckler): Propagate statuses from modules.
- context_->android_probes_module->ParseTraceConfig(trace_config);
-
for (auto& module : context_->modules) {
module->ParseTraceConfig(trace_config);
}
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 d19edae..6d7f711 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -261,17 +261,25 @@
#if PERFETTO_BUILDFLAG(PERFETTO_TP_GRAPHICS)
context_.vulkan_memory_tracker.reset(new VulkanMemoryTracker(&context_));
#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_GRAPHICS)
- context_.ftrace_module.reset(
- new ProtoImporterModule<FtraceModule>(&context_));
- context_.track_event_module.reset(
- new ProtoImporterModule<TrackEventModule>(&context_));
- context_.system_probes_module.reset(
- new ProtoImporterModule<SystemProbesModule>(&context_));
- context_.android_probes_module.reset(
- new ProtoImporterModule<AndroidProbesModule>(&context_));
- context_.heap_graph_module.reset(
- new ProtoImporterModule<HeapGraphModule>(&context_));
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
+ context_.modules.emplace_back(new FtraceModuleImpl(&context_));
+#else
+ context_.modules.emplace_back(new FtraceModule());
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
+ context_.ftrace_module =
+ static_cast<FtraceModule*>(context_.modules.back().get());
+
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_HEAP_GRAPHS)
+ context_.modules.emplace_back(new HeapGraphModule(&context_));
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_HEAP_GRAPHS)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_ANDROID_PROBES)
+ context_.modules.emplace_back(new AndroidProbesModule(&context_));
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_ANDROID_PROBES)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_SYSTEM_PROBES)
+ context_.modules.emplace_back(new SystemProbesModule(&context_));
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_SYSTEM_PROBES)
+ context_.modules.emplace_back(new TrackEventModule(&context_));
#if PERFETTO_BUILDFLAG(PERFETTO_TP_GRAPHICS)
context_.modules.emplace_back(new GraphicsEventModule(&context_));
#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_GRAPHICS)
diff --git a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
index b75ccf4..97d7689 100644
--- a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
+++ b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
@@ -32,7 +32,6 @@
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/importers/proto/proto_incremental_state.h"
-#include "src/trace_processor/importers/proto/track_event_module.h"
#include "src/trace_processor/stats.h"
#include "src/trace_processor/trace_sorter.h"
#include "src/trace_processor/trace_storage.h"
@@ -283,22 +282,11 @@
ParseInternedData(decoder, packet.slice(offset, field.size));
}
- ModuleResult res = ModuleResult::Ignored();
- res = context_->ftrace_module->TokenizePacket(decoder, &packet, timestamp,
- state);
- if (!res.ignored())
- return res.ToStatus();
-
- res = context_->track_event_module->TokenizePacket(decoder, &packet,
- timestamp, state);
- if (!res.ignored())
- return res.ToStatus();
-
auto& modules = context_->modules_by_field;
for (uint32_t field_id = 1; field_id < modules.size(); ++field_id) {
if (modules[field_id] && decoder.Get(field_id).valid()) {
- modules[field_id]->TokenizePacket(decoder, &packet, timestamp, state,
- field_id);
+ ModuleResult res = modules[field_id]->TokenizePacket(
+ decoder, &packet, timestamp, state, field_id);
if (!res.ignored())
return res.ToStatus();
}
diff --git a/src/trace_processor/importers/proto/system_probes_module.cc b/src/trace_processor/importers/proto/system_probes_module.cc
new file mode 100644
index 0000000..7d5f254
--- /dev/null
+++ b/src/trace_processor/importers/proto/system_probes_module.cc
@@ -0,0 +1,57 @@
+/*
+ * 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/importers/proto/system_probes_module.h"
+#include "perfetto/base/build_config.h"
+#include "src/trace_processor/importers/proto/system_probes_parser.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using perfetto::protos::pbzero::TracePacket;
+
+SystemProbesModule::SystemProbesModule(TraceProcessorContext* context)
+ : parser_(context) {
+ RegisterForField(TracePacket::kProcessTreeFieldNumber, context);
+ RegisterForField(TracePacket::kProcessStatsFieldNumber, context);
+ RegisterForField(TracePacket::kSysStatsFieldNumber, context);
+ RegisterForField(TracePacket::kSystemInfoFieldNumber, context);
+}
+
+void SystemProbesModule::ParsePacket(const TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) {
+ switch (field_id) {
+ case TracePacket::kProcessTreeFieldNumber:
+ parser_.ParseProcessTree(decoder.process_tree());
+ return;
+ case TracePacket::kProcessStatsFieldNumber:
+ parser_.ParseProcessStats(ttp.timestamp, decoder.process_stats());
+ return;
+ case TracePacket::kSysStatsFieldNumber:
+ parser_.ParseSysStats(ttp.timestamp, decoder.sys_stats());
+ return;
+ case TracePacket::kSystemInfoFieldNumber:
+ parser_.ParseSystemInfo(decoder.system_info());
+ return;
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/system_probes_module.h b/src/trace_processor/importers/proto/system_probes_module.h
index 53db890..438eabe 100644
--- a/src/trace_processor/importers/proto/system_probes_module.h
+++ b/src/trace_processor/importers/proto/system_probes_module.h
@@ -20,43 +20,19 @@
#include "perfetto/base/build_config.h"
#include "src/trace_processor/importers/proto/proto_importer_module.h"
#include "src/trace_processor/importers/proto/system_probes_parser.h"
-#include "src/trace_processor/timestamped_trace_piece.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
namespace perfetto {
namespace trace_processor {
-class SystemProbesModule : public ProtoImporterModuleBase<PERFETTO_BUILDFLAG(
- PERFETTO_TP_SYSTEM_PROBES)> {
+class SystemProbesModule : public ProtoImporterModule {
public:
- explicit SystemProbesModule(TraceProcessorContext* context)
- : ProtoImporterModuleBase(context), parser_(context) {}
+ explicit SystemProbesModule(TraceProcessorContext* context);
- ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
- const TimestampedTracePiece& ttp) {
- if (decoder.has_process_tree()) {
- parser_.ParseProcessTree(decoder.process_tree());
- return ModuleResult::Handled();
- }
-
- if (decoder.has_process_stats()) {
- parser_.ParseProcessStats(ttp.timestamp, decoder.process_stats());
- return ModuleResult::Handled();
- }
-
- if (decoder.has_sys_stats()) {
- parser_.ParseSysStats(ttp.timestamp, decoder.sys_stats());
- return ModuleResult::Handled();
- }
-
- if (decoder.has_system_info()) {
- parser_.ParseSystemInfo(decoder.system_info());
- return ModuleResult::Handled();
- }
-
- return ModuleResult::Ignored();
- }
+ void ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) override;
private:
SystemProbesParser parser_;
diff --git a/src/trace_processor/importers/proto/track_event_module.cc b/src/trace_processor/importers/proto/track_event_module.cc
new file mode 100644
index 0000000..8e80a80
--- /dev/null
+++ b/src/trace_processor/importers/proto/track_event_module.cc
@@ -0,0 +1,76 @@
+/*
+ * 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/importers/proto/track_event_module.h"
+#include "perfetto/base/build_config.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+
+#include "protos/perfetto/config/trace_config.pbzero.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using perfetto::protos::pbzero::TracePacket;
+
+TrackEventModule::TrackEventModule(TraceProcessorContext* context)
+ : tokenizer_(context), parser_(context) {
+ RegisterForField(TracePacket::kTrackEventFieldNumber, context);
+ RegisterForField(TracePacket::kTrackDescriptorFieldNumber, context);
+ RegisterForField(TracePacket::kThreadDescriptorFieldNumber, context);
+ RegisterForField(TracePacket::kProcessDescriptorFieldNumber, context);
+}
+
+TrackEventModule::~TrackEventModule() = default;
+
+ModuleResult TrackEventModule::TokenizePacket(
+ const TracePacket::Decoder& decoder,
+ TraceBlobView* packet,
+ int64_t packet_timestamp,
+ PacketSequenceState* state,
+ uint32_t field_id) {
+ switch (field_id) {
+ case TracePacket::kTrackDescriptorFieldNumber:
+ tokenizer_.TokenizeTrackDescriptorPacket(decoder);
+ return ModuleResult::Handled();
+ case TracePacket::kTrackEventFieldNumber:
+ tokenizer_.TokenizeTrackEventPacket(state, decoder, packet,
+ packet_timestamp);
+ return ModuleResult::Handled();
+ case TracePacket::kThreadDescriptorFieldNumber:
+ // TODO(eseckler): Remove these once Chrome has switched fully over to
+ // TrackDescriptors.
+ tokenizer_.TokenizeThreadDescriptorPacket(state, decoder);
+ return ModuleResult::Handled();
+ case TracePacket::kProcessDescriptorFieldNumber:
+ tokenizer_.TokenizeProcessDescriptorPacket(decoder);
+ return ModuleResult::Handled();
+ }
+ return ModuleResult::Ignored();
+}
+
+void TrackEventModule::ParsePacket(const TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) {
+ if (field_id == TracePacket::kTrackEventFieldNumber) {
+ parser_.ParseTrackEvent(
+ ttp.timestamp, ttp.thread_timestamp, ttp.thread_instruction_count,
+ ttp.packet_sequence_state, ttp.packet_sequence_state_generation,
+ decoder.track_event());
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/track_event_module.h b/src/trace_processor/importers/proto/track_event_module.h
index b58b8bc..de31d47 100644
--- a/src/trace_processor/importers/proto/track_event_module.h
+++ b/src/trace_processor/importers/proto/track_event_module.h
@@ -17,66 +17,31 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRACK_EVENT_MODULE_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRACK_EVENT_MODULE_H_
-#include "perfetto/base/build_config.h"
#include "src/trace_processor/importers/proto/proto_importer_module.h"
#include "src/trace_processor/importers/proto/track_event_parser.h"
#include "src/trace_processor/importers/proto/track_event_tokenizer.h"
-#include "src/trace_processor/timestamped_trace_piece.h"
-#include "protos/perfetto/config/trace_config.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
namespace perfetto {
namespace trace_processor {
-class TrackEventModule : public ProtoImporterModuleBase</*IsEnabled=*/1> {
+class TrackEventModule : public ProtoImporterModule {
public:
- explicit TrackEventModule(TraceProcessorContext* context)
- : ProtoImporterModuleBase(context),
- tokenizer_(context),
- parser_(context) {}
+ explicit TrackEventModule(TraceProcessorContext* context);
+
+ ~TrackEventModule() override;
ModuleResult TokenizePacket(
const protos::pbzero::TracePacket::Decoder& decoder,
TraceBlobView* packet,
int64_t packet_timestamp,
- PacketSequenceState* state) {
- if (decoder.has_track_descriptor()) {
- tokenizer_.TokenizeTrackDescriptorPacket(decoder);
- return ModuleResult::Handled();
- }
+ PacketSequenceState* state,
+ uint32_t field_id) override;
- if (decoder.has_track_event()) {
- tokenizer_.TokenizeTrackEventPacket(state, decoder, packet,
- packet_timestamp);
- return ModuleResult::Handled();
- }
-
- // TODO(eseckler): Remove these once Chrome has switched fully over to
- // TrackDescriptors.
- if (decoder.has_thread_descriptor()) {
- tokenizer_.TokenizeThreadDescriptorPacket(state, decoder);
- return ModuleResult::Handled();
- }
- if (decoder.has_process_descriptor()) {
- tokenizer_.TokenizeProcessDescriptorPacket(decoder);
- return ModuleResult::Handled();
- }
-
- return ModuleResult::Ignored();
- }
-
- ModuleResult ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
- const TimestampedTracePiece& ttp) {
- if (decoder.has_track_event()) {
- parser_.ParseTrackEvent(
- ttp.timestamp, ttp.thread_timestamp, ttp.thread_instruction_count,
- ttp.packet_sequence_state, ttp.packet_sequence_state_generation,
- decoder.track_event());
- return ModuleResult::Handled();
- }
- return ModuleResult::Ignored();
- }
+ void ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) override;
private:
TrackEventTokenizer tokenizer_;
diff --git a/src/trace_processor/importers/systrace/systrace_parser.cc b/src/trace_processor/importers/systrace/systrace_parser.cc
index f99a29d..66dc3e7 100644
--- a/src/trace_processor/importers/systrace/systrace_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_parser.cc
@@ -101,13 +101,29 @@
switch (point.phase) {
case 'B': {
StringId name_id = context_->storage->InternString(point.name);
- context_->slice_tracker->BeginAndroid(ts, pid, point.tgid, 0 /*cat_id*/,
- name_id);
+ UniqueTid utid = context_->process_tracker->UpdateThread(pid, point.tgid);
+ TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
+ context_->slice_tracker->Begin(ts, track_id, utid, RefType::kRefUtid,
+ 0 /* cat */, name_id);
break;
}
case 'E': {
- context_->slice_tracker->EndAndroid(ts, pid, point.tgid);
+ // |point.tgid| can be 0 in older android versions where the end event
+ // would not contain the value.
+ UniqueTid utid;
+ if (point.tgid == 0) {
+ // If we haven't seen this thread before, there can't have been a Begin
+ // event for it so just ignore the event.
+ auto opt_utid = context_->process_tracker->GetThreadOrNull(pid);
+ if (!opt_utid)
+ break;
+ utid = *opt_utid;
+ } else {
+ utid = context_->process_tracker->UpdateThread(pid, point.tgid);
+ }
+ TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
+ context_->slice_tracker->End(ts, track_id);
break;
}
diff --git a/src/trace_processor/rpc/rpc.cc b/src/trace_processor/rpc/rpc.cc
index f943b80..e09d0ae 100644
--- a/src/trace_processor/rpc/rpc.cc
+++ b/src/trace_processor/rpc/rpc.cc
@@ -190,7 +190,7 @@
// Write the column descriptors.
for (uint32_t col_idx = 0; col_idx < it.ColumnCount(); ++col_idx) {
auto* descriptor = result->add_column_descriptors();
- std::string col_name = it.GetColumName(col_idx);
+ std::string col_name = it.GetColumnName(col_idx);
descriptor->set_name(col_name.data(), col_name.size());
descriptor->set_type(col_types[col_idx]);
}
diff --git a/src/trace_processor/slice_table.cc b/src/trace_processor/slice_table.cc
deleted file mode 100644
index 2570674..0000000
--- a/src/trace_processor/slice_table.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2018 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/slice_table.h"
-
-#include "src/trace_processor/storage_columns.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-SliceTable::SliceTable(sqlite3*, const TraceStorage* storage)
- : storage_(storage) {}
-
-void SliceTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
- SqliteTable::Register<SliceTable>(db, storage, "internal_slice");
-}
-
-StorageSchema SliceTable::CreateStorageSchema() {
- const auto& slices = storage_->nestable_slices();
- return StorageSchema::Builder()
- .AddGenericNumericColumn("slice_id", RowAccessor())
- .AddOrderedNumericColumn("ts", &slices.start_ns())
- .AddNumericColumn("dur", &slices.durations())
- .AddNumericColumn("track_id", &slices.track_id())
- .AddNumericColumn("ref", &slices.refs())
- .AddStringColumn("ref_type", &slices.types(), &GetRefTypeStringMap())
- .AddStringColumn("category", &slices.categories(),
- &storage_->string_pool())
- .AddStringColumn("name", &slices.names(), &storage_->string_pool())
- .AddNumericColumn("depth", &slices.depths())
- .AddNumericColumn("stack_id", &slices.stack_ids())
- .AddNumericColumn("parent_stack_id", &slices.parent_stack_ids())
- .AddNumericColumn("arg_set_id", &slices.arg_set_ids())
- .Build({"slice_id"});
-}
-
-uint32_t SliceTable::RowCount() {
- return static_cast<uint32_t>(storage_->nestable_slices().slice_count());
-}
-
-int SliceTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
- info->estimated_cost = EstimateCost(qc);
- info->sqlite_omit_order_by = true;
-
- // Only the string columns are handled by SQLite
- size_t name_index = schema().ColumnIndexFromName("name");
- size_t cat_index = schema().ColumnIndexFromName("category");
- size_t ref_type_index = schema().ColumnIndexFromName("ref_type");
- for (size_t i = 0; i < qc.constraints().size(); i++) {
- auto col = static_cast<size_t>(qc.constraints()[i].column);
- info->sqlite_omit_constraint[i] =
- col != name_index && col != cat_index && col != ref_type_index;
- }
- return SQLITE_OK;
-}
-
-uint32_t SliceTable::EstimateCost(const QueryConstraints& qc) {
- // slice_id is row index, so we can filter efficiently for equality.
- if (HasEqConstraint(qc, "slice_id"))
- return 1;
-
- auto eq_ts = HasEqConstraint(qc, "ts");
- auto eq_ref = HasEqConstraint(qc, "ref");
- auto eq_ref_type = HasEqConstraint(qc, "ref_type");
- auto eq_depth = HasEqConstraint(qc, "depth");
- auto eq_name = HasEqConstraint(qc, "name");
-
- // ref + ref_type + ts + depth is a unique key. others are estimates.
- if (eq_ref && eq_ref_type && eq_ts && eq_depth)
- return 1;
- else if (eq_ref && eq_ref_type && eq_ts)
- return 10;
- else if (eq_ts && eq_name)
- return 10;
- else if (eq_ts || eq_name)
- return 100;
- return RowCount();
-}
-
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/slice_table.h b/src/trace_processor/slice_table.h
deleted file mode 100644
index 5276900..0000000
--- a/src/trace_processor/slice_table.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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_SLICE_TABLE_H_
-#define SRC_TRACE_PROCESSOR_SLICE_TABLE_H_
-
-#include "src/trace_processor/storage_table.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-class QueryConstraints;
-class TraceStorage;
-
-// A virtual table that allows to query slices coming from userspace events
-// such as chromium TRACE_EVENT macros. Conversely to "shced" slices, these
-// slices can be nested and form stacks.
-// The current implementation of this table is extremely simple and not
-// particularly efficient, as it delegates all the sorting and filtering to
-// the SQLite query engine.
-class SliceTable : public StorageTable {
- public:
- SliceTable(sqlite3*, const TraceStorage* storage);
-
- static void RegisterTable(sqlite3* db, const TraceStorage* storage);
-
- // StorageTable implementation.
- StorageSchema CreateStorageSchema() override;
- uint32_t RowCount() override;
- int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
-
- private:
- uint32_t EstimateCost(const QueryConstraints&);
-
- std::vector<const char*> ref_types_;
- const TraceStorage* const storage_;
-};
-
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_SLICE_TABLE_H_
diff --git a/src/trace_processor/slice_tracker.cc b/src/trace_processor/slice_tracker.cc
index 22c85d9..39d4058 100644
--- a/src/trace_processor/slice_tracker.cc
+++ b/src/trace_processor/slice_tracker.cc
@@ -38,19 +38,6 @@
SliceTracker::~SliceTracker() = default;
-base::Optional<uint32_t> SliceTracker::BeginAndroid(int64_t timestamp,
- uint32_t ftrace_tid,
- uint32_t atrace_tgid,
- StringId category,
- StringId name) {
- UniqueTid utid =
- context_->process_tracker->UpdateThread(ftrace_tid, atrace_tgid);
- ftrace_to_atrace_tgid_[ftrace_tid] = atrace_tgid;
-
- TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- return Begin(timestamp, track_id, utid, RefType::kRefUtid, category, name);
-}
-
base::Optional<uint32_t> SliceTracker::Begin(int64_t timestamp,
TrackId track_id,
int64_t ref,
@@ -101,7 +88,7 @@
StringId name,
SetArgsCallback args_callback) {
auto* stack = &stacks_[track_id];
- auto* slices = context_->storage->mutable_nestable_slices();
+ auto* slices = context_->storage->mutable_slice_table();
const uint8_t depth = static_cast<uint8_t>(stack->size());
if (depth >= std::numeric_limits<uint8_t>::max()) {
@@ -109,10 +96,14 @@
return base::nullopt;
}
int64_t parent_stack_id =
- depth == 0 ? 0 : slices->stack_ids()[stack->back().first];
- uint32_t slice_idx =
- slices->AddSlice(timestamp, duration, track_id, ref, ref_type, category,
- name, depth, 0, parent_stack_id);
+ depth == 0 ? 0 : slices->stack_id()[stack->back().first];
+
+ StringId ref_type_id = context_->storage->InternString(
+ GetRefTypeStringMap()[static_cast<uint32_t>(ref_type)]);
+
+ tables::SliceTable::Row row(timestamp, duration, track_id, ref, ref_type_id,
+ category, name, depth, 0, parent_stack_id);
+ uint32_t slice_idx = slices->Insert(row);
stack->emplace_back(std::make_pair(slice_idx, ArgsTracker(context_)));
if (args_callback) {
@@ -120,39 +111,10 @@
&stack->back().second,
TraceStorage::CreateRowId(TableId::kNestableSlices, slice_idx));
}
- slices->set_stack_id(slice_idx, GetStackHash(*stack));
+ slices->mutable_stack_id()->Set(slice_idx, GetStackHash(*stack));
return slice_idx;
}
-base::Optional<uint32_t> SliceTracker::EndAndroid(int64_t timestamp,
- uint32_t ftrace_tid,
- uint32_t atrace_tgid) {
- auto map_tgid_it = ftrace_to_atrace_tgid_.find(ftrace_tid);
- bool has_map_tgid = map_tgid_it != ftrace_to_atrace_tgid_.end();
-
- // atrace_tgid can be 0 in older android versions where the end event would
- // not contain the value.
- if (atrace_tgid == 0) {
- if (!has_map_tgid) {
- // This is possible if we start tracing after a begin slice.
- PERFETTO_DLOG("Unknown tgid for ftrace tid %u", ftrace_tid);
- return base::nullopt;
- }
- } else {
- if (has_map_tgid && atrace_tgid != map_tgid_it->second) {
- PERFETTO_DLOG("Mismatched atrace pid %u and looked up pid %u",
- atrace_tgid, map_tgid_it->second);
- context_->storage->IncrementStats(stats::atrace_tgid_mismatch);
- }
- }
-
- uint32_t actual_tgid = atrace_tgid == 0 ? map_tgid_it->second : atrace_tgid;
- UniqueTid utid =
- context_->process_tracker->UpdateThread(ftrace_tid, actual_tgid);
- TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- return End(timestamp, track_id);
-}
-
// Returns the first incomplete slice in the stack with matching name and
// category. We assume null category/name matches everything. Returns
// nullopt if no matching slice is found.
@@ -160,16 +122,16 @@
SlicesStack& stack,
StringId name,
StringId category) {
- auto* slices = context_->storage->mutable_nestable_slices();
+ auto* slices = context_->storage->mutable_slice_table();
for (int i = static_cast<int>(stack.size()) - 1; i >= 0; i--) {
uint32_t slice_idx = stack[static_cast<size_t>(i)].first;
- if (slices->durations()[slice_idx] != kPendingDuration)
+ if (slices->dur()[slice_idx] != kPendingDuration)
continue;
- const StringId& other_category = slices->categories()[slice_idx];
+ const StringId& other_category = slices->category()[slice_idx];
if (!category.is_null() && !other_category.is_null() &&
category != other_category)
continue;
- const StringId& other_name = slices->names()[slice_idx];
+ const StringId& other_name = slices->name()[slice_idx];
if (!name.is_null() && !other_name.is_null() && name != other_name)
continue;
return static_cast<size_t>(i);
@@ -195,7 +157,7 @@
if (stack.empty())
return base::nullopt;
- auto* slices = context_->storage->mutable_nestable_slices();
+ auto* slices = context_->storage->mutable_slice_table();
base::Optional<size_t> stack_idx =
MatchingIncompleteSliceIndex(stack, name, category);
@@ -220,8 +182,8 @@
uint32_t slice_idx = stack[stack_idx.value()].first;
- PERFETTO_DCHECK(slices->durations()[slice_idx] == kPendingDuration);
- slices->set_duration(slice_idx, timestamp - slices->start_ns()[slice_idx]);
+ PERFETTO_DCHECK(slices->dur()[slice_idx] == kPendingDuration);
+ slices->mutable_dur()->Set(slice_idx, timestamp - slices->ts()[slice_idx]);
if (args_callback) {
args_callback(
@@ -252,13 +214,13 @@
}
void SliceTracker::MaybeCloseStack(int64_t ts, SlicesStack* stack) {
- const auto& slices = context_->storage->nestable_slices();
+ const auto& slices = context_->storage->slice_table();
bool pending_dur_descendent = false;
for (int i = static_cast<int>(stack->size()) - 1; i >= 0; i--) {
uint32_t slice_idx = (*stack)[static_cast<size_t>(i)].first;
- int64_t start_ts = slices.start_ns()[slice_idx];
- int64_t dur = slices.durations()[slice_idx];
+ int64_t start_ts = slices.ts()[slice_idx];
+ int64_t dur = slices.dur()[slice_idx];
int64_t end_ts = start_ts + dur;
if (dur == kPendingDuration) {
pending_dur_descendent = true;
@@ -290,19 +252,15 @@
int64_t SliceTracker::GetStackHash(const SlicesStack& stack) {
PERFETTO_DCHECK(!stack.empty());
- const auto& slices = context_->storage->nestable_slices();
+ const auto& slices = context_->storage->slice_table();
- std::string s;
- s.reserve(stack.size() * sizeof(uint64_t) * 2);
+ base::Hash hash;
for (size_t i = 0; i < stack.size(); i++) {
uint32_t slice_idx = stack[i].first;
- s.append(reinterpret_cast<const char*>(&slices.categories()[slice_idx]),
- sizeof(slices.categories()[slice_idx]));
- s.append(reinterpret_cast<const char*>(&slices.names()[slice_idx]),
- sizeof(slices.names()[slice_idx]));
+ hash.Update(slices.category()[slice_idx]);
+ hash.Update(slices.name()[slice_idx]);
}
- constexpr uint64_t kMask = uint64_t(-1) >> 1;
- return static_cast<int64_t>((std::hash<std::string>{}(s)) & kMask);
+ return static_cast<int64_t>(hash.digest());
}
} // namespace trace_processor
diff --git a/src/trace_processor/slice_tracker.h b/src/trace_processor/slice_tracker.h
index 726c25f..2347aea 100644
--- a/src/trace_processor/slice_tracker.h
+++ b/src/trace_processor/slice_tracker.h
@@ -34,12 +34,6 @@
explicit SliceTracker(TraceProcessorContext*);
virtual ~SliceTracker();
- base::Optional<uint32_t> BeginAndroid(int64_t timestamp,
- uint32_t ftrace_tid,
- uint32_t atrace_tgid,
- StringId category,
- StringId name);
-
// virtual for testing
virtual base::Optional<uint32_t> Begin(
int64_t timestamp,
@@ -61,10 +55,6 @@
int64_t duration,
SetArgsCallback args_callback = SetArgsCallback());
- base::Optional<uint32_t> EndAndroid(int64_t timestamp,
- uint32_t ftrace_tid,
- uint32_t atrace_tgid);
-
// virtual for testing
virtual base::Optional<uint32_t> End(
int64_t timestamp,
@@ -101,7 +91,6 @@
TraceProcessorContext* const context_;
StackMap stacks_;
- std::unordered_map<uint32_t, uint32_t> ftrace_to_atrace_tgid_;
};
} // namespace trace_processor
diff --git a/src/trace_processor/slice_tracker_unittest.cc b/src/trace_processor/slice_tracker_unittest.cc
index 33f0d5e..3b709ce 100644
--- a/src/trace_processor/slice_tracker_unittest.cc
+++ b/src/trace_processor/slice_tracker_unittest.cc
@@ -42,10 +42,10 @@
*os << "SliceInfo{" << info.start << ", " << info.duration << "}";
}
-std::vector<SliceInfo> ToSliceInfo(const TraceStorage::NestableSlices& slices) {
+std::vector<SliceInfo> ToSliceInfo(const tables::SliceTable& slices) {
std::vector<SliceInfo> infos;
- for (size_t i = 0; i < slices.slice_count(); i++) {
- infos.emplace_back(SliceInfo{slices.start_ns()[i], slices.durations()[i]});
+ for (uint32_t i = 0; i < slices.size(); i++) {
+ infos.emplace_back(SliceInfo{slices.ts()[i], slices.dur()[i]});
}
return infos;
}
@@ -60,17 +60,18 @@
1 /*name*/);
tracker.End(10 /*ts*/, track, 0 /*cat*/, 1 /*name*/);
- auto slices = context.storage->nestable_slices();
- EXPECT_EQ(slices.slice_count(), 1u);
- EXPECT_EQ(slices.start_ns()[0], 2);
- EXPECT_EQ(slices.durations()[0], 8);
+ const auto& slices = context.storage->slice_table();
+ EXPECT_EQ(slices.size(), 1u);
+ EXPECT_EQ(slices.ts()[0], 2);
+ EXPECT_EQ(slices.dur()[0], 8);
EXPECT_EQ(slices.track_id()[0], track);
- EXPECT_EQ(slices.categories()[0], 0u);
- EXPECT_EQ(slices.names()[0], 1u);
- EXPECT_EQ(slices.refs()[0], 42);
- EXPECT_EQ(slices.types()[0], RefType::kRefUtid);
- EXPECT_EQ(slices.depths()[0], 0);
- EXPECT_EQ(slices.arg_set_ids()[0], kInvalidArgSetId);
+ EXPECT_EQ(slices.category()[0], 0u);
+ EXPECT_EQ(slices.name()[0], 1u);
+ EXPECT_EQ(slices.ref()[0], 42);
+ EXPECT_EQ(slices.ref_type().GetString(0),
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ EXPECT_EQ(slices.depth()[0], 0u);
+ EXPECT_EQ(slices.arg_set_id()[0], kInvalidArgSetId);
}
TEST(SliceTrackerTest, OneSliceWithArgs) {
@@ -90,17 +91,18 @@
/*value=*/Variadic::Integer(20));
});
- auto slices = context.storage->nestable_slices();
- EXPECT_EQ(slices.slice_count(), 1u);
- EXPECT_EQ(slices.start_ns()[0], 2);
- EXPECT_EQ(slices.durations()[0], 8);
+ const auto& slices = context.storage->slice_table();
+ EXPECT_EQ(slices.size(), 1u);
+ EXPECT_EQ(slices.ts()[0], 2);
+ EXPECT_EQ(slices.dur()[0], 8);
EXPECT_EQ(slices.track_id()[0], track);
- EXPECT_EQ(slices.categories()[0], 0u);
- EXPECT_EQ(slices.names()[0], 1u);
- EXPECT_EQ(slices.refs()[0], 42);
- EXPECT_EQ(slices.types()[0], RefType::kRefUtid);
- EXPECT_EQ(slices.depths()[0], 0);
- auto set_id = slices.arg_set_ids()[0];
+ EXPECT_EQ(slices.category()[0], 0u);
+ EXPECT_EQ(slices.name()[0], 1u);
+ EXPECT_EQ(slices.ref()[0], 42);
+ EXPECT_EQ(slices.ref_type().GetString(0),
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ EXPECT_EQ(slices.depth()[0], 0u);
+ auto set_id = slices.arg_set_id()[0];
auto args = context.storage->args();
EXPECT_EQ(args.set_ids()[0], set_id);
@@ -126,32 +128,34 @@
tracker.End(5 /*ts*/, track);
tracker.End(10 /*ts*/, track);
- auto slices = context.storage->nestable_slices();
+ const auto& slices = context.storage->slice_table();
- EXPECT_EQ(slices.slice_count(), 2u);
+ EXPECT_EQ(slices.size(), 2u);
- size_t idx = 0;
- EXPECT_EQ(slices.start_ns()[idx], 2);
- EXPECT_EQ(slices.durations()[idx], 8);
+ uint32_t idx = 0;
+ EXPECT_EQ(slices.ts()[idx], 2);
+ EXPECT_EQ(slices.dur()[idx], 8);
EXPECT_EQ(slices.track_id()[idx], track);
- EXPECT_EQ(slices.categories()[idx], 0u);
- EXPECT_EQ(slices.names()[idx], 1u);
- EXPECT_EQ(slices.refs()[idx], 42);
- EXPECT_EQ(slices.types()[idx], RefType::kRefUtid);
- EXPECT_EQ(slices.depths()[idx++], 0);
+ EXPECT_EQ(slices.category()[idx], 0u);
+ EXPECT_EQ(slices.name()[idx], 1u);
+ EXPECT_EQ(slices.ref()[idx], 42);
+ EXPECT_EQ(slices.ref_type().GetString(idx),
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ EXPECT_EQ(slices.depth()[idx++], 0u);
- EXPECT_EQ(slices.start_ns()[idx], 3);
- EXPECT_EQ(slices.durations()[idx], 2);
+ EXPECT_EQ(slices.ts()[idx], 3);
+ EXPECT_EQ(slices.dur()[idx], 2);
EXPECT_EQ(slices.track_id()[idx], track);
- EXPECT_EQ(slices.categories()[idx], 0u);
- EXPECT_EQ(slices.names()[idx], 2u);
- EXPECT_EQ(slices.refs()[idx], 42);
- EXPECT_EQ(slices.types()[idx], RefType::kRefUtid);
- EXPECT_EQ(slices.depths()[idx], 1);
+ EXPECT_EQ(slices.category()[idx], 0u);
+ EXPECT_EQ(slices.name()[idx], 2u);
+ EXPECT_EQ(slices.ref()[idx], 42);
+ EXPECT_EQ(slices.ref_type().GetString(idx),
+ GetRefTypeStringMap()[static_cast<uint32_t>(RefType::kRefUtid)]);
+ EXPECT_EQ(slices.depth()[idx], 1u);
- EXPECT_EQ(slices.parent_stack_ids()[0], 0);
- EXPECT_EQ(slices.stack_ids()[0], slices.parent_stack_ids()[1]);
- EXPECT_NE(slices.stack_ids()[1], 0);
+ EXPECT_EQ(slices.parent_stack_id()[0], 0);
+ EXPECT_EQ(slices.stack_id()[0], slices.parent_stack_id()[1]);
+ EXPECT_NE(slices.stack_id()[1], 0);
}
TEST(SliceTrackerTest, Scoped) {
@@ -166,7 +170,7 @@
tracker.End(9 /*ts*/, track);
tracker.End(10 /*ts*/, track);
- auto slices = ToSliceInfo(context.storage->nestable_slices());
+ auto slices = ToSliceInfo(context.storage->slice_table());
EXPECT_THAT(slices,
ElementsAre(SliceInfo{0, 10}, SliceInfo{1, 8}, SliceInfo{2, 6}));
}
@@ -183,7 +187,7 @@
tracker.End(4 /*ts*/, track, 0 /*cat*/, 2 /*name*/);
tracker.End(5 /*ts*/, track, 5 /*cat*/, 1 /*name*/);
- auto slices = ToSliceInfo(context.storage->nestable_slices());
+ auto slices = ToSliceInfo(context.storage->slice_table());
EXPECT_THAT(slices, ElementsAre(SliceInfo{2, 3}));
}
@@ -205,7 +209,7 @@
tracker.Scoped(13 /*ts*/, track, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/,
1 /*name*/, 1 /* dur */);
- auto slices = ToSliceInfo(context.storage->nestable_slices());
+ auto slices = ToSliceInfo(context.storage->slice_table());
EXPECT_THAT(slices, ElementsAre(SliceInfo{2, 10}, SliceInfo{2, 0},
SliceInfo{12, 1}, SliceInfo{13, 1}));
}
@@ -223,16 +227,16 @@
tracker.End(10 /*ts*/, track_a);
tracker.FlushPendingSlices();
- auto slices = ToSliceInfo(context.storage->nestable_slices());
+ auto slices = ToSliceInfo(context.storage->slice_table());
EXPECT_THAT(slices,
ElementsAre(SliceInfo{0, 10}, SliceInfo{2, 6}, SliceInfo{3, 4}));
- EXPECT_EQ(context.storage->nestable_slices().track_id()[0], track_a);
- EXPECT_EQ(context.storage->nestable_slices().track_id()[1], track_b);
- EXPECT_EQ(context.storage->nestable_slices().track_id()[2], track_b);
- EXPECT_EQ(context.storage->nestable_slices().depths()[0], 0);
- EXPECT_EQ(context.storage->nestable_slices().depths()[1], 0);
- EXPECT_EQ(context.storage->nestable_slices().depths()[2], 1);
+ EXPECT_EQ(context.storage->slice_table().track_id()[0], track_a);
+ EXPECT_EQ(context.storage->slice_table().track_id()[1], track_b);
+ EXPECT_EQ(context.storage->slice_table().track_id()[2], track_b);
+ EXPECT_EQ(context.storage->slice_table().depth()[0], 0u);
+ EXPECT_EQ(context.storage->slice_table().depth()[1], 0u);
+ EXPECT_EQ(context.storage->slice_table().depth()[2], 1u);
}
TEST(SliceTrackerTest, EndEventOutOfOrder) {
@@ -267,15 +271,15 @@
tracker.FlushPendingSlices();
- auto slices = ToSliceInfo(context.storage->nestable_slices());
+ auto slices = ToSliceInfo(context.storage->slice_table());
EXPECT_THAT(slices, ElementsAre(SliceInfo{50, 100}, SliceInfo{100, 400},
SliceInfo{450, 100}, SliceInfo{800, 200},
SliceInfo{1100, -1}, SliceInfo{1300, 0 - 1}));
- EXPECT_EQ(context.storage->nestable_slices().depths()[0], 0);
- EXPECT_EQ(context.storage->nestable_slices().depths()[1], 1);
- EXPECT_EQ(context.storage->nestable_slices().depths()[2], 2);
- EXPECT_EQ(context.storage->nestable_slices().depths()[3], 0);
+ EXPECT_EQ(context.storage->slice_table().depth()[0], 0u);
+ EXPECT_EQ(context.storage->slice_table().depth()[1], 1u);
+ EXPECT_EQ(context.storage->slice_table().depth()[2], 2u);
+ EXPECT_EQ(context.storage->slice_table().depth()[3], 0u);
}
} // namespace
diff --git a/src/trace_processor/stats.h b/src/trace_processor/stats.h
index 97d968b..b64ad6b 100644
--- a/src/trace_processor/stats.h
+++ b/src/trace_processor/stats.h
@@ -29,7 +29,6 @@
F(android_log_num_failed, kSingle, kError, kTrace), \
F(android_log_num_skipped, kSingle, kError, kTrace), \
F(android_log_num_total, kSingle, kInfo, kTrace), \
- F(atrace_tgid_mismatch, kSingle, kError, kTrace), \
F(counter_events_out_of_order, kSingle, kError, kAnalysis), \
F(ftrace_bundle_tokenizer_errors, kSingle, kError, kAnalysis), \
F(ftrace_cpu_bytes_read_begin, kIndexed, kInfo, kTrace), \
diff --git a/src/trace_processor/storage_columns.h b/src/trace_processor/storage_columns.h
index a10f4ba..20678cd 100644
--- a/src/trace_processor/storage_columns.h
+++ b/src/trace_processor/storage_columns.h
@@ -327,7 +327,7 @@
class StringVectorAccessor : public Accessor<NullTermStringView> {
public:
StringVectorAccessor(const std::deque<Id>* deque,
- const std::vector<const char*>* string_map)
+ const std::vector<NullTermStringView>* string_map)
: deque_(deque), string_map_(string_map) {}
~StringVectorAccessor() override = default;
@@ -336,13 +336,12 @@
}
NullTermStringView Get(uint32_t idx) const override {
- const char* ptr = (*string_map_)[static_cast<size_t>((*deque_)[idx])];
- return ptr ? NullTermStringView(ptr) : NullTermStringView();
+ return (*string_map_)[static_cast<size_t>((*deque_)[idx])];
}
private:
const std::deque<Id>* deque_;
- const std::vector<const char*>* string_map_;
+ const std::vector<NullTermStringView>* string_map_;
};
// An accessor implementation for numeric columns which uses a deque as the
diff --git a/src/trace_processor/storage_schema.h b/src/trace_processor/storage_schema.h
index fe7955c..db032bc 100644
--- a/src/trace_processor/storage_schema.h
+++ b/src/trace_processor/storage_schema.h
@@ -76,9 +76,10 @@
}
template <class Id>
- Builder& AddStringColumn(std::string column_name,
- const std::deque<Id>* ids,
- const std::vector<const char*>* string_map) {
+ Builder& AddStringColumn(
+ std::string column_name,
+ const std::deque<Id>* ids,
+ const std::vector<NullTermStringView>* string_map) {
StringVectorAccessor<Id> accessor(ids, string_map);
columns_.emplace_back(
new StringColumn<decltype(accessor)>(column_name, accessor));
diff --git a/src/trace_processor/tables/macros_unittest.cc b/src/trace_processor/tables/macros_unittest.cc
index e1e06b8..46e03da 100644
--- a/src/trace_processor/tables/macros_unittest.cc
+++ b/src/trace_processor/tables/macros_unittest.cc
@@ -189,6 +189,42 @@
ASSERT_EQ(dur->Get(1).long_value, 200);
}
+TEST_F(TableMacrosUnittest, NullableLongCompareWithDouble) {
+ slice_.Insert({});
+
+ TestSliceTable::Row row;
+ row.dur = 100;
+ slice_.Insert(row);
+
+ row.dur = std::numeric_limits<int64_t>::max();
+ slice_.Insert(row);
+
+ row.dur = std::numeric_limits<int64_t>::min();
+ slice_.Insert(row);
+
+ Table out = slice_.Filter({slice_.dur().eq_value(SqlValue::Double(100.0))});
+ const Column* dur = out.GetColumnByName("dur");
+ ASSERT_EQ(out.size(), 1u);
+ ASSERT_EQ(dur->Get(0).long_value, 100);
+
+ out = slice_.Filter({slice_.dur().le_value(SqlValue::Double(99.9999))});
+ dur = out.GetColumnByName("dur");
+ ASSERT_EQ(out.size(), 1u);
+ ASSERT_EQ(dur->Get(0).long_value, std::numeric_limits<int64_t>::min());
+
+ out = slice_.Filter({slice_.dur().ge_value(SqlValue::Double(99.9999))});
+ dur = out.GetColumnByName("dur");
+ ASSERT_EQ(out.size(), 2u);
+ ASSERT_EQ(dur->Get(0).long_value, 100);
+ ASSERT_EQ(dur->Get(1).long_value, std::numeric_limits<int64_t>::max());
+
+ out = slice_.Filter({slice_.dur().eq_value(
+ SqlValue::Double(std::numeric_limits<int64_t>::min()))});
+ dur = out.GetColumnByName("dur");
+ ASSERT_EQ(out.size(), 1u);
+ ASSERT_EQ(dur->Get(0).long_value, std::numeric_limits<int64_t>::min());
+}
+
TEST_F(TableMacrosUnittest, NullableLongCompareWrongType) {
slice_.Insert({});
@@ -209,9 +245,101 @@
out = slice_.Filter({slice_.dur().eq_value(SqlValue::String("100"))});
ASSERT_EQ(out.size(), 0u);
+}
- out = slice_.Filter({slice_.dur().eq_value(SqlValue::Double(100.0))});
- ASSERT_EQ(out.size(), 0u);
+TEST_F(TableMacrosUnittest, NullableDoubleComparision) {
+ counter_.Insert({});
+
+ TestCounterTable::Row row;
+ row.value = 100.0;
+ counter_.Insert(row);
+
+ row.value = 101.0;
+ counter_.Insert(row);
+
+ row.value = 200.0;
+ counter_.Insert(row);
+
+ counter_.Insert({});
+
+ Table out = counter_.Filter({counter_.value().is_null()});
+ const auto* value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 2u);
+ ASSERT_EQ(value->Get(0).type, SqlValue::kNull);
+ ASSERT_EQ(value->Get(1).type, SqlValue::kNull);
+
+ out = counter_.Filter({counter_.value().is_not_null()});
+ value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 3u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100);
+ ASSERT_DOUBLE_EQ(value->Get(1).double_value, 101);
+ ASSERT_DOUBLE_EQ(value->Get(2).double_value, 200);
+
+ out = counter_.Filter({counter_.value().lt(101)});
+ value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 1u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100);
+
+ out = counter_.Filter({counter_.value().eq(101)});
+ value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 1u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value, 101);
+
+ out = counter_.Filter({counter_.value().gt(101)});
+ value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 1u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value, 200);
+
+ out = counter_.Filter({counter_.value().ne(100)});
+ value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 2u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value, 101);
+ ASSERT_DOUBLE_EQ(value->Get(1).double_value, 200);
+
+ out = counter_.Filter({counter_.value().le(101)});
+ value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 2u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100);
+ ASSERT_DOUBLE_EQ(value->Get(1).double_value, 101);
+
+ out = counter_.Filter({counter_.value().ge(101)});
+ value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 2u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value, 101);
+ ASSERT_DOUBLE_EQ(value->Get(1).double_value, 200);
+}
+
+TEST_F(TableMacrosUnittest, NullableDoubleCompareWithLong) {
+ counter_.Insert({});
+
+ TestCounterTable::Row row;
+ row.value = 100.0;
+ counter_.Insert(row);
+
+ row.value = 99.9999;
+ counter_.Insert(row);
+
+ row.value = std::numeric_limits<int64_t>::min();
+ counter_.Insert(row);
+
+ Table out = counter_.Filter({counter_.value().eq_value(SqlValue::Long(100))});
+ const Column* value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 1u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100.0);
+
+ out = counter_.Filter({counter_.value().lt_value(SqlValue::Long(100))});
+ value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 2u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value, 99.9999);
+ ASSERT_DOUBLE_EQ(value->Get(1).double_value,
+ std::numeric_limits<int64_t>::min());
+
+ out = counter_.Filter({counter_.value().eq_value(
+ SqlValue::Long(std::numeric_limits<int64_t>::min()))});
+ value = out.GetColumnByName("value");
+ ASSERT_EQ(out.size(), 1u);
+ ASSERT_DOUBLE_EQ(value->Get(0).double_value,
+ std::numeric_limits<int64_t>::min());
}
TEST_F(TableMacrosUnittest, StringComparision) {
@@ -291,68 +419,6 @@
ASSERT_STREQ(end_state->Get(0).string_value, "D");
}
-TEST_F(TableMacrosUnittest, NullableDoubleComparision) {
- counter_.Insert({});
-
- TestCounterTable::Row row;
- row.value = 100.0;
- counter_.Insert(row);
-
- row.value = 101.0;
- counter_.Insert(row);
-
- row.value = 200.0;
- counter_.Insert(row);
-
- counter_.Insert({});
-
- Table out = counter_.Filter({counter_.value().is_null()});
- const auto* value = out.GetColumnByName("value");
- ASSERT_EQ(out.size(), 2u);
- ASSERT_EQ(value->Get(0).type, SqlValue::kNull);
- ASSERT_EQ(value->Get(1).type, SqlValue::kNull);
-
- out = counter_.Filter({counter_.value().is_not_null()});
- value = out.GetColumnByName("value");
- ASSERT_EQ(out.size(), 3u);
- ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100);
- ASSERT_DOUBLE_EQ(value->Get(1).double_value, 101);
- ASSERT_DOUBLE_EQ(value->Get(2).double_value, 200);
-
- out = counter_.Filter({counter_.value().lt(101)});
- value = out.GetColumnByName("value");
- ASSERT_EQ(out.size(), 1u);
- ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100);
-
- out = counter_.Filter({counter_.value().eq(101)});
- value = out.GetColumnByName("value");
- ASSERT_EQ(out.size(), 1u);
- ASSERT_DOUBLE_EQ(value->Get(0).double_value, 101);
-
- out = counter_.Filter({counter_.value().gt(101)});
- value = out.GetColumnByName("value");
- ASSERT_EQ(out.size(), 1u);
- ASSERT_DOUBLE_EQ(value->Get(0).double_value, 200);
-
- out = counter_.Filter({counter_.value().ne(100)});
- value = out.GetColumnByName("value");
- ASSERT_EQ(out.size(), 2u);
- ASSERT_DOUBLE_EQ(value->Get(0).double_value, 101);
- ASSERT_DOUBLE_EQ(value->Get(1).double_value, 200);
-
- out = counter_.Filter({counter_.value().le(101)});
- value = out.GetColumnByName("value");
- ASSERT_EQ(out.size(), 2u);
- ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100);
- ASSERT_DOUBLE_EQ(value->Get(1).double_value, 101);
-
- out = counter_.Filter({counter_.value().ge(101)});
- value = out.GetColumnByName("value");
- ASSERT_EQ(out.size(), 2u);
- ASSERT_DOUBLE_EQ(value->Get(0).double_value, 101);
- ASSERT_DOUBLE_EQ(value->Get(1).double_value, 200);
-}
-
TEST_F(TableMacrosUnittest, Sort) {
ASSERT_TRUE(event_.ts().IsSorted());
diff --git a/src/trace_processor/tables/slice_tables.h b/src/trace_processor/tables/slice_tables.h
index 06ca534..d4485fb 100644
--- a/src/trace_processor/tables/slice_tables.h
+++ b/src/trace_processor/tables/slice_tables.h
@@ -23,6 +23,23 @@
namespace trace_processor {
namespace tables {
+#define PERFETTO_TP_SLICE_TABLE_DEF(NAME, PARENT, C) \
+ NAME(SliceTable, "internal_slice") \
+ PERFETTO_TP_ROOT_TABLE(PARENT, C) \
+ C(int64_t, ts, Column::Flag::kSorted) \
+ C(int64_t, dur) \
+ C(uint32_t, track_id) \
+ C(int64_t, ref) \
+ C(StringPool::Id, ref_type) \
+ C(StringPool::Id, category) \
+ C(StringPool::Id, name) \
+ C(uint32_t, depth) \
+ C(int64_t, stack_id) \
+ C(int64_t, parent_stack_id) \
+ C(uint32_t, arg_set_id)
+
+PERFETTO_TP_TABLE(PERFETTO_TP_SLICE_TABLE_DEF);
+
#define PERFETTO_TP_GPU_SLICES_DEF(NAME, PARENT, C) \
NAME(GpuSliceTable, "internal_gpu_slice") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
diff --git a/src/trace_processor/trace_processor.cc b/src/trace_processor/trace_processor.cc
index 0a4942a..9be89e5 100644
--- a/src/trace_processor/trace_processor.cc
+++ b/src/trace_processor/trace_processor.cc
@@ -47,7 +47,7 @@
return iterator_->Get(col);
}
-std::string TraceProcessor::Iterator::GetColumName(uint32_t col) {
+std::string TraceProcessor::Iterator::GetColumnName(uint32_t col) {
return iterator_->GetColumnName(col);
}
diff --git a/src/trace_processor/trace_processor_context.h b/src/trace_processor/trace_processor_context.h
index 784b130..7229c15 100644
--- a/src/trace_processor/trace_processor_context.h
+++ b/src/trace_processor/trace_processor_context.h
@@ -26,27 +26,22 @@
namespace perfetto {
namespace trace_processor {
-class AndroidProbesModule;
class ArgsTracker;
class BinderTracker;
class ChunkedTraceReader;
class ClockTracker;
class EventTracker;
class FtraceModule;
-class GraphicsEventModule;
-class HeapGraphModule;
class HeapGraphTracker;
class HeapProfileTracker;
class ProcessTracker;
class SchedEventTracker;
class SliceTracker;
class SyscallTracker;
-class SystemProbesModule;
class SystraceParser;
class TraceParser;
class TraceSorter;
class TraceStorage;
-class TrackEventModule;
class TrackTracker;
class VulkanMemoryTracker;
@@ -75,17 +70,11 @@
std::unique_ptr<VulkanMemoryTracker> vulkan_memory_tracker;
std::unique_ptr<BinderTracker> binder_tracker;
- std::unique_ptr<ProtoImporterModule<FtraceModule>> ftrace_module;
- std::unique_ptr<ProtoImporterModule<TrackEventModule>> track_event_module;
- std::unique_ptr<ProtoImporterModule<SystemProbesModule>> system_probes_module;
- std::unique_ptr<ProtoImporterModule<AndroidProbesModule>>
- android_probes_module;
- std::unique_ptr<ProtoImporterModule<HeapGraphModule>> heap_graph_module;
-
// The module at the index N is registered to handle field id N in
// TracePacket.
- std::vector<NewProtoImporterModule*> modules_by_field;
- std::vector<std::unique_ptr<NewProtoImporterModule>> modules;
+ std::vector<ProtoImporterModule*> modules_by_field;
+ std::vector<std::unique_ptr<ProtoImporterModule>> modules;
+ FtraceModule* ftrace_module;
};
} // namespace trace_processor
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 1a891f6..c1b3873 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -32,7 +32,6 @@
#include "src/trace_processor/process_table.h"
#include "src/trace_processor/raw_table.h"
#include "src/trace_processor/sched_slice_table.h"
-#include "src/trace_processor/slice_table.h"
#include "src/trace_processor/span_join_operator_table.h"
#include "src/trace_processor/sql_stats_table.h"
#include "src/trace_processor/sqlite/db_sqlite_table.h"
@@ -178,6 +177,7 @@
"SELECT "
" *, "
" category AS cat, "
+ " id AS slice_id, "
" CASE ref_type "
" WHEN 'utid' THEN ref "
" ELSE NULL "
@@ -193,7 +193,8 @@
"CREATE VIEW gpu_slice AS "
"SELECT "
"* "
- "FROM internal_gpu_slice join internal_slice using(slice_id);",
+ "FROM internal_gpu_slice join internal_slice "
+ "ON internal_gpu_slice.slice_id = internal_slice.id;",
0, 0, &error);
if (error) {
PERFETTO_ELOG("Error initializing: %s", error);
@@ -376,7 +377,6 @@
#if PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
SchedSliceTable::RegisterTable(*db_, context_.storage.get());
#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
- SliceTable::RegisterTable(*db_, context_.storage.get());
SqlStatsTable::RegisterTable(*db_, context_.storage.get());
ThreadTable::RegisterTable(*db_, context_.storage.get());
SpanJoinOperatorTable::RegisterTable(*db_, context_.storage.get());
@@ -394,14 +394,17 @@
// New style db-backed tables.
const TraceStorage* storage = context_.storage.get();
+ DbSqliteTable::RegisterTable(*db_, &storage->slice_table(),
+ storage->slice_table().table_name());
+ DbSqliteTable::RegisterTable(*db_, &storage->gpu_slice_table(),
+ storage->gpu_slice_table().table_name());
+
DbSqliteTable::RegisterTable(*db_, &storage->track_table(),
storage->track_table().table_name());
DbSqliteTable::RegisterTable(*db_, &storage->thread_track_table(),
storage->thread_track_table().table_name());
DbSqliteTable::RegisterTable(*db_, &storage->process_track_table(),
storage->process_track_table().table_name());
- DbSqliteTable::RegisterTable(*db_, &storage->gpu_slice_table(),
- storage->gpu_slice_table().table_name());
DbSqliteTable::RegisterTable(*db_, &storage->gpu_track_table(),
storage->gpu_track_table().table_name());
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index f7a2877..50877fa 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -171,7 +171,7 @@
fprintf(stderr, "Error stats for this trace:\n");
for (uint32_t i = 0; i < it.ColumnCount(); i++)
- fprintf(stderr, "%40s ", it.GetColumName(i).c_str());
+ fprintf(stderr, "%40s ", it.GetColumnName(i).c_str());
fprintf(stderr, "\n");
for (uint32_t i = 0; i < it.ColumnCount(); i++)
@@ -398,7 +398,7 @@
}
for (uint32_t i = 0; i < it->ColumnCount(); i++)
printf("%-*.*s ", column_width, column_width,
- it->GetColumName(i).c_str());
+ it->GetColumnName(i).c_str());
printf("\n");
std::string divider(column_width, '-');
@@ -489,7 +489,7 @@
for (uint32_t c = 0; c < it->ColumnCount(); c++) {
if (c > 0)
fprintf(output, ",");
- fprintf(output, "\"%s\"", it->GetColumName(c).c_str());
+ fprintf(output, "\"%s\"", it->GetColumnName(c).c_str());
}
fprintf(output, "\n");
diff --git a/src/trace_processor/trace_processor_storage_impl.cc b/src/trace_processor/trace_processor_storage_impl.cc
index da5521b..2ab4afa 100644
--- a/src/trace_processor/trace_processor_storage_impl.cc
+++ b/src/trace_processor/trace_processor_storage_impl.cc
@@ -68,17 +68,27 @@
#if PERFETTO_BUILDFLAG(PERFETTO_TP_GRAPHICS)
context_.vulkan_memory_tracker.reset(new VulkanMemoryTracker(&context_));
#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_GRAPHICS)
- context_.ftrace_module.reset(
- new ProtoImporterModule<FtraceModule>(&context_));
- context_.track_event_module.reset(
- new ProtoImporterModule<TrackEventModule>(&context_));
- context_.system_probes_module.reset(
- new ProtoImporterModule<SystemProbesModule>(&context_));
- context_.android_probes_module.reset(
- new ProtoImporterModule<AndroidProbesModule>(&context_));
- context_.heap_graph_module.reset(
- new ProtoImporterModule<HeapGraphModule>(&context_));
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
+ context_.modules.emplace_back(new FtraceModuleImpl(&context_));
+#else
+ context_.modules.emplace_back(new FtraceModule());
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
+ // Ftrace module is special, because it has one extra method for parsing
+ // ftrace packets. So we need to store a pointer to it separately.
+ context_.ftrace_module =
+ static_cast<FtraceModule*>(context_.modules.back().get());
+
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_HEAP_GRAPHS)
+ context_.modules.emplace_back(new HeapGraphModule(&context_));
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_HEAP_GRAPHS)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_ANDROID_PROBES)
+ context_.modules.emplace_back(new AndroidProbesModule(&context_));
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_ANDROID_PROBES)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_SYSTEM_PROBES)
+ context_.modules.emplace_back(new SystemProbesModule(&context_));
+#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_SYSTEM_PROBES)
+ context_.modules.emplace_back(new TrackEventModule(&context_));
#if PERFETTO_BUILDFLAG(PERFETTO_TP_GRAPHICS)
context_.modules.emplace_back(new GraphicsEventModule(&context_));
#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_GRAPHICS)
diff --git a/src/trace_processor/trace_storage.cc b/src/trace_processor/trace_storage.cc
index 70c2d7e..2f4e872 100644
--- a/src/trace_processor/trace_storage.cc
+++ b/src/trace_processor/trace_storage.cc
@@ -51,9 +51,9 @@
*max_value = std::max(*max_value, column[column.row_map().size() - 1]);
}
-std::vector<const char*> CreateRefTypeStringMap() {
- std::vector<const char*> map(static_cast<size_t>(RefType::kRefMax));
- map[static_cast<size_t>(RefType::kRefNoRef)] = nullptr;
+std::vector<NullTermStringView> CreateRefTypeStringMap() {
+ std::vector<NullTermStringView> map(static_cast<size_t>(RefType::kRefMax));
+ map[static_cast<size_t>(RefType::kRefNoRef)] = NullTermStringView();
map[static_cast<size_t>(RefType::kRefUtid)] = "utid";
map[static_cast<size_t>(RefType::kRefCpuId)] = "cpu";
map[static_cast<size_t>(RefType::kRefGpuId)] = "gpu";
@@ -66,8 +66,8 @@
} // namespace
-const std::vector<const char*>& GetRefTypeStringMap() {
- static const base::NoDestructor<std::vector<const char*>> map(
+const std::vector<NullTermStringView>& GetRefTypeStringMap() {
+ static const base::NoDestructor<std::vector<NullTermStringView>> map(
CreateRefTypeStringMap());
return map.ref();
}
@@ -128,8 +128,6 @@
&start_ns, &end_ns);
MaybeUpdateMinMax(instants_.timestamps().begin(),
instants_.timestamps().end(), &start_ns, &end_ns);
- MaybeUpdateMinMax(nestable_slices_.start_ns().begin(),
- nestable_slices_.start_ns().end(), &start_ns, &end_ns);
MaybeUpdateMinMax(android_log_.timestamps().begin(),
android_log_.timestamps().end(), &start_ns, &end_ns);
MaybeUpdateMinMax(raw_events_.timestamps().begin(),
@@ -139,6 +137,7 @@
&end_ns);
DbTableMaybeUpdateMinMax(counter_table_.ts(), &start_ns, &end_ns);
+ DbTableMaybeUpdateMinMax(slice_table_.ts(), &start_ns, &end_ns);
if (start_ns == std::numeric_limits<int64_t>::max()) {
return std::make_pair(0, 0);
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index 61eb528..56c92a0 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -98,7 +98,7 @@
kRefMax
};
-const std::vector<const char*>& GetRefTypeStringMap();
+const std::vector<NullTermStringView>& GetRefTypeStringMap();
// Stores a data inside a trace file in a columnar form. This makes it efficient
// to read or search across a single field of the trace (e.g. all the thread
@@ -324,78 +324,6 @@
std::deque<std::vector<uint32_t>> rows_for_utids_;
};
- class NestableSlices {
- public:
- inline uint32_t AddSlice(int64_t start_ns,
- int64_t duration_ns,
- TrackId track_id,
- int64_t ref,
- RefType type,
- StringId category,
- StringId name,
- uint8_t depth,
- int64_t stack_id,
- int64_t parent_stack_id) {
- start_ns_.emplace_back(start_ns);
- durations_.emplace_back(duration_ns);
- track_id_.emplace_back(track_id);
- refs_.emplace_back(ref);
- types_.emplace_back(type);
- categories_.emplace_back(category);
- names_.emplace_back(name);
- depths_.emplace_back(depth);
- stack_ids_.emplace_back(stack_id);
- parent_stack_ids_.emplace_back(parent_stack_id);
- arg_set_ids_.emplace_back(kInvalidArgSetId);
- return slice_count() - 1;
- }
-
- void set_name(uint32_t index, StringId name) { names_[index] = name; }
-
- void set_duration(uint32_t index, int64_t duration_ns) {
- durations_[index] = duration_ns;
- }
-
- void set_stack_id(uint32_t index, int64_t stack_id) {
- stack_ids_[index] = stack_id;
- }
-
- void set_arg_set_id(uint32_t index, ArgSetId id) {
- arg_set_ids_[index] = id;
- }
-
- uint32_t slice_count() const {
- return static_cast<uint32_t>(start_ns_.size());
- }
-
- const std::deque<int64_t>& start_ns() const { return start_ns_; }
- const std::deque<int64_t>& durations() const { return durations_; }
- const std::deque<TrackId>& track_id() const { return track_id_; }
- const std::deque<int64_t>& refs() const { return refs_; }
- const std::deque<RefType>& types() const { return types_; }
- const std::deque<StringId>& categories() const { return categories_; }
- const std::deque<StringId>& names() const { return names_; }
- const std::deque<uint8_t>& depths() const { return depths_; }
- const std::deque<int64_t>& stack_ids() const { return stack_ids_; }
- const std::deque<int64_t>& parent_stack_ids() const {
- return parent_stack_ids_;
- }
- const std::deque<ArgSetId>& arg_set_ids() const { return arg_set_ids_; }
-
- private:
- std::deque<int64_t> start_ns_;
- std::deque<int64_t> durations_;
- std::deque<TrackId> track_id_;
- std::deque<int64_t> refs_;
- std::deque<RefType> types_;
- std::deque<StringId> categories_;
- std::deque<StringId> names_;
- std::deque<uint8_t> depths_;
- std::deque<int64_t> stack_ids_;
- std::deque<int64_t> parent_stack_ids_;
- std::deque<ArgSetId> arg_set_ids_;
- };
-
class ThreadSlices {
public:
inline uint32_t AddThreadSlice(uint32_t slice_id,
@@ -1115,8 +1043,8 @@
const Slices& slices() const { return slices_; }
Slices* mutable_slices() { return &slices_; }
- const NestableSlices& nestable_slices() const { return nestable_slices_; }
- NestableSlices* mutable_nestable_slices() { return &nestable_slices_; }
+ const tables::SliceTable& slice_table() const { return slice_table_; }
+ tables::SliceTable* mutable_slice_table() { return &slice_table_; }
const ThreadSlices& thread_slices() const { return thread_slices_; }
ThreadSlices* mutable_thread_slices() { return &thread_slices_; }
@@ -1304,7 +1232,7 @@
std::deque<Thread> unique_threads_;
// Slices coming from userspace events (e.g. Chromium TRACE_EVENT macros).
- NestableSlices nestable_slices_;
+ tables::SliceTable slice_table_{&string_pool_, nullptr};
// Additional attributes for threads slices (sub-type of NestableSlices).
ThreadSlices thread_slices_;
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 9ee7477..6850c0b 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -75,7 +75,7 @@
constexpr int kMaxBuffersPerConsumer = 128;
constexpr base::TimeMillis kSnapshotsInterval(10 * 1000);
constexpr int kDefaultWriteIntoFilePeriodMs = 5000;
-constexpr int kMaxConcurrentTracingSessions = 5;
+constexpr int kMaxConcurrentTracingSessions = 15;
constexpr uint32_t kMillisPerHour = 3600000;
constexpr uint32_t kMaxTracingDurationMillis = 7 * 24 * kMillisPerHour;
diff --git a/test/metrics/heap_profile.textproto b/test/metrics/heap_profile.textproto
index d7dcfd7..7ca4b08 100644
--- a/test/metrics/heap_profile.textproto
+++ b/test/metrics/heap_profile.textproto
@@ -14,6 +14,20 @@
}
}
}
+
+packet {
+ clock_snapshot {
+ clocks: {
+ clock_id: 6 # BOOTTIME
+ timestamp: 0
+ }
+ clocks: {
+ clock_id: 4 # MONOTONIC_COARSE
+ timestamp: 10
+ }
+ }
+}
+
packet {
trusted_packet_sequence_id: 999
previous_packet_dropped: true
diff --git a/tools/dev_server b/tools/dev_server
new file mode 100755
index 0000000..b73e28a
--- /dev/null
+++ b/tools/dev_server
@@ -0,0 +1,167 @@
+# 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.
+
+#!/usr/bin/env python
+from __future__ import print_function
+import sys
+import os
+import time
+import argparse
+import socket
+import subprocess
+
+try:
+ import socketserver
+ from http.server import SimpleHTTPRequestHandler
+except ImportError:
+ import SocketServer as socketserver
+ import SimpleHTTPServer
+ SimpleHTTPRequestHandler = SimpleHTTPServer.SimpleHTTPRequestHandler
+
+
+class TCPServer(socketserver.TCPServer):
+
+ def server_bind(self):
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ self.socket.bind(self.server_address)
+
+
+class Server(object):
+
+ def __init__(self, port, directory, rebuilder):
+ self.port = port
+ self.directory = directory
+ self.rebuilder = rebuilder
+
+ def serve(self):
+ this = self
+
+ class Handler(SimpleHTTPRequestHandler):
+
+ def __init__(self, *args, **kwargs):
+ SimpleHTTPRequestHandler.__init__(self, *args, **kwargs)
+
+ def translate_path(self, path):
+ path = SimpleHTTPRequestHandler.translate_path(self, path)
+ relpath = os.path.relpath(path, os.getcwd())
+ fullpath = os.path.join(this.directory, relpath)
+ return fullpath
+
+ def do_GET(self):
+ try:
+ this.rebuilder.rebuild_if_needed()
+ except RebuildFailed as e:
+ self.send_response(200)
+ self.send_header("Content-type", "text/html")
+ self.end_headers()
+ self.wfile.write(e.stdout_and_stderr)
+ return
+ return SimpleHTTPRequestHandler.do_GET(self)
+
+ print('Starting server at http://localhost:{}'.format(self.port))
+ httpd = TCPServer(('', self.port), Handler)
+ try:
+ httpd.serve_forever()
+ except KeyboardInterrupt:
+ httpd.shutdown()
+ httpd.server_close()
+
+
+class RebuildFailed(Exception):
+
+ def __init__(self, stdout_and_stderr):
+ self.stdout_and_stderr = stdout_and_stderr
+
+
+class Rebuilder(object):
+
+ def __init__(self, command, ignored_paths):
+ self.command = command
+ self.ignored_paths = ignored_paths
+ self.last_disk_state = None
+
+ def rebuild_if_needed(self):
+ if self.last_disk_state == self.last_modified_time():
+ return
+ stdout_and_stderr, success = self.rebuild()
+ if not success:
+ message = b"Failed to build! Command output:\n\n" + stdout_and_stderr
+ raise RebuildFailed(message)
+ self.last_disk_state = self.last_modified_time()
+
+ def last_modified_time(self):
+ start_time = time.time()
+ max_mtime = 0
+ for dirpath, dirnames, filenames in os.walk('.', topdown=True):
+ dirnames[:] = [
+ n for n in dirnames
+ if not self.should_ignore_path(os.path.join(dirpath, n))
+ ]
+ for filename in filenames:
+ path = os.path.join(dirpath, filename)
+ if self.should_ignore_path(path):
+ continue
+ mtime = os.stat(path).st_mtime
+ max_mtime = max(max_mtime, mtime)
+ print(' scanned in {:.03f}s'.format(time.time() - start_time).rjust(
+ 80, '='))
+ return max_mtime
+
+ def should_ignore_path(self, path):
+ return os.path.abspath(path) in (
+ os.path.abspath(p) for p in self.ignored_paths)
+
+ def rebuild(self):
+ print('Running command: {}'.format(self.command))
+ print(' begin build'.rjust(80, '='))
+ start_time = time.time()
+ status = 0
+ try:
+ stdout_and_stderr = subprocess.check_output(
+ self.command, shell=True, stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as e:
+ status = e.returncode
+ stdout_and_stderr = e.output
+ print(stdout_and_stderr.decode('utf8'))
+ print(' built in {:.03f}s'.format(time.time() - start_time).rjust(80, '='))
+ return stdout_and_stderr, status == 0
+
+
+def main(argv):
+ parser = argparse.ArgumentParser(description='HTTP server for UI development')
+ parser.add_argument(
+ '-p',
+ '--port',
+ help='port number (default: 3000)',
+ type=int,
+ default=3000)
+ parser.add_argument(
+ '-i', '--ignore', default=[], action='append', help='Ignore this path')
+ parser.add_argument(
+ '-s',
+ '--serve',
+ default=os.getcwd(),
+ help='Serve this directory (default: current directory)')
+ parser.add_argument('command', default='', nargs='?', help='Command to run')
+
+ args = parser.parse_args(argv)
+
+ rebuilder = Rebuilder(args.command, args.ignore)
+ server = Server(args.port, args.serve, rebuilder)
+ server.serve()
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/ui/bs-config.js b/ui/bs-config.js
deleted file mode 100644
index b93c74c..0000000
--- a/ui/bs-config.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2018 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.
-
-/**
- * Configuration file for lite-server. Contains configuration for auto rerunning
- * ninja on file change.
- */
-'use strict';
-
-const { spawn } = require('child_process');
-const path = require('path');
-
-// Print without added new line.
-const print = data => process.stdout.write(data);
-const printErr = data => process.stderr.write(data);
-
-const ninjaOutDir = process.env.OUT_DIR;
-const uiOutDir = path.join(ninjaOutDir, 'ui');
-const perfettoRoot = process.env.ROOT_DIR;
-const ninjaPath = path.join(perfettoRoot, 'tools', 'ninja');
-let ninjaRunning = false;
-
-function rebasePath(relative_path) {
- return path.join(perfettoRoot, relative_path);
-}
-
-module.exports = function(bs) {
- return {
- files: [
- {
- match: [
- "ui/**",
- "src/trace_processor/**",
- "protos/**",
- ].map(rebasePath),
- fn: function(event, file) {
- console.log(`Change detected on ${file}`);
- if (ninjaRunning) {
- console.log("Already have a ninja build running. Doing nothing.");
- return;
- }
-
- ninjaRunning = true;
-
- console.log(`Executing: ninja -C ${ninjaOutDir} ui`);
- const ninja = spawn(ninjaPath, ['-C', ninjaOutDir, 'ui']);
- ninja.stdout.on('data', data => print(data.toString()));
- ninja.stderr.on('data', data => printErr(data.toString()));
-
- // We can be smarter and load just the file we need. Need to
- // resolve to the dist/location of the file in that case.
- // For now, we're reloading the whole page.
- ninja.on('exit', () => {
- ninjaRunning = false;
- bs.reload();
- });
- },
- options: {
- ignored: [
- "ui/dist/",
- "ui/.git/",
- "ui/node_modules/",
- ].map(rebasePath),
- ignoreInitial: true,
- }
- }
- ],
- server: {
- baseDir: uiOutDir,
- },
- };
-};
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 61d7ad6..2b06d8c 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -200,16 +200,6 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true
},
- "accepts": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
- "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
- "dev": true,
- "requires": {
- "mime-types": "~2.1.18",
- "negotiator": "0.6.1"
- }
- },
"acorn": {
"version": "5.7.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
@@ -240,12 +230,6 @@
"integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==",
"dev": true
},
- "after": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
- "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
- "dev": true
- },
"ajv": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz",
@@ -661,12 +645,6 @@
"integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
"dev": true
},
- "arraybuffer.slice": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
- "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==",
- "dev": true
- },
"arrify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
@@ -709,18 +687,6 @@
"lodash": "^4.17.11"
}
},
- "async-each": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
- "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
- "dev": true
- },
- "async-each-series": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz",
- "integrity": "sha1-dhfBkXQB/Yykooqtzj266Yr+tDI=",
- "dev": true
- },
"async-foreach": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
@@ -983,12 +949,6 @@
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
"dev": true
},
- "backo2": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
- "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
- "dev": true
- },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -1062,24 +1022,6 @@
}
}
},
- "base64-arraybuffer": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
- "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
- "dev": true
- },
- "base64id": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
- "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=",
- "dev": true
- },
- "batch": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
- "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
- "dev": true
- },
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -1089,27 +1031,6 @@
"tweetnacl": "^0.14.3"
}
},
- "better-assert": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
- "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
- "dev": true,
- "requires": {
- "callsite": "1.0.0"
- }
- },
- "binary-extensions": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz",
- "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==",
- "dev": true
- },
- "blob": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
- "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==",
- "dev": true
- },
"block-stream": {
"version": "0.0.9",
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
@@ -1163,565 +1084,6 @@
}
}
},
- "browser-sync": {
- "version": "2.26.7",
- "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.7.tgz",
- "integrity": "sha512-lY3emme0OyvA2ujEMpRmyRy9LY6gHLuTr2/ABxhIm3lADOiRXzP4dgekvnDrQqZ/Ec2Fz19lEjm6kglSG5766w==",
- "dev": true,
- "requires": {
- "browser-sync-client": "^2.26.6",
- "browser-sync-ui": "^2.26.4",
- "bs-recipes": "1.3.4",
- "bs-snippet-injector": "^2.0.1",
- "chokidar": "^2.0.4",
- "connect": "3.6.6",
- "connect-history-api-fallback": "^1",
- "dev-ip": "^1.0.1",
- "easy-extender": "^2.3.4",
- "eazy-logger": "^3",
- "etag": "^1.8.1",
- "fresh": "^0.5.2",
- "fs-extra": "3.0.1",
- "http-proxy": "1.15.2",
- "immutable": "^3",
- "localtunnel": "1.9.2",
- "micromatch": "^3.1.10",
- "opn": "5.3.0",
- "portscanner": "2.1.1",
- "qs": "6.2.3",
- "raw-body": "^2.3.2",
- "resp-modifier": "6.0.2",
- "rx": "4.1.0",
- "send": "0.16.2",
- "serve-index": "1.9.1",
- "serve-static": "1.13.2",
- "server-destroy": "1.0.1",
- "socket.io": "2.1.1",
- "ua-parser-js": "0.7.17",
- "yargs": "6.4.0"
- },
- "dependencies": {
- "arr-diff": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
- "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
- "dev": true
- },
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true
- },
- "axios": {
- "version": "0.19.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
- "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==",
- "dev": true,
- "requires": {
- "follow-redirects": "1.5.10",
- "is-buffer": "^2.0.2"
- }
- },
- "braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "dev": true,
- "requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "browser-sync-client": {
- "version": "2.26.6",
- "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.6.tgz",
- "integrity": "sha512-mGrkZdNzttKdf/16I+y+2dTQxoMCIpKbVIMJ/uP8ZpnKu9f9qa/2CYVtLtbjZG8nsM14EwiCrjuFTGBEnT3Gjw==",
- "dev": true,
- "requires": {
- "etag": "1.8.1",
- "fresh": "0.5.2",
- "mitt": "^1.1.3",
- "rxjs": "^5.5.6"
- }
- },
- "browser-sync-ui": {
- "version": "2.26.4",
- "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.4.tgz",
- "integrity": "sha512-u20P3EsZoM8Pt+puoi3BU3KlbQAH1lAcV+/O4saF26qokrBqIDotmGonfWwoRbUmdxZkM9MBmA0K39ZTG1h4sA==",
- "dev": true,
- "requires": {
- "async-each-series": "0.1.1",
- "connect-history-api-fallback": "^1",
- "immutable": "^3",
- "server-destroy": "1.0.1",
- "socket.io-client": "^2.0.4",
- "stream-throttle": "^0.1.3"
- }
- },
- "camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
- "dev": true
- },
- "cliui": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
- "dev": true,
- "requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wrap-ansi": "^2.0.0"
- }
- },
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- },
- "dependencies": {
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- }
- }
- },
- "expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
- "dev": true,
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
- },
- "is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- }
- },
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
- "extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "dev": true,
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "follow-redirects": {
- "version": "1.5.10",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
- "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
- "dev": true,
- "requires": {
- "debug": "=3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-buffer": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
- "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
- "dev": true
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "dev": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
- },
- "kind-of": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
- "dev": true
- },
- "localtunnel": {
- "version": "1.9.2",
- "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.2.tgz",
- "integrity": "sha512-NEKF7bDJE9U3xzJu3kbayF0WTvng6Pww7tzqNb/XtEARYwqw7CKEX7BvOMg98FtE9es2CRizl61gkV3hS8dqYg==",
- "dev": true,
- "requires": {
- "axios": "0.19.0",
- "debug": "4.1.1",
- "openurl": "1.1.1",
- "yargs": "6.6.0"
- },
- "dependencies": {
- "yargs": {
- "version": "6.6.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
- "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
- "dev": true,
- "requires": {
- "camelcase": "^3.0.0",
- "cliui": "^3.2.0",
- "decamelize": "^1.1.1",
- "get-caller-file": "^1.0.1",
- "os-locale": "^1.4.0",
- "read-pkg-up": "^1.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^1.0.2",
- "which-module": "^1.0.0",
- "y18n": "^3.2.1",
- "yargs-parser": "^4.2.0"
- }
- }
- }
- },
- "micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
- }
- },
- "os-locale": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
- "dev": true,
- "requires": {
- "lcid": "^1.0.0"
- }
- },
- "qs": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz",
- "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=",
- "dev": true
- },
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "dev": true,
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "which-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
- "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
- "dev": true
- },
- "yargs": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz",
- "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=",
- "dev": true,
- "requires": {
- "camelcase": "^3.0.0",
- "cliui": "^3.2.0",
- "decamelize": "^1.1.1",
- "get-caller-file": "^1.0.1",
- "os-locale": "^1.4.0",
- "read-pkg-up": "^1.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^1.0.2",
- "which-module": "^1.0.0",
- "window-size": "^0.2.0",
- "y18n": "^3.2.1",
- "yargs-parser": "^4.1.0"
- }
- },
- "yargs-parser": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
- "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
- "dev": true,
- "requires": {
- "camelcase": "^3.0.0"
- }
- }
- }
- },
- "bs-recipes": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz",
- "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=",
- "dev": true
- },
- "bs-snippet-injector": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz",
- "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=",
- "dev": true
- },
"bser": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz",
@@ -1749,12 +1111,6 @@
"integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==",
"dev": true
},
- "bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
- "dev": true
- },
"cache-base": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
@@ -1780,12 +1136,6 @@
}
}
},
- "callsite": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
- "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
- "dev": true
- },
"callsites": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
@@ -1842,130 +1192,6 @@
"supports-color": "^5.3.0"
}
},
- "chokidar": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.1.tgz",
- "integrity": "sha512-gfw3p2oQV2wEt+8VuMlNsPjCxDxvvgnm/kz+uATu805mWVF8IJN7uz9DN7iBz+RMJISmiVbCOBFs9qBGMjtPfQ==",
- "dev": true,
- "requires": {
- "anymatch": "^2.0.0",
- "async-each": "^1.0.1",
- "braces": "^2.3.2",
- "fsevents": "^1.2.7",
- "glob-parent": "^3.1.0",
- "inherits": "^2.0.3",
- "is-binary-path": "^1.0.0",
- "is-glob": "^4.0.0",
- "normalize-path": "^3.0.0",
- "path-is-absolute": "^1.0.0",
- "readdirp": "^2.2.1",
- "upath": "^1.1.0"
- },
- "dependencies": {
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true
- },
- "braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "dev": true,
- "requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- }
- },
- "glob-parent": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
- "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
- "dev": true,
- "requires": {
- "is-glob": "^3.1.0",
- "path-dirname": "^1.0.0"
- },
- "dependencies": {
- "is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
- "dev": true,
- "requires": {
- "is-extglob": "^2.1.0"
- }
- }
- }
- },
- "is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "dev": true
- },
- "is-glob": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
- "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
- "dev": true,
- "requires": {
- "is-extglob": "^2.1.1"
- }
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- }
- },
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
- },
- "normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true
- }
- }
- },
"ci-info": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
@@ -2062,24 +1288,12 @@
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
"dev": true
},
- "component-bind": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
- "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
- "dev": true
- },
"component-emitter": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
"dev": true
},
- "component-inherit": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
- "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
- "dev": true
- },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2098,33 +1312,6 @@
"typedarray": "^0.0.6"
}
},
- "connect": {
- "version": "3.6.6",
- "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
- "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "finalhandler": "1.1.0",
- "parseurl": "~1.3.2",
- "utils-merge": "1.0.1"
- }
- },
- "connect-history-api-fallback": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
- "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
- "dev": true
- },
- "connect-logger": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/connect-logger/-/connect-logger-0.0.1.tgz",
- "integrity": "sha1-TZmZeKHSC7RgjnzUNNdBZSJVF0s=",
- "dev": true,
- "requires": {
- "moment": "*"
- }
- },
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
@@ -2140,12 +1327,6 @@
"safe-buffer": "~5.1.1"
}
},
- "cookie": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
- "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
- "dev": true
- },
"copy-descriptor": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
@@ -2344,18 +1525,6 @@
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
"dev": true
},
- "depd": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
- "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
- "dev": true
- },
- "destroy": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
- "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
- "dev": true
- },
"detect-indent": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
@@ -2371,12 +1540,6 @@
"integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
"dev": true
},
- "dev-ip": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz",
- "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=",
- "dev": true
- },
"devtools-protocol": {
"version": "0.0.681549",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.681549.tgz",
@@ -2403,24 +1566,6 @@
"webidl-conversions": "^4.0.2"
}
},
- "easy-extender": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz",
- "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==",
- "dev": true,
- "requires": {
- "lodash": "^4.17.10"
- }
- },
- "eazy-logger": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.0.2.tgz",
- "integrity": "sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw=",
- "dev": true,
- "requires": {
- "tfunk": "^3.0.1"
- }
- },
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -2431,106 +1576,6 @@
"safer-buffer": "^2.1.0"
}
},
- "ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
- "dev": true
- },
- "encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
- "dev": true
- },
- "engine.io": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz",
- "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==",
- "dev": true,
- "requires": {
- "accepts": "~1.3.4",
- "base64id": "1.0.0",
- "cookie": "0.3.1",
- "debug": "~3.1.0",
- "engine.io-parser": "~2.1.0",
- "ws": "~3.3.1"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ws": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
- "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
- "dev": true,
- "requires": {
- "async-limiter": "~1.0.0",
- "safe-buffer": "~5.1.0",
- "ultron": "~1.1.0"
- }
- }
- }
- },
- "engine.io-client": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz",
- "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==",
- "dev": true,
- "requires": {
- "component-emitter": "1.2.1",
- "component-inherit": "0.0.3",
- "debug": "~3.1.0",
- "engine.io-parser": "~2.1.1",
- "has-cors": "1.1.0",
- "indexof": "0.0.1",
- "parseqs": "0.0.5",
- "parseuri": "0.0.5",
- "ws": "~6.1.0",
- "xmlhttprequest-ssl": "~1.5.4",
- "yeast": "0.1.2"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ws": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.3.tgz",
- "integrity": "sha512-tbSxiT+qJI223AP4iLfQbkbxkwdFcneYinM2+x46Gx2wgvbaOMO36czfdfVUBRTHvzAMRhDd98sA5d/BuWbQdg==",
- "dev": true,
- "requires": {
- "async-limiter": "~1.0.0"
- }
- }
- }
- },
- "engine.io-parser": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz",
- "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==",
- "dev": true,
- "requires": {
- "after": "0.8.2",
- "arraybuffer.slice": "~0.0.7",
- "base64-arraybuffer": "0.1.5",
- "blob": "0.0.5",
- "has-binary2": "~1.0.2"
- }
- },
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -2586,12 +1631,6 @@
}
}
},
- "escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
- "dev": true
- },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -2650,18 +1689,6 @@
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"dev": true
},
- "etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
- "dev": true
- },
- "eventemitter3": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
- "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=",
- "dev": true
- },
"events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
@@ -2848,21 +1875,6 @@
"repeat-string": "^1.5.2"
}
},
- "finalhandler": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
- "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.1",
- "escape-html": "~1.0.3",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.2",
- "statuses": "~1.3.1",
- "unpipe": "~1.0.0"
- }
- },
"find-up": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
@@ -2913,23 +1925,6 @@
"map-cache": "^0.2.2"
}
},
- "fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
- "dev": true
- },
- "fs-extra": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz",
- "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^3.0.0",
- "universalify": "^0.1.0"
- }
- },
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -3686,29 +2681,6 @@
"ansi-regex": "^2.0.0"
}
},
- "has-binary2": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
- "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
- "dev": true,
- "requires": {
- "isarray": "2.0.1"
- },
- "dependencies": {
- "isarray": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
- "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
- "dev": true
- }
- }
- },
- "has-cors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
- "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
- "dev": true
- },
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -3811,36 +2783,6 @@
"whatwg-encoding": "^1.0.1"
}
},
- "http-errors": {
- "version": "1.6.3",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
- "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
- "dev": true,
- "requires": {
- "depd": "~1.1.2",
- "inherits": "2.0.3",
- "setprototypeof": "1.1.0",
- "statuses": ">= 1.4.0 < 2"
- },
- "dependencies": {
- "statuses": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
- "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
- "dev": true
- }
- }
- },
- "http-proxy": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz",
- "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=",
- "dev": true,
- "requires": {
- "eventemitter3": "1.x.x",
- "requires-port": "1.x.x"
- }
- },
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -3902,12 +2844,6 @@
"resolved": "https://registry.npmjs.org/immer/-/immer-1.12.1.tgz",
"integrity": "sha512-3fmKM6ovaqDt0CdC9daXpNi5x/YCYS3i4cwLdTVkhJdk5jrDXoPs7lCm3IqM3yhfSnz4tjjxbRG2CziQ7m8ztg=="
},
- "immutable": {
- "version": "3.8.2",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
- "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=",
- "dev": true
- },
"import-local": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz",
@@ -3939,12 +2875,6 @@
"repeating": "^2.0.0"
}
},
- "indexof": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
- "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
- "dev": true
- },
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -3995,15 +2925,6 @@
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
"dev": true
},
- "is-binary-path": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
- "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
- "dev": true,
- "requires": {
- "binary-extensions": "^1.0.0"
- }
- },
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -4134,15 +3055,6 @@
"kind-of": "^3.0.2"
}
},
- "is-number-like": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz",
- "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==",
- "dev": true,
- "requires": {
- "lodash.isfinite": "^3.3.2"
- }
- },
"is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -4862,15 +3774,6 @@
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
"dev": true
},
- "jsonfile": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz",
- "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.6"
- }
- },
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -4929,25 +3832,6 @@
"type-check": "~0.3.2"
}
},
- "limiter": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.4.tgz",
- "integrity": "sha512-XCpr5bElgDI65vVgstP8TWjv6/QKWm9GU5UG0Pr5sLQ3QLo8NVKsioe+Jed5/3vFOe3IQuqE7DKwTvKQkjTHvg==",
- "dev": true
- },
- "lite-server": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/lite-server/-/lite-server-2.4.0.tgz",
- "integrity": "sha512-Vo06tHpXrqm37i6T7tVdq5PSbrFmvQRw64+dlFXdh1tltv6KCvpE+xzXz2+x6KWJ8ja+GgwSy4P13GUWyhaDHQ==",
- "dev": true,
- "requires": {
- "browser-sync": "^2.24.4",
- "connect-history-api-fallback": "^1.2.0",
- "connect-logger": "0.0.1",
- "lodash": "^4.11.1",
- "minimist": "1.2.0"
- }
- },
"load-json-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
@@ -4977,12 +3861,6 @@
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
- "lodash.isfinite": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz",
- "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=",
- "dev": true
- },
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -5144,12 +4022,6 @@
"resolved": "https://registry.npmjs.org/micromodal/-/micromodal-0.4.0.tgz",
"integrity": "sha512-YDku9Fi57S4Sm6oitSy3sr786qSp5L6NbatuH2kEeXf0jStvZgZk4bLBKaoSONBaq3BEvFz3hAaoUa7/pV1Kgg=="
},
- "mime": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
- "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
- "dev": true
- },
"mime-db": {
"version": "1.38.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
@@ -5191,12 +4063,6 @@
"resolved": "https://registry.npmjs.org/mithril/-/mithril-1.1.7.tgz",
"integrity": "sha512-1SAkGeVrIVvkUHlPHvR3pXdWzNfTzmS/fBAe+rC2ApEBfZFFc+idi8Qg/M5JoW/sZkIDXSfQYVgvENMIhBIVAg=="
},
- "mitt": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz",
- "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==",
- "dev": true
- },
"mixin-deep": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
@@ -5235,12 +4101,6 @@
}
}
},
- "moment": {
- "version": "2.24.0",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
- "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==",
- "dev": true
- },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -5299,12 +4159,6 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
- "negotiator": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
- "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
- "dev": true
- },
"neo-async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
@@ -5532,12 +4386,6 @@
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true
},
- "object-component": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
- "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
- "dev": true
- },
"object-copy": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
@@ -5565,12 +4413,6 @@
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz",
"integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg=="
},
- "object-path": {
- "version": "0.9.2",
- "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz",
- "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=",
- "dev": true
- },
"object-visit": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
@@ -5636,15 +4478,6 @@
}
}
},
- "on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
- "dev": true,
- "requires": {
- "ee-first": "1.1.1"
- }
- },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -5654,21 +4487,6 @@
"wrappy": "1"
}
},
- "openurl": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz",
- "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=",
- "dev": true
- },
- "opn": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
- "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
- "dev": true,
- "requires": {
- "is-wsl": "^1.1.0"
- }
- },
"optimist": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
@@ -5804,42 +4622,12 @@
"integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
"dev": true
},
- "parseqs": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
- "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
- "dev": true,
- "requires": {
- "better-assert": "~1.0.0"
- }
- },
- "parseuri": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
- "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
- "dev": true,
- "requires": {
- "better-assert": "~1.0.0"
- }
- },
- "parseurl": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
- "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
- "dev": true
- },
"pascalcase": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
"dev": true
},
- "path-dirname": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
- "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
- "dev": true
- },
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
@@ -5923,24 +4711,6 @@
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
"dev": true
},
- "portscanner": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz",
- "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=",
- "dev": true,
- "requires": {
- "async": "1.5.2",
- "is-number-like": "^1.0.3"
- },
- "dependencies": {
- "async": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
- "dev": true
- }
- }
- },
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@@ -6135,35 +4905,6 @@
}
}
},
- "range-parser": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
- "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
- "dev": true
- },
- "raw-body": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
- "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
- "dev": true,
- "requires": {
- "bytes": "3.0.0",
- "http-errors": "1.6.3",
- "iconv-lite": "0.4.23",
- "unpipe": "1.0.0"
- },
- "dependencies": {
- "iconv-lite": {
- "version": "0.4.23",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
- "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
- "dev": true,
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- }
- }
- },
"read-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
@@ -6221,293 +4962,6 @@
"util-deprecate": "~1.0.1"
}
},
- "readdirp": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
- "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.11",
- "micromatch": "^3.1.10",
- "readable-stream": "^2.0.2"
- },
- "dependencies": {
- "arr-diff": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
- "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
- "dev": true
- },
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true
- },
- "braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "dev": true,
- "requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
- "dev": true,
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- }
- },
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
- "extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "dev": true,
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
- },
- "kind-of": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
- "dev": true
- },
- "micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
- }
- }
- }
- },
"realpath-native": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz",
@@ -6657,12 +5111,6 @@
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
"dev": true
},
- "requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
- "dev": true
- },
"resolve": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz",
@@ -6701,16 +5149,6 @@
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
"dev": true
},
- "resp-modifier": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz",
- "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=",
- "dev": true,
- "requires": {
- "debug": "^2.2.0",
- "minimatch": "^3.0.2"
- }
- },
"ret": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
@@ -6798,21 +5236,6 @@
"integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==",
"dev": true
},
- "rx": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
- "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
- "dev": true
- },
- "rxjs": {
- "version": "5.5.12",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz",
- "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==",
- "dev": true,
- "requires": {
- "symbol-observable": "1.0.1"
- }
- },
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -7276,68 +5699,6 @@
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
"dev": true
},
- "send": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
- "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "destroy": "~1.0.4",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "~1.6.2",
- "mime": "1.4.1",
- "ms": "2.0.0",
- "on-finished": "~2.3.0",
- "range-parser": "~1.2.0",
- "statuses": "~1.4.0"
- },
- "dependencies": {
- "statuses": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
- "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
- "dev": true
- }
- }
- },
- "serve-index": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
- "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
- "dev": true,
- "requires": {
- "accepts": "~1.3.4",
- "batch": "0.6.1",
- "debug": "2.6.9",
- "escape-html": "~1.0.3",
- "http-errors": "~1.6.2",
- "mime-types": "~2.1.17",
- "parseurl": "~1.3.2"
- }
- },
- "serve-static": {
- "version": "1.13.2",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
- "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
- "dev": true,
- "requires": {
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.2",
- "send": "0.16.2"
- }
- },
- "server-destroy": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz",
- "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=",
- "dev": true
- },
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
@@ -7367,12 +5728,6 @@
}
}
},
- "setprototypeof": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
- "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
- "dev": true
- },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -7520,167 +5875,6 @@
"kind-of": "^3.2.0"
}
},
- "socket.io": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz",
- "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==",
- "dev": true,
- "requires": {
- "debug": "~3.1.0",
- "engine.io": "~3.2.0",
- "has-binary2": "~1.0.2",
- "socket.io-adapter": "~1.1.0",
- "socket.io-client": "2.1.1",
- "socket.io-parser": "~3.2.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "engine.io-client": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz",
- "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==",
- "dev": true,
- "requires": {
- "component-emitter": "1.2.1",
- "component-inherit": "0.0.3",
- "debug": "~3.1.0",
- "engine.io-parser": "~2.1.1",
- "has-cors": "1.1.0",
- "indexof": "0.0.1",
- "parseqs": "0.0.5",
- "parseuri": "0.0.5",
- "ws": "~3.3.1",
- "xmlhttprequest-ssl": "~1.5.4",
- "yeast": "0.1.2"
- }
- },
- "isarray": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
- "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
- "dev": true
- },
- "socket.io-client": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz",
- "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==",
- "dev": true,
- "requires": {
- "backo2": "1.0.2",
- "base64-arraybuffer": "0.1.5",
- "component-bind": "1.0.0",
- "component-emitter": "1.2.1",
- "debug": "~3.1.0",
- "engine.io-client": "~3.2.0",
- "has-binary2": "~1.0.2",
- "has-cors": "1.1.0",
- "indexof": "0.0.1",
- "object-component": "0.0.3",
- "parseqs": "0.0.5",
- "parseuri": "0.0.5",
- "socket.io-parser": "~3.2.0",
- "to-array": "0.1.4"
- }
- },
- "socket.io-parser": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz",
- "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==",
- "dev": true,
- "requires": {
- "component-emitter": "1.2.1",
- "debug": "~3.1.0",
- "isarray": "2.0.1"
- }
- },
- "ws": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
- "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
- "dev": true,
- "requires": {
- "async-limiter": "~1.0.0",
- "safe-buffer": "~5.1.0",
- "ultron": "~1.1.0"
- }
- }
- }
- },
- "socket.io-adapter": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz",
- "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=",
- "dev": true
- },
- "socket.io-client": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz",
- "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==",
- "dev": true,
- "requires": {
- "backo2": "1.0.2",
- "base64-arraybuffer": "0.1.5",
- "component-bind": "1.0.0",
- "component-emitter": "1.2.1",
- "debug": "~3.1.0",
- "engine.io-client": "~3.3.1",
- "has-binary2": "~1.0.2",
- "has-cors": "1.1.0",
- "indexof": "0.0.1",
- "object-component": "0.0.3",
- "parseqs": "0.0.5",
- "parseuri": "0.0.5",
- "socket.io-parser": "~3.3.0",
- "to-array": "0.1.4"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "socket.io-parser": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz",
- "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
- "dev": true,
- "requires": {
- "component-emitter": "1.2.1",
- "debug": "~3.1.0",
- "isarray": "2.0.1"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "isarray": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
- "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
- "dev": true
- }
- }
- },
"sorcery": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz",
@@ -7824,12 +6018,6 @@
}
}
},
- "statuses": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
- "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
- "dev": true
- },
"stdout-stream": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
@@ -7845,16 +6033,6 @@
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
"dev": true
},
- "stream-throttle": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz",
- "integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=",
- "dev": true,
- "requires": {
- "commander": "^2.2.0",
- "limiter": "^1.0.5"
- }
- },
"string-length": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
@@ -7934,12 +6112,6 @@
"has-flag": "^3.0.0"
}
},
- "symbol-observable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
- "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=",
- "dev": true
- },
"symbol-tree": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
@@ -7970,52 +6142,6 @@
"require-main-filename": "^1.0.1"
}
},
- "tfunk": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz",
- "integrity": "sha1-OORBT8ZJd9h6/apy+sttKfgve1s=",
- "dev": true,
- "requires": {
- "chalk": "^1.1.1",
- "object-path": "^0.9.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
- "dev": true
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "dev": true,
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
- "dev": true
- }
- }
- },
"throat": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz",
@@ -8028,12 +6154,6 @@
"integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
"dev": true
},
- "to-array": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
- "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
- "dev": true
- },
"to-fast-properties": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
@@ -8212,12 +6332,6 @@
"integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==",
"dev": true
},
- "ua-parser-js": {
- "version": "0.7.17",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
- "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==",
- "dev": true
- },
"uglify-js": {
"version": "3.4.9",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
@@ -8238,12 +6352,6 @@
}
}
},
- "ultron": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
- "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
- "dev": true
- },
"union-value": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
@@ -8256,18 +6364,6 @@
"set-value": "^2.0.1"
}
},
- "universalify": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
- "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
- "dev": true
- },
- "unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
- "dev": true
- },
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
@@ -8314,12 +6410,6 @@
}
}
},
- "upath": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz",
- "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==",
- "dev": true
- },
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@@ -8369,12 +6459,6 @@
"object.getownpropertydescriptors": "^2.0.3"
}
},
- "utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
- "dev": true
- },
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
@@ -8485,12 +6569,6 @@
"string-width": "^1.0.2 || 2"
}
},
- "window-size": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
- "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
- "dev": true
- },
"wordwrap": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
@@ -8570,12 +6648,6 @@
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true
},
- "xmlhttprequest-ssl": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
- "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=",
- "dev": true
- },
"y18n": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
@@ -8625,12 +6697,6 @@
"requires": {
"fd-slicer": "~1.0.1"
}
- },
- "yeast": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
- "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
- "dev": true
}
}
}
diff --git a/ui/package.json b/ui/package.json
index dd44b6f..6a0f0f8 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -4,10 +4,6 @@
"description": "Perfetto UI",
"repository": "https://android.googlesource.com/platform/external/perfetto",
"main": "main.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1",
- "dev": "lite-server --baseDir=dist"
- },
"author": "Perfetto Team",
"license": "Apache-2.0",
"dependencies": {
@@ -37,7 +33,6 @@
"@types/puppeteer": "^1.12.4",
"dingusjs": "^0.0.3",
"jest": "^23.6.0",
- "lite-server": "^2.4.0",
"node-sass": "^4.12.0",
"puppeteer": "^1.16.0",
"rollup": "^1.17.0",
diff --git a/ui/run-dev-server b/ui/run-dev-server
index e42a940..843d2ac 100755
--- a/ui/run-dev-server
+++ b/ui/run-dev-server
@@ -15,15 +15,7 @@
UI_DIR="$(cd -P ${BASH_SOURCE[0]%/*}; pwd)"
ROOT_DIR=$(dirname "$UI_DIR")
-NODE=$ROOT_DIR/buildtools/nodejs/bin/node
-LITE="$UI_DIR/node_modules/.bin/lite-server"
-if [ ! -f "$LITE" ]; then
- echo "ERROR: cannot find lite-server. You need to run:"
- echo " tools/install-build-deps --ui"
- echo " ninja -C out/xxx ui"
- exit 127
-fi
if [ -z "$1" ]; then
echo "ERROR: no output directory specified."
echo "Usage: $0 out/mac_debug"
@@ -31,16 +23,20 @@
fi
OUT_DIR="$1"
UI_OUT_DIR="$OUT_DIR/ui"
-if [ ! -d $OUT_DIR ]; then
- echo "ERROR: cannot find the output directory (\"$OUT_DIR\")"
- echo "Did you run ninja?"
- exit 127
-fi
if [ ! -d $UI_OUT_DIR ]; then
echo "ERROR: cannot find the UI output directory (\"$UI_OUT_DIR\")."
echo "Did you run ninja ui?"
exit 127
fi
-OUT_DIR="$OUT_DIR" ROOT_DIR="$ROOT_DIR" $NODE $LITE -c $UI_DIR/bs-config.js
+$ROOT_DIR/tools/dev_server \
+ -p 10000 \
+ -i $ROOT_DIR/.git \
+ -i $ROOT_DIR/src/traced \
+ -i $ROOT_DIR/buildtools \
+ -i $ROOT_DIR/out \
+ -i $ROOT_DIR/ui/node_modules \
+ -s $UI_OUT_DIR \
+ "$ROOT_DIR/tools/ninja -C $OUT_DIR ui"
+