blob: bee562e5c1b568c92a21347ca325a7d0bc39abfc [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_OVERLAYS_STORAGE_OVERLAY_H_
#define SRC_TRACE_PROCESSOR_DB_OVERLAYS_STORAGE_OVERLAY_H_
#include <vector>
#include "src/trace_processor/containers/bit_vector.h"
#include "src/trace_processor/containers/row_map.h"
namespace perfetto {
namespace trace_processor {
namespace overlays {
// Abstract class which is layered on top of Storage transforming how the
// storage should be interpreted. The main purpose of this class is to be
// responsible for for mapping between table indices and storage indices (i.e.
// in both directions).
//
// Overlays are designed to be "layered" on top of each other (i.e. the mapping
// algorithms compose). To make it easier to reason about this class, we
// ignore any other overlays and assume we are mapping directly between table
// indices and storage indices. i.e. even if "table indices" we are working with
// come from another overlay, we still consider them as having come from the
// table and vice versa for "storage indices".
class StorageOverlay {
public:
// The core functions in this class work with input and output arguments which
// use the same data structure but have different semantics (i.e. input might
// be in terms of storage indices and output might be in terms of table
// indices).
//
// For this reason, we define a bunch of wrapper structs which "tag" the data
// structure with the semantics.
// A range of indices in the table space.
struct TableRange {
RowMap::Range range;
};
// A range of indices in the storage space.
struct StorageRange {
RowMap::Range range;
};
// A BitVector with set bits corresponding to indices in the table space.
struct TableBitVector {
BitVector bv;
};
// A BitVector with set bits corresponding to indices in the table space.
struct StorageBitVector {
BitVector bv;
};
// Represents a vector of indices in the table space.
struct TableIndexVector {
std::vector<uint32_t> indices;
};
// Represents a vector of indices in the storage space.
struct StorageIndexVector {
std::vector<uint32_t> indices;
};
// A subset of FilterOp containing operations which can be handled by
// overlays.
enum class OverlayOp {
kIsNull,
kIsNotNull,
kOther,
};
// Contains estimates of the cost for each of method in this class per row.
struct CostEstimatePerRow {
uint32_t to_storage_range;
uint32_t to_table_bit_vector;
uint32_t is_storage_search_required;
uint32_t map_to_storage_index_vector;
uint32_t index_search;
};
virtual ~StorageOverlay();
// Maps a range of indices in table space to an equivalent range of
// indices in the storage space.
virtual StorageRange MapToStorageRange(TableRange) const = 0;
// Maps a BitVector of indices in storage space to an equivalent range of
// indices in the table space.
virtual TableBitVector MapToTableBitVector(StorageBitVector) const = 0;
// Returns a BitVector where each boolean indicates if the corresponding index
// in |indices| needs to be mapped and searched in the storage or if the
// overlay can provide the answer without storage lookup.
virtual BitVector IsStorageLookupRequired(OverlayOp,
const TableIndexVector&) const = 0;
// Maps a vector of indices in the table space with an equivalent range
// of indices in the storage space.
//
// Note: callers must call |IsStorageSearchRequired| first and only call
// this method with indices where |IsStorageSearchRequired| returned true.
// Passing indices here which are not mappable is undefined behaviour.
virtual StorageIndexVector MapToStorageIndexVector(
TableIndexVector) const = 0;
// Given a vector of indices given in table space, returns whether the index
// matches the operation given by |op|.
//
// Note: callers must call |IsStorageSearchRequired| first and only call
// this method with indices where |IsStorageSearchRequired| returned false.
// Passing indices here which are not searchable is undefined behaviour.
virtual BitVector IndexSearch(OverlayOp, const TableIndexVector&) const = 0;
// Estimates the per-row costs of the methods of this class. Allows for
// deciding which algorithm to use to search/sort the storage.
virtual CostEstimatePerRow EstimateCostPerRow(OverlayOp) const = 0;
};
} // namespace overlays
} // namespace trace_processor
} // namespace perfetto
#endif // SRC_TRACE_PROCESSOR_DB_OVERLAYS_STORAGE_OVERLAY_H_