blob: 89020df75bf6e2b0a77084ea0f8c3c1c5e237742 [file] [log] [blame]
/*
* Copyright (C) 2023 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_COLUMN_DATA_NODE_H_
#define SRC_TRACE_PROCESSOR_DB_COLUMN_DATA_NODE_H_
#include <cstdint>
#include <memory>
#include <string>
#include "perfetto/base/logging.h"
#include "perfetto/trace_processor/basic_types.h"
#include "perfetto/trace_processor/ref_counted.h"
#include "src/trace_processor/db/column/types.h"
namespace perfetto {
namespace protos::pbzero {
class SerializedColumn_Storage;
}
namespace trace_processor::column {
class DataNode : public RefCounted {
public:
class Queryable {
public:
using StorageProto = protos::pbzero::SerializedColumn_Storage;
virtual ~Queryable();
// Verifies whether any further filtering is needed and if not, whether the
// search would return all values or none of them. This allows for skipping
// the |Search| and |IndexSearch| in special cases.
//
// Notes for callers:
// * The SqlValue and FilterOp have to be valid in Sqlite: it will crash if
// either: value is NULL and operation is different than "IS NULL" and "IS
// NOT NULL" or the operation is "IS NULL" and "IS NOT NULL" and value is
// different than NULL.
virtual SearchValidationResult ValidateSearchConstraints(SqlValue, FilterOp)
const = 0;
// Searches for elements which match |op| and |value| between |range.start|
// and |range.end|.
//
// Returns either a range or BitVector which indicate the positions in
// |range| which match the constraint. If a BitVector is returned, it will
// be *precisely* as large as |range.end|.
//
// Notes for callers:
// * Should only be called if ValidateSearchContraints returned kOk.
// * Callers should note that the return value of this function corresponds
// to positions in the storage.
//
// Notes for implementors:
// * Implementations should ensure that the return value *only* includes
// positions in |range| as callers will expect this to be true and can
// optimize based on this.
// * Implementations should ensure that, if they return a BitVector, it is
// precisely of size |range.end|.
virtual RangeOrBitVector Search(FilterOp, SqlValue, Range) const = 0;
// Searches for elements which match |op| and |value| at the positions given
// by |indices| array.
//
// Returns either a range of BitVector which indicate the positions in
// |indices| which match the constraint. If a BitVector is returned, it will
// be *precisely* as large as |indices_count|.
//
// Notes for callers:
// * Should only be called if ValidateSearchContraints returned kOk.
// * Callers should note that the return value of this function corresponds
// to positions in |indices| *not* positions in the storage.
//
// Notes for implementors:
// * Implementations should ensure that, if they return a BitVector, it is
// precisely of size |indices_count|.
virtual RangeOrBitVector IndexSearch(FilterOp, SqlValue, Indices) const = 0;
// Searches for elements which match |op| and |value| at the positions given
// by indices data.
//
// Returns a Range into Indices data of indices that pass the constraint.
//
// Notes for callers:
// * Should not be called on:
// - kGlob and kRegex as those operations can't use the sorted state
// hence they can't return a Range.
// - kNe as this is inherently unsorted. Use kEq and then reverse the
// result.
// * Should only be called if ValidateSearchContraints returned kOk.
// * Callers should note that the return value of this function corresponds
// to positions in |indices| *not* positions in the storage.
virtual Range OrderedIndexSearch(FilterOp, SqlValue, Indices) const = 0;
// Sorts |rows| in ascending order with the comparator:
// data[rows[a]] < data[rows[b]].
virtual void Sort(uint32_t* rows, uint32_t rows_size) const = 0;
// Stable sorts |rows| in ascending order with the comparator:
// data[rows[a]] < data[rows[b]].
virtual void StableSort(uint32_t* rows, uint32_t rows_size) const = 0;
// Serializes storage data to proto format.
virtual void Serialize(StorageProto*) const = 0;
// Returns a string which represents the column for debugging purposes.
//
// Warning: the format of the string returned by this class is *not* stable
// and should be relied upon for anything except printing for debugging
// purposes.
virtual std::string DebugString() const = 0;
// Number of elements in stored data.
virtual uint32_t size() const = 0;
};
virtual ~DataNode();
virtual std::unique_ptr<Queryable> MakeQueryable() {
PERFETTO_FATAL("Unimplemented");
}
virtual std::unique_ptr<Queryable> MakeQueryable(std::unique_ptr<Queryable>) {
PERFETTO_FATAL("Unimplemented");
}
};
} // namespace trace_processor::column
} // namespace perfetto
#endif // SRC_TRACE_PROCESSOR_DB_COLUMN_DATA_NODE_H_