/* * 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. */ #ifndef SRC_TRACE_PROCESSOR_DB_COMPARE_H_ #define SRC_TRACE_PROCESSOR_DB_COMPARE_H_ #include <stdint.h> #include <algorithm> #include <optional> #include "perfetto/ext/base/string_view.h" #include "perfetto/trace_processor/basic_types.h" namespace perfetto { namespace trace_processor { namespace compare { // This file contains the de-facto impleemntation of all comparisions used by // trace processor in every setting. All of this is centralised in one file to // ensure both internal consistency with SQLite and consistency with SQLite. // Compare a non-null numeric to a double; returns: // * <0 if i < d, // * >0 if i > d. // * 0 otherwise // This code matches the behaviour of sqlite3IntFloatCompare. inline int LongToDouble(int64_t i, double d) { … } // Compares two non-null numeric values; returns: // * <0 if a < b, // * >0 if a > b. // * 0 otherwise // This code matches the behaviour of the inline code in the comparision path of // sqlite3VdbeExec (for ints) and the behaviour of sqlite3MemCompare (for // doubles). template <typename T> inline int Numeric(T a, T b) { … } // Compares two non-null bytes values; returns: // * <0 if a < b, // * >0 if a > b. // * 0 otherwise // This code matches the behaviour of sqlite3BlobCompare. inline int Bytes(const void* a, size_t a_n, const void* b, size_t b_n) { … } // Compares two non-null string values; returns: // * <0 if a < b, // * >0 if a > b. // * 0 otherwise // This code matches the behaviour of sqlite3BlobCompare which is called when // there is no collation sequence defined in sqlite3MemCompare. inline int String(base::StringView a, base::StringView b) { … } // Compares two nullable numeric values; returns: // * 0 if both a and b are null // * <0 if a is null and b is non null // * >0 if a is non null and b is null // * <0 if a < b (a and b both non null) // * >0 if a > b (a and b both non null) // * 0 otherwise // Should only be used for defining an ordering on value of type T. For filter // functions, compare::Numeric should be used above after checking if the value // is null. // This method was defined from observing the behaviour of SQLite when sorting // on columns containing nulls. template <typename T> inline int NullableNumeric(std::optional<T> a, std::optional<T> b) { … } // Compares two strings, either of which can be null; returns: // * 0 if both a and b are null // * <0 if a is null and b is non null // * >0 if a is non null and b is null // * <0 if a < b (a and b both non null) // * >0 if a > b (a and b both non null) // * 0 otherwise // Should only be used for defining an ordering on value of type T. For filter // functions, compare::String should be used above after checking if the value // is null. // This method was defined from observing the behaviour of SQLite when sorting // on columns containing nulls. inline int NullableString(base::StringView a, base::StringView b) { … } // Compares two SqlValue; returns: // * <0 if a.type < b.type and a and b are not both numeric // * >0 if a.type > b.type and a and b are not both numeric // * <0 if a < b (a and b both non null and either of same type or numeric) // * >0 if a > b (a and b both non null and either of same type or numeric) // * 0 otherwise // This code roughly matches the behaviour of the code in the comparision path // of sqlite3VdbeExec except we are intentionally more strict than SQLite when // it comes to casting between strings and numerics - we disallow moving between // the two. We do allow comparing between doubles and longs however as doubles // can easily appear by using constants in SQL even when intending to use longs. inline int SqlValue(const SqlValue& a, const SqlValue& b) { … } // Implements a comparator for SqlValues to use for std algorithms. // See documentation of compare::SqlValue for details of how this function // works. inline int SqlValueComparator(const trace_processor::SqlValue& a, const trace_processor::SqlValue& b) { … } } // namespace compare } // namespace trace_processor } // namespace perfetto #endif // SRC_TRACE_PROCESSOR_DB_COMPARE_H_