List:Internals« Previous MessageNext Message »
From:Marko Mäkelä Date:June 30 2005 10:20am
Subject:bk commit into 5.0 tree (marko:1.1994)
View as plain text  
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