1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

WL#2735: Refactor replication

Factoring out pack_row() and unpack_row() into new files
rpl_record.{cc,h}.
This commit is contained in:
mats@romeo.(none)
2007-04-13 14:55:28 +02:00
parent 6044deb72e
commit 84ec7be2c7
12 changed files with 368 additions and 282 deletions

View File

@@ -27,6 +27,7 @@
#include "mysql_priv.h"
#include "rpl_rli.h"
#include "rpl_record.h"
#include <my_bitmap.h>
#include "log_event.h"
#include <m_ctype.h>
@@ -2554,112 +2555,6 @@ my_size_t THD::max_row_length_blob(TABLE *table, const byte *data) const
}
/*
Pack a record of data for a table into a format suitable for
transfer via the binary log.
SYNOPSIS
THD::pack_row()
table Table describing the format of the record
cols Bitmap with a set bit for each column that should be
stored in the row
row_data Pointer to memory where row will be written
record Pointer to record that should be packed. It is assumed
that the pointer refers to either record[0] or
record[1], but no such check is made since the code does
not rely on that.
DESCRIPTION
The format for a row in transfer with N fields is the following:
ceil(N/8) null bytes:
One null bit for every column *regardless of whether it can be
null or not*. This simplifies the decoding. Observe that the
number of null bits is equal to the number of set bits in the
'cols' bitmap. The number of null bytes is the smallest number
of bytes necessary to store the null bits.
Padding bits are 1.
N packets:
Each field is stored in packed format.
RETURN VALUE
The number of bytes written at 'row_data'.
*/
my_size_t
THD::pack_row(TABLE *table, MY_BITMAP const* cols,
byte *const row_data, const byte *record) const
{
Field **p_field= table->field, *field;
int const null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
byte *pack_ptr = row_data + null_byte_count;
byte *null_ptr = row_data;
my_ptrdiff_t const rec_offset= record - table->record[0];
my_ptrdiff_t const def_offset= table->s->default_values - table->record[0];
/*
We write the null bits and the packed records using one pass
through all the fields. The null bytes are written little-endian,
i.e., the first fields are in the first byte.
*/
unsigned int null_bits= (1U << 8) - 1;
// Mask to mask out the correct but among the null bits
unsigned int null_mask= 1U;
for ( ; (field= *p_field) ; p_field++)
{
DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d",
null_mask, null_ptr, row_data, null_byte_count));
if (bitmap_is_set(cols, p_field - table->field))
{
my_ptrdiff_t offset;
if (field->is_null(rec_offset))
{
offset= def_offset;
null_bits |= null_mask;
}
else
{
offset= rec_offset;
null_bits &= ~null_mask;
/*
We only store the data of the field if it is non-null
*/
pack_ptr= (byte*)field->pack((char *) pack_ptr, field->ptr + offset);
}
null_mask <<= 1;
if ((null_mask & 0xFF) == 0)
{
DBUG_ASSERT(null_ptr < row_data + null_byte_count);
null_mask = 1U;
*null_ptr++ = null_bits;
null_bits= (1U << 8) - 1;
}
}
}
/*
Write the last (partial) byte, if there is one
*/
if ((null_mask & 0xFF) > 1)
{
DBUG_ASSERT(null_ptr < row_data + null_byte_count);
*null_ptr++ = null_bits;
}
/*
The null pointer should now point to the first byte of the
packed data. If it doesn't, something is very wrong.
*/
DBUG_ASSERT(null_ptr == row_data + null_byte_count);
return static_cast<my_size_t>(pack_ptr - row_data);
}
namespace {
@@ -2830,9 +2725,9 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
byte *before_row= row_data.slot(0);
byte *after_row= row_data.slot(1);
my_size_t const before_size= pack_row(table, cols, before_row,
my_size_t const before_size= pack_row(table, cols, before_row,
before_record);
my_size_t const after_size= pack_row(table, cols, after_row,
my_size_t const after_size= pack_row(table, cols, after_row,
after_record);
/*