Below is the list of changes that have just been committed into a local
5.0 repository of marko. When marko does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1994 05/06/30 13:20:38 marko@stripped +1 -0
InnoDB: Fix a bug in BLOB handling; optimize null flag handling.
innobase/rem/rem0rec.c
1.19 05/06/30 13:20:28 marko@stripped +67 -38
rec_set_nth_field_extern_bit_new(): Fix a bug
(read the "extern" flag from the correct position).
rec_set_nth_field_extern_bit_new(),
rec_convert_dtuple_to_rec_new(),
rec_copy_prefix_to_buf(): Eliminate variables, reduce branching,
optimize the handling of the null flags.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: marko
# Host: hundin.mysql.fi
# Root: /home/marko/mysql-5.0-current
--- 1.18/innobase/rem/rem0rec.c Wed Apr 27 12:28:35 2005
+++ 1.19/innobase/rem/rem0rec.c Thu Jun 30 13:20:28 2005
@@ -601,30 +601,38 @@
/* read the lengths of fields 0..n */
for (i = 0; i < n_fields; i++) {
- ibool is_null;
- ulint len;
field = dict_index_get_nth_field(index, i);
type = dict_col_get_type(dict_field_get_col(field));
- is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL);
- if (is_null) {
- /* nullable field => read the null flag */
- is_null = !!(*nulls & null_mask);
+ if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
+ if (UNIV_UNLIKELY(!(byte) null_mask)) {
+ nulls--;
+ null_mask = 1;
+ }
+
+ if (*nulls & null_mask) {
+ null_mask <<= 1;
+ /* NULL fields cannot be external. */
+ ut_ad(i != ith);
+ continue;
+ }
+
null_mask <<= 1;
- if (null_mask == 0x100)
- nulls--, null_mask = 1;
}
- if (is_null || field->fixed_len) {
- /* No length (or extern bit) is stored for
- fields that are NULL or fixed-length. */
+ if (field->fixed_len) {
+ /* fixed-length fields cannot be external
+ (Fixed-length fields longer than
+ DICT_MAX_COL_PREFIX_LEN will be treated as
+ variable-length ones in dict_index_add_col().) */
ut_ad(i != ith);
continue;
}
- len = *lens--;
+ lens--;
if (dtype_get_len(type) > 255
|| dtype_get_mtype(type) == DATA_BLOB) {
+ ulint len = lens[1];
if (len & 0x80) { /* 1exxxxxx: 2-byte length */
if (i == ith) {
- if (!val == !(len & 0x20)) {
+ if (!val == !(len & 0x40)) {
return; /* no change */
}
/* toggle the extern bit */
@@ -823,6 +831,7 @@
byte* lens;
ulint len;
ulint i;
+ ulint n_node_ptr_field;
ulint fixed_len;
ulint null_mask = 1;
const ulint n_fields = dtuple_get_n_fields(dtuple);
@@ -831,16 +840,26 @@
ut_ad(index->table->comp);
ut_ad(n_fields > 0);
- switch (status) {
+
+ /* Try to ensure that the memset() between the for() loops
+ completes fast. The address is not exact, but UNIV_PREFETCH
+ should never generate a memory fault. */
+ UNIV_PREFETCH_RW(rec - REC_N_NEW_EXTRA_BYTES - n_fields);
+ UNIV_PREFETCH_RW(rec);
+
+ switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
case REC_STATUS_ORDINARY:
ut_ad(n_fields <= dict_index_get_n_fields(index));
+ n_node_ptr_field = ULINT_UNDEFINED;
break;
case REC_STATUS_NODE_PTR:
ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1);
+ n_node_ptr_field = n_fields - 1;
break;
case REC_STATUS_INFIMUM:
case REC_STATUS_SUPREMUM:
ut_ad(n_fields == 1);
+ n_node_ptr_field = ULINT_UNDEFINED;
goto init;
default:
ut_a(0);
@@ -852,15 +871,18 @@
rec += (index->n_nullable + 7) / 8;
for (i = 0; i < n_fields; i++) {
+ if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
+#ifdef UNIV_DEBUG
+ field = dtuple_get_nth_field(dtuple, i);
+ type = dfield_get_type(field);
+ ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL);
+ ut_ad(dfield_get_len(field) == 4);
+#endif /* UNIV_DEBUG */
+ goto init;
+ }
field = dtuple_get_nth_field(dtuple, i);
type = dfield_get_type(field);
len = dfield_get_len(field);
- if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) {
- fixed_len = 4;
- ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL);
- ut_ad(len == 4);
- continue;
- }
fixed_len = dict_index_get_nth_field(index, i)->fixed_len;
if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
@@ -902,27 +924,33 @@
type = dfield_get_type(field);
len = dfield_get_len(field);
- if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) {
- fixed_len = 4;
+ if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL);
ut_ad(len == 4);
- goto copy;
+ memcpy(end, dfield_get_data(field), len);
+ break;
}
fixed_len = dict_index_get_nth_field(index, i)->fixed_len;
if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
/* nullable field */
ut_ad(index->n_nullable > 0);
+
+ if (UNIV_UNLIKELY(!(byte) null_mask)) {
+ nulls--;
+ null_mask = 1;
+ }
+
ut_ad(*nulls < null_mask);
+
/* set the null flag if necessary */
if (len == UNIV_SQL_NULL) {
*nulls |= null_mask;
+ null_mask <<= 1;
+ continue;
}
+
null_mask <<= 1;
- if (null_mask == 0x100)
- nulls--, null_mask = 1;
- if (len == UNIV_SQL_NULL)
- continue;
}
/* only nullable fields can be null */
ut_ad(len != UNIV_SQL_NULL);
@@ -942,7 +970,7 @@
*lens-- = (byte) len;
}
}
- copy:
+
memcpy(end, dfield_get_data(field), len);
end += len;
}
@@ -1105,7 +1133,6 @@
dtype_t* type;
ulint i;
ulint prefix_len;
- ibool is_null;
ulint null_mask;
ulint status;
@@ -1146,20 +1173,22 @@
for (i = 0; i < n_fields; i++) {
field = dict_index_get_nth_field(index, i);
type = dict_col_get_type(dict_field_get_col(field));
- is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL);
- if (is_null) {
+ if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
/* nullable field => read the null flag */
- is_null = !!(*nulls & null_mask);
- null_mask <<= 1;
- if (null_mask == 0x100) {
- --nulls;
- UNIV_PREFETCH_R(nulls);
+ if (UNIV_UNLIKELY(!(byte) null_mask)) {
+ nulls--;
null_mask = 1;
}
+
+ if (*nulls & null_mask) {
+ null_mask <<= 1;
+ continue;
+ }
+
+ null_mask <<= 1;
}
- if (is_null) {
- } else if (field->fixed_len) {
+ if (field->fixed_len) {
prefix_len += field->fixed_len;
} else {
ulint len = *lens--;
| Thread |
|---|
| • bk commit into 5.0 tree (marko:1.1994) | Marko Mäkelä | 30 Jun |