From 7e5591e1c2e874391353b08217afbb8a83c75fb0 Mon Sep 17 00:00:00 2001 From: wu__xiao__ming1 <15848722+wuxiaoming1@user.noreply.gitee.com> Date: Thu, 12 Jun 2025 11:36:35 +0800 Subject: [PATCH] rocksdb interface port----rdb_converter.h --- storage/rocksdb/rdb_converter.h | 187 +++++++++++++++++++++++++++++++- 1 file changed, 186 insertions(+), 1 deletion(-) diff --git a/storage/rocksdb/rdb_converter.h b/storage/rocksdb/rdb_converter.h index 2794e002e..58a32fbb7 100644 --- a/storage/rocksdb/rdb_converter.h +++ b/storage/rocksdb/rdb_converter.h @@ -58,4 +58,189 @@ class Rdb_convert_to_record_value_decoder { 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); \ No newline at end of file + 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 +class Rdb_value_field_iterator { + private: + bool m_is_null; + std::vector::const_iterator m_field_iter; + std::vector::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 &key_def, uchar *dst, + const rocksdb::Slice *key_slice, const rocksdb::Slice *value_slice, + bool decode_value = true); + + int encode_value_slice(const std::shared_ptr &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 *get_decode_fields() const { + return &m_decoders_vect; + } + + private: + int decode_value_header_for_pk(Rdb_string_reader *reader, + const std::shared_ptr &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 &pk_def, + const rocksdb::Slice *const key, const rocksdb::Slice *const value, + uchar *const buf, bool decode_value); + + int verify_row_debug_checksum(const std::shared_ptr &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 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 -- Gitee