Databases Reference
In-Depth Information
Rows and keys
Now we discuss the row and key formats. The naive approach would be to store
rows in a MySQL format—what is passed to the write_row() function is written
to disk. Thus retrieval would be easy too. Unfortunately, this does not work. For
example, this format has all CHAR and VARCHAR fields space padded to their full
length. Storing them that way would waste a lot of space. But the main reason why
this simple approach is fundamentally flawed is the BLOB type. In memory, all BLOB
(and TEXT ) fields are kept outside of the row buffer; the row buffer only keeps a
pointer to the actual BLOB field content. This is why we use a special packed row
format, which makes our code only slightly more complex, as MySQL conveniently
provides a Field::pack() method that will do all of the packing job. First, we
need a buffer for a packed row. A growing String object (briefly discussed in the
previous chapter) would be very handy here. As we do not need more than one row
buffer per table, we can put it in the ha_tocab object:
bool ha_tocab::pack_row(const uchar *from)
{
uint max_length = table->s->reclength;
for (int i = 0; i < table->s->blob_fields ; i++) {
Field_blob *blob = (Field_blob*)
table->field[table->s->blob_field[i]];
max_length += blob->get_packed_size(from +
blob->offset(table->record[0]),
table->s->db_low_byte_first);
}
We start by calculating the required buffer size. The row length without BLOB fields.
is table->s->reclength , and for all BLOB fields we add up the sizes of their packed
values to get the buffer size that we need. MySQL has a blob_field[] array in
TABLE_SHARE , it is an array of field numbers—indexes in the table->field[] array
of Field objects—for all BLOB fields. We simply iterate over this array, find the
corresponding Field_blob object, and use its get_packed_size() method, which
returns the number of bytes that the packed image of the actual BLOB field value will
need. Unlike table>s->reclength , which is a fixed length of the row, and does not
depend on the row content, we need to use a sizes of an actual BLOB field content,
unless we want to allocate 4 GB of memory for every BLOB field in the table up front.
if (row_buf.realloc(max_length))
return 1;
 
Search WWH ::




Custom Search