mariadb/storage/rocksdb/rdb_converter.h
Sergei Golubchik 49b5a2b360 Revert "MDEV-30610 Update RocksDB to v8.1.1"
Not ready yet, it fails its own test suite

This reverts commit 485c9b1fb3
2023-09-30 14:12:55 +02:00

247 lines
8 KiB
C++

/*
Copyright (c) 2018, Facebook, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#pragma once
// C++ standard header files
#include <string>
#include <vector>
// MySQL header files
#include "./handler.h" // handler
#include "./my_global.h" // ulonglong
#include "./sql_string.h"
#include "./ut0counter.h"
// MyRocks header files
#include "./ha_rocksdb.h"
#include "./rdb_datadic.h"
namespace myrocks {
class Rdb_field_encoder;
/**
Describes instructions on how to decode the field for value slice
*/
struct READ_FIELD {
// Points to Rdb_field_encoder describing the field
Rdb_field_encoder *m_field_enc;
// if true, decode the field, otherwise skip it
bool m_decode;
// Skip this many bytes before reading (or skipping) this field
int m_skip;
};
/**
Class to convert rocksdb value slice from storage format to mysql record
format.
*/
class Rdb_convert_to_record_value_decoder {
public:
Rdb_convert_to_record_value_decoder() = delete;
Rdb_convert_to_record_value_decoder(
const Rdb_convert_to_record_value_decoder &decoder) = delete;
Rdb_convert_to_record_value_decoder &operator=(
const Rdb_convert_to_record_value_decoder &decoder) = delete;
static int decode(uchar *const buf, uint *offset, TABLE *table,
my_core::Field *field, Rdb_field_encoder *field_dec,
Rdb_string_reader *reader, bool decode, bool is_null);
private:
static int decode_blob(TABLE *table, Field *field, Rdb_string_reader *reader,
bool decode);
static int decode_fixed_length_field(Field *const field,
Rdb_field_encoder *field_dec,
Rdb_string_reader *const reader,
bool decode);
static int decode_varchar(Field *const field, Rdb_string_reader *const reader,
bool decode);
};
/**
Class to iterator fields in RocksDB value slice
A template class instantiation represent a way to decode the data.
The reason to use template class instead of normal class is to elimate
virtual method call.
*/
template <typename value_field_decoder>
class Rdb_value_field_iterator {
private:
bool m_is_null;
std::vector<READ_FIELD>::const_iterator m_field_iter;
std::vector<READ_FIELD>::const_iterator m_field_end;
Rdb_string_reader *m_value_slice_reader;
// null value map
const char *m_null_bytes;
// The current open table
TABLE *m_table;
// The current field
Field *m_field;
Rdb_field_encoder *m_field_dec;
uchar *const m_buf;
uint m_offset;
public:
Rdb_value_field_iterator(TABLE *table, Rdb_string_reader *value_slice_reader,
const Rdb_converter *rdb_converter,
uchar *const buf);
Rdb_value_field_iterator(const Rdb_value_field_iterator &field_iterator) =
delete;
Rdb_value_field_iterator &operator=(
const Rdb_value_field_iterator &field_iterator) = delete;
/*
Move and decode next field
Run next() before accessing data
*/
int next();
// Whether current field is the end of fields
bool end_of_fields() const;
void *get_dst() const;
// Whether the value of current field is null
bool is_null() const;
// get current field index
int get_field_index() const;
// get current field type
enum_field_types get_field_type() const;
// get current field
Field *get_field() const;
};
/**
Class to convert Mysql formats to rocksdb storage format, and vice versa.
*/
class Rdb_converter {
public:
/*
Initialize converter with table data
*/
Rdb_converter(const THD *thd, const Rdb_tbl_def *tbl_def, TABLE *table);
Rdb_converter(const Rdb_converter &decoder) = delete;
Rdb_converter &operator=(const Rdb_converter &decoder) = delete;
~Rdb_converter();
void setup_field_decoders(const MY_BITMAP *field_map,
bool decode_all_fields = false);
int decode(const std::shared_ptr<Rdb_key_def> &key_def, uchar *dst,
const rocksdb::Slice *key_slice,
const rocksdb::Slice *value_slice);
int encode_value_slice(const std::shared_ptr<Rdb_key_def> &pk_def,
const rocksdb::Slice &pk_packed_slice,
Rdb_string_writer *pk_unpack_info, bool is_update_row,
bool store_row_debug_checksums, char *ttl_bytes,
bool *is_ttl_bytes_updated,
rocksdb::Slice *const value_slice);
my_core::ha_rows get_row_checksums_checked() const {
return m_row_checksums_checked;
}
bool get_verify_row_debug_checksums() const {
return m_verify_row_debug_checksums;
}
void set_verify_row_debug_checksums(bool verify_row_debug_checksums) {
m_verify_row_debug_checksums = verify_row_debug_checksums;
}
const Rdb_field_encoder *get_encoder_arr() const { return m_encoder_arr; }
int get_null_bytes_in_record() { return m_null_bytes_length_in_record; }
const char *get_null_bytes() const { return m_null_bytes; }
void set_is_key_requested(bool key_requested) {
m_key_requested = key_requested;
}
bool get_maybe_unpack_info() const { return m_maybe_unpack_info; }
char *get_ttl_bytes_buffer() { return m_ttl_bytes; }
const std::vector<READ_FIELD> *get_decode_fields() const {
return &m_decoders_vect;
}
private:
int decode_value_header(Rdb_string_reader *reader,
const std::shared_ptr<Rdb_key_def> &pk_def,
rocksdb::Slice *unpack_slice);
void setup_field_encoders();
void get_storage_type(Rdb_field_encoder *const encoder, const uint kp);
int convert_record_from_storage_format(
const std::shared_ptr<Rdb_key_def> &pk_def,
const rocksdb::Slice *const key, const rocksdb::Slice *const value,
uchar *const buf);
int verify_row_debug_checksum(const std::shared_ptr<Rdb_key_def> &pk_def,
Rdb_string_reader *reader,
const rocksdb::Slice *key,
const rocksdb::Slice *value);
private:
/*
This tells if any field which is part of the key needs to be unpacked and
decoded.
*/
bool m_key_requested;
/*
Controls whether verifying checksums during reading, This is updated from
the session variable at the start of each query.
*/
bool m_verify_row_debug_checksums;
// Thread handle
const THD *m_thd;
/* MyRocks table definition*/
const Rdb_tbl_def *m_tbl_def;
/* The current open table */
TABLE *m_table;
/*
Number of bytes in on-disk (storage) record format that are used for
storing SQL NULL flags.
*/
int m_null_bytes_length_in_record;
/*
Pointer to null bytes value
*/
const char *m_null_bytes;
/*
TRUE <=> Some fields in the PK may require unpack_info.
*/
bool m_maybe_unpack_info;
/*
Pointer to the original TTL timestamp value (8 bytes) during UPDATE.
*/
char m_ttl_bytes[ROCKSDB_SIZEOF_TTL_RECORD];
/*
Array of table->s->fields elements telling how to store fields in the
record.
*/
Rdb_field_encoder *m_encoder_arr;
/*
Array of request fields telling how to decode data in RocksDB format
*/
std::vector<READ_FIELD> m_decoders_vect;
/*
A counter of how many row checksums were checked for this table. Note that
this does not include checksums for secondary index entries.
*/
my_core::ha_rows m_row_checksums_checked;
// buffer to hold data during encode_value_slice
String m_storage_record;
};
} // namespace myrocks