Skip to content

Commit

Permalink
Merge "Update __intrinsic_strip_hex to replace hex at the start of th…
Browse files Browse the repository at this point in the history
…e string" into main
  • Loading branch information
Treehugger Robot authored and Gerrit Code Review committed Mar 7, 2025
2 parents b6ab6b8 + ab1ae64 commit c44847a
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 50 deletions.
1 change: 1 addition & 0 deletions Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -13729,6 +13729,7 @@ python_binary_host {
filegroup {
name: "perfetto_src_trace_processor_perfetto_sql_intrinsics_functions_unittests",
srcs: [
"src/trace_processor/perfetto_sql/intrinsics/functions/replace_numbers_function_unittest.cc",
"src/trace_processor/perfetto_sql/intrinsics/functions/sqlite3_str_split_unittest.cc",
],
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,10 @@ perfetto_tp_tables("tables") {

perfetto_unittest_source_set("unittests") {
testonly = true
sources = [ "sqlite3_str_split_unittest.cc" ]
sources = [
"replace_numbers_function_unittest.cc",
"sqlite3_str_split_unittest.cc",
]
deps = [
":functions",
"../../../../../gn:default_deps",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ namespace perfetto {
namespace trace_processor {
namespace {

// __instrinsic_strip_hex(name STRING, min_repeated_digits LONG)
// __intrinsic_strip_hex(name STRING, min_repeated_digits LONG)
//
// Replaces hexadecimal sequences (with at least one digit) in a string with
// "<num>" based on specified criteria.
struct StripHexFunction : public SqlFunction {
static constexpr char kFunctionName[] = "__instrinsic_strip_hex";
static constexpr char kFunctionName[] = "__intrinsic_strip_hex";
static constexpr std::array<std::string_view, 2> kSpecialPrefixes = {"0x",
"0X"};

using Context = void;

Expand All @@ -57,6 +59,55 @@ struct StripHexFunction : public SqlFunction {
return status;
}

static const std::string_view MatchesSpecialPrefix(
base::StringView input_view,
size_t pos) {
for (const auto& special_prefix : kSpecialPrefixes) {
if (input_view.substr(pos, special_prefix.size()) ==
special_prefix.data()) {
return special_prefix;
}
}
return "";
}

static std::string StripHex(std::string input, int64_t min_repeated_digits) {
base::StringView input_view = base::StringView(input);
std::string result;
result.reserve(input.length());
for (size_t i = 0; i < input.length();) {
const std::string_view special_prefix =
MatchesSpecialPrefix(input_view, i);
if (!special_prefix.empty()) {
// Case 1: Special prefixes for hex sequence found
result += input.substr(i, special_prefix.size());
i += special_prefix.size();
} else if (!isalnum(input[i])) {
// Case 2: Non alpha numeric prefix for hex sequence found
result += input[i++];
} else if (i == 0 && isxdigit(input[i])) {
// Case 3: Start of input is hex digit, continue to check hex sequence
} else {
// Case 4: No potential prefix for hex digits found
result += input[i++];
continue;
}

size_t hex_start = i;
bool digit_found = false;
for (; i < input.length() && isxdigit(input[i]); i++) {
if (isdigit(input[i])) {
digit_found = true;
}
}
result += digit_found && (i - hex_start >=
static_cast<size_t>(min_repeated_digits))
? "<num>"
: input.substr(hex_start, i - hex_start);
}
return result;
}

static base::Status RunImpl(void*,
size_t argc,
sqlite3_value** argv,
Expand Down Expand Up @@ -90,42 +141,7 @@ struct StripHexFunction : public SqlFunction {
kFunctionName);
}

base::StringView inputView = base::StringView(input);
constexpr std::array<const char*, 2> special_prefixes = {"0x", "0X"};
std::string result;
result.reserve(input.length());
for (size_t i = 0; i < input.length();) {
size_t prefix_len = 0;
for (const auto& special_prefix : special_prefixes) {
if (inputView.substr(i, strlen(special_prefix)) == special_prefix) {
prefix_len = strlen(special_prefix);
break;
}
}
if (prefix_len == 0 && !isalnum(input[i])) {
// Treat the current character as a prefix if no defined prefix was
// found and the character is non-alphanumeric.
prefix_len = 1;
}
if (prefix_len == 0) {
result += input[i++];
continue;
}
result += input.substr(i, prefix_len);

i += prefix_len;
size_t hex_start = i;
bool digit_found = false;
for (; i < input.length() && isxdigit(input[i]); i++) {
if (isdigit(input[i])) {
digit_found = true;
}
}
result += digit_found && (i - hex_start >=
static_cast<size_t>(min_repeated_digits))
? "<num>"
: input.substr(hex_start, i - hex_start);
}
std::string result = StripHex(input, min_repeated_digits);
char* result_cstr = static_cast<char*>(malloc(result.length() + 1));
memcpy(result_cstr, result.c_str(), result.length() + 1);
out = SqlValue::String(result_cstr);
Expand All @@ -136,11 +152,15 @@ struct StripHexFunction : public SqlFunction {

} // namespace

base::Status RegisterReplaceNumbersFunction(PerfettoSqlEngine* engine,
TraceProcessorContext* context) {
base::Status RegisterStripHexFunction(PerfettoSqlEngine* engine,
TraceProcessorContext* context) {
return engine->RegisterStaticFunction<StripHexFunction>(
StripHexFunction::kFunctionName, 2, context->storage.get());
}

std::string SqlStripHex(std::string input, int64_t min_repeated_digits) {
return StripHexFunction::StripHex(input, min_repeated_digits);
}

} // namespace trace_processor
} // namespace perfetto
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class TraceProcessorContext;

// Registers the following functions:
//
// __instrinsic_strip_hex(name STRING, min_repeated_digits LONG)
// __intrinsic_strip_hex(name STRING, min_repeated_digits LONG)
//
// Description:
// Replaces hexadecimal sequences (with at least one digit) in a string with
Expand All @@ -43,16 +43,19 @@ class TraceProcessorContext;
// Replacement Criteria:
// - Replaces hex/num sequences [0-9a-fA-F] with at least one occurrence of a
// digit preceded by:
// - Start of the string
// - Defined prefix ("0x", "0X")
// - Non-alphanumeric character
// - Whitespace character
// - Replaces only sequences with length >= 'min_repeated_digits'.
// - Replaces only sequences with length >= 'min_repeated_digits'
//
// Return Value:
// The string with replaced hex sequences.
base::Status RegisterReplaceNumbersFunction(PerfettoSqlEngine* engine,
TraceProcessorContext* context);
base::Status RegisterStripHexFunction(PerfettoSqlEngine* engine,
TraceProcessorContext* context);

// Implementation of __intrinsic_strip_hex function
// Visible for testing
std::string SqlStripHex(std::string input, int64_t min_repeated_digits);
} // namespace trace_processor
} // namespace perfetto

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2025 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/perfetto_sql/intrinsics/functions/replace_numbers_function.h"

#include <string>

#include "perfetto/base/logging.h"
#include "test/gtest_and_gmock.h"

namespace perfetto {
namespace trace_processor {
namespace test {
namespace {

TEST(ReplaceNumbersFunctionTest, TestReplaceWithPrefix) {
std::string result = SqlStripHex("0x1234", 3);
ASSERT_STREQ(result.c_str(), "0x<num>");
}

TEST(ReplaceNumbersFunctionTest, TestReplaceAtTheStart) {
std::string result = SqlStripHex("12a34", 3);
ASSERT_STREQ(result.c_str(), "<num>");
}

TEST(ReplaceNumbersFunctionTest, TestReplaceAfterSpace) {
std::string result = SqlStripHex("Hello 123", 3);
ASSERT_STREQ(result.c_str(), "Hello <num>");
}

TEST(ReplaceNumbersFunctionTest, TestReplaceOnlyDigits) {
std::string result = SqlStripHex("abc", 1);
ASSERT_STREQ(result.c_str(), "abc");
}

TEST(ReplaceNumbersFunctionTest, TestReplaceOnlyGreaterThanRepeated) {
std::string result = SqlStripHex("1=22@333-444", 3);
ASSERT_STREQ(result.c_str(), "1=22@<num>-<num>");
}

TEST(ReplaceNumbersFunctionTest, TestReplaceDoingNothing) {
std::string result = SqlStripHex("aaaaaa", 1);
ASSERT_STREQ(result.c_str(), "aaaaaa");
}

} // namespace
} // namespace test
} // namespace trace_processor
} // namespace perfetto
2 changes: 1 addition & 1 deletion src/trace_processor/perfetto_sql/stdlib/android/slices.sql
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,5 @@ SELECT
THEN "Handler: " || _remove_lambda_name($name)
WHEN $name GLOB "deliverInputEvent*"
THEN "deliverInputEvent <...>"
ELSE __instrinsic_strip_hex($name, 3)
ELSE __intrinsic_strip_hex($name, 3)
END;
3 changes: 1 addition & 2 deletions src/trace_processor/trace_processor_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -986,8 +986,7 @@ void TraceProcessorImpl::InitPerfettoSqlEngine() {
PERFETTO_FATAL("%s", status.c_message());
}
{
base::Status status =
RegisterReplaceNumbersFunction(engine_.get(), &context_);
base::Status status = RegisterStripHexFunction(engine_.get(), &context_);
if (!status.ok())
PERFETTO_FATAL("%s", status.c_message());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
'+job=1234:"com.google.android.apps.internal.betterbug"',
'Looper.dispatch: android.app.ActivityThread$H(runnable@a9f7a84'
'(android.app.ActivityThread@1d57743,40))', 'Not changed at ALL 01',
'Three digits to replace 123 1234', 'kworker/1d57743',
'Three digits to replace 123 1234', 'kworker/1d57743', '1234',
'1019b5c SurfaceView[com.google.android.apps.maps/com.google.android.maps.'
'MapsActivity]#1(BLAST Consumer)1', '1 2 3 4', '0x1019b5c',
'ImageDecoder#decodeDrawable'
]

Expand Down
4 changes: 4 additions & 0 deletions test/trace_processor/diff_tests/stdlib/android/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ def test_android_slices_standardization_for_aggregation(self):
"Not changed at ALL 01"
"Three digits to replace <num> <num>"
"kworker/<num>"
"<num>"
"<num> SurfaceView[com.google.android.apps.maps/com.google.android.maps.MapsActivity]#1(BLAST Consumer)1"
"1 2 3 4"
"0x<num>"
"ImageDecoder#decodeDrawable"
"""))

Expand Down

0 comments on commit c44847a

Please sign in to comment.