blob: cc3277597c3969ebaf9fc170ed0dbc4e379d560f [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 KUDU_CODEGEN_ROW_PROJECTOR_H
#define KUDU_CODEGEN_ROW_PROJECTOR_H
#include <cstddef>
#include <cstdint>
#include <iosfwd>
#include <memory>
#include <vector>
#include <glog/logging.h>
#include "kudu/codegen/jit_wrapper.h"
#include "kudu/common/row.h"
#include "kudu/common/rowblock.h"
#include "kudu/common/schema.h"
#include "kudu/gutil/macros.h"
#include "kudu/gutil/port.h"
#include "kudu/gutil/ref_counted.h"
#include "kudu/util/status.h"
namespace llvm {
class TargetMachine;
} // namespace llvm
namespace kudu {
class Arena;
class faststring;
namespace codegen {
// The JITWrapper for codegen::RowProjector functions. Contains
// the compiled functions themselves as well as the schemas used
// to generate them.
class RowProjectorFunctions : public JITWrapper {
public:
// Compiles the row projector functions for the given base
// and projection.
// Writes the llvm::TargetMachine* used to 'tm' (if not NULL)
// and the functions to 'out' upon success.
static Status Create(const Schema& base_schema, const Schema& projection,
scoped_refptr<RowProjectorFunctions>* out,
llvm::TargetMachine** tm = NULL);
const Schema& base_schema() { return base_schema_; }
const Schema& projection() { return projection_; }
typedef bool(*ProjectionFunction)(const uint8_t*, RowBlockRow*, Arena*);
ProjectionFunction read() const { return read_f_; }
ProjectionFunction write() const { return write_f_; }
virtual Status EncodeOwnKey(faststring* out) OVERRIDE {
return EncodeKey(base_schema_, projection_, out);
}
static Status EncodeKey(const Schema& base, const Schema& proj,
faststring* out);
private:
RowProjectorFunctions(const Schema& base_schema, const Schema& projection,
ProjectionFunction read_f, ProjectionFunction write_f,
std::unique_ptr<JITCodeOwner> owner);
const Schema base_schema_, projection_;
const ProjectionFunction read_f_, write_f_;
};
// This projector behaves the almost the same way as a tablet/RowProjector except that
// it only supports certain row types, and expects a regular Arena. Furthermore,
// the Reset() public method is unsupported.
//
// See documentation for RowProjector. Any differences in the API will be explained
// in this class.
class RowProjector {
public:
typedef kudu::RowProjector::ProjectionIdxMapping ProjectionIdxMapping;
// Requires that both schemas remain valid for the lifetime of this
// object. Also requires that the schemas are compatible with
// the schemas used to create 'functions'.
RowProjector(const Schema* base_schema, const Schema* projection,
scoped_refptr<RowProjectorFunctions> functions);
Status Init();
// Ignores relocations if dst_arena == NULL
template<class ContiguousRowType>
Status ProjectRowForRead(const ContiguousRowType& src_row,
RowBlockRow* dst_row,
Arena* dst_arena) const {
DCHECK_SCHEMA_EQ(*base_schema(), *src_row.schema());
DCHECK_SCHEMA_EQ(*projection(), *dst_row->schema());
RowProjectorFunctions::ProjectionFunction f = functions_->read();
if (PREDICT_TRUE(f(src_row.row_data(), dst_row, dst_arena))) {
return Status::OK();
}
return Status::IOError("out of memory copying slice during projection. "
"Base schema row: ", base_schema()->DebugRow(src_row));
}
// Warning: the projection schema should have write-defaults defined
// if it has default columns. There was no check for default write
// columns during this class' initialization.
// Ignores relocations if dst_arena == NULL
template<class ContiguousRowType>
Status ProjectRowForWrite(const ContiguousRowType& src_row,
RowBlockRow* dst_row,
Arena* dst_arena) const {
DCHECK_SCHEMA_EQ(*base_schema(), *src_row.schema());
DCHECK_SCHEMA_EQ(*projection(), *dst_row->schema());
RowProjectorFunctions::ProjectionFunction f = functions_->write();
if (PREDICT_TRUE(f(src_row.row_data(), dst_row, dst_arena))) {
return Status::OK();
}
return Status::IOError("out of memory copying slice during projection. "
"Base schema row: ", base_schema()->DebugRow(src_row));
}
const std::vector<ProjectionIdxMapping>& base_cols_mapping() const {
return projector_.base_cols_mapping();
}
const std::vector<size_t>& projection_defaults() const {
return projector_.projection_defaults();
}
bool is_identity() const { return projector_.is_identity(); }
const Schema* projection() const { return projector_.projection(); }
const Schema* base_schema() const { return projector_.base_schema(); }
private:
kudu::RowProjector projector_;
scoped_refptr<RowProjectorFunctions> functions_;
DISALLOW_COPY_AND_ASSIGN(RowProjector);
};
extern std::ostream& operator<<(std::ostream& o, const RowProjector& rp);
} // namespace codegen
} // namespace kudu
#endif