List:Commits« Previous MessageNext Message »
From:ahristov Date:April 18 2007 4:29pm
Subject:PHP mysqlnd svn commit: r342 - trunk/mysqlnd
View as plain text  
Author: ahristov
Date: 2007-04-18 18:29:05 +0200 (Wed, 18 Apr 2007)
New Revision: 342

Modified:
   trunk/mysqlnd/mysqlnd.c
   trunk/mysqlnd/mysqlnd_palloc.c
   trunk/mysqlnd/mysqlnd_palloc.h
   trunk/mysqlnd/mysqlnd_wireprotocol.c
Log:
Add zval cache integration to PS. Now, they should be faster,
and use less emalloc/efree calls.


Modified: trunk/mysqlnd/mysqlnd.c
===================================================================
--- trunk/mysqlnd/mysqlnd.c	2007-04-18 16:13:59 UTC (rev 341)
+++ trunk/mysqlnd/mysqlnd.c	2007-04-18 16:29:05 UTC (rev 342)
@@ -168,20 +168,12 @@
 		zend_uchar *current_buffer = set->row_buffers[row];
 
 		for (col = 0; col < field_count; col++) {
-			if (result_type == MYSQLND_RES_PS) {
-				/* For now PS always does create copies when fetching data */
-				zval_ptr_dtor(&current_row[col]);
-
-				MYSQLND_INC_CONN_STATISTIC(NULL, STAT_COPY_ON_WRITE_PERFORMED);
-			} else {
-				zend_bool copy_ctor_called;
-				/* Free only if we haven't referenced it */
-				mysqlnd_palloc_zval_ptr_dtor(&(current_row[col]), zval_cache,
-											 FALSE, &copy_ctor_called TSRMLS_CC);
-
-				MYSQLND_INC_CONN_STATISTIC(NULL, copy_ctor_called? STAT_COPY_ON_WRITE_PERFORMED:
-																   STAT_COPY_ON_WRITE_SAVED);
-			}
+			zend_bool copy_ctor_called;
+			mysqlnd_palloc_zval_ptr_dtor(&(current_row[col]), zval_cache,
+										 result_type == MYSQLND_RES_PS,
+										 &copy_ctor_called TSRMLS_CC);
+			MYSQLND_INC_CONN_STATISTIC(NULL, copy_ctor_called? STAT_COPY_ON_WRITE_PERFORMED:
+															   STAT_COPY_ON_WRITE_SAVED);
 		}
 		pefree(current_row, set->persistent);
 		pefree(current_buffer, set->persistent);

Modified: trunk/mysqlnd/mysqlnd_palloc.c
===================================================================
--- trunk/mysqlnd/mysqlnd_palloc.c	2007-04-18 16:13:59 UTC (rev 341)
+++ trunk/mysqlnd/mysqlnd_palloc.c	2007-04-18 16:29:05 UTC (rev 342)
@@ -61,7 +61,7 @@
 	ret->references = 1;
 
 	/* 1. First initialize the free list part of the structure */
-	ret->free_list		= calloc(1, sizeof(mysqlnd_ndzval_list));
+	ret->free_list = calloc(1, sizeof(mysqlnd_ndzval_list));
 
 	/* One more for empty position of last_added - always 0x0, bounds checking */
 	ret->free_list->ptr_line = calloc(ret->max_items + 1, sizeof(mysqlnd_zval *));
@@ -161,21 +161,21 @@
   2. get_zval -> *last_added = NULL. Use MAKE_STD_ZVAL
   3. get_zval -> *last_added = NULL. Use MAKE_STD_ZVAL
   4. get_zval -> *last_added = NULL. Use MAKE_STD_ZVAL
-    0x0
- 	0x0
- 	0x0
- 	0x0 
- 	0x0
+	0x0
+	0x0
+	0x0
+	0x0
+	0x0
 	---
-    empty_position, always 0x0 <-- last_added
+	empty_position, always 0x0 <-- last_added
 
   5. free_zval -> if (free_items++ != max_items) {// we can add more
                     *(--last_added) = zval_ptr;
- 				 }
+				 }
 	(memory addresses increase downwards)
-    0x0
 	0x0
 	0x0
+	0x0
 	0x0 
 	0xA <-- last_added
 	---
@@ -184,9 +184,9 @@
   6. free_zval -> if (free_items++ != max_items) {// we can add more
                    *(--last_added) = zval_ptr;
 				 }
-    0x0
 	0x0
 	0x0
+	0x0
 	0xB <-- last_added
 	0xA 
 	---
@@ -195,38 +195,38 @@
   7. free_zval -> if (free_items++ != max_items) {// we can add more
                    *(--last_added) = zval_ptr;
 				 }
-    0x0
 	0x0
+	0x0
 	0xC <-- last_added
-	0xB 
-	0xA 
+	0xB
+	0xA
 	---
 	0x0
 
   8. get_zval -> *last_added != NULL. -> p = *last_added; *last_added++ = NULL;
-    0x0
 	0x0
-	0x0 
+	0x0
+	0x0
 	0xB <-- last_added
-	0xA 
+	0xA
 	---
 	0x0
 
   9. get_zval -> *last_added != NULL. -> p = *last_added; *last_added++ = NULL;
-    0x0
 	0x0
-	0x0 
-	0x0 
+	0x0
+	0x0
+	0x0
 	0xA <-- last_added
 	---
 	0x0
 
   10. get_zval -> *last_added != NULL. -> p = *last_added; *last_added++ = NULL;
-    0x0
 	0x0
-	0x0 
-	0x0 
-	0x0 
+	0x0
+	0x0
+	0x0
+	0x0
 	---
 	0x0 <-- last_added
 
@@ -267,7 +267,7 @@
 		*allocated = TRUE;
 	} else {
 		/* This will set the refcount to 1, increase it, to keep the variable */
-		INIT_PZVAL(&((mysqlnd_zval *) ret)->zv);	
+		INIT_PZVAL(&((mysqlnd_zval *) ret)->zv);
 		ZVAL_ADDREF(&(((mysqlnd_zval *)ret)->zv));
 	}
 
@@ -283,7 +283,6 @@
 #ifndef MYSQLND_SILENT
 	php_printf("[mysqlnd_palloc_zval_ptr_dtor %p] *zv=%p ps=%d refc=%d\n", cache, *zv, ps,
ZVAL_REFCOUNT(*zv));
 #endif
-	/* refcount is always > 1, because we call ZVAL_ADDREF(). Thus test refcount > 2
*/
 	*copy_ctor_called = FALSE;
 	/* Check whether cache is used and the zval is from the cache */
 	if (!cache || ((char *)*zv < (char *)cache->block || (char *)*zv > (char
*)cache->last_in_block)) {
@@ -310,14 +309,18 @@
 			} else {
 				/* For PS we copy stndup() the row buffers, so do nothing here */
 			}
-		} else if (ps == FALSE) {
-			/*
-			  Prevent Zend from freeing PS allocated data.
-			  Also don't null in Unicode mode as then the data doesn't point to
-			  the internal buffers and we will leak if we do this trick.
-			*/
-			if (IS_UNICODE_DISABLED) {
-				ZVAL_NULL(*zv);
+		} else {
+			if (ps == FALSE) {
+				/*
+				  Prevent Zend from freeing PS allocated data.
+				  Also don't null in Unicode mode as then the data doesn't point to
+				  the internal buffers and we will leak if we do this trick.
+				*/
+				if (IS_UNICODE_DISABLED) {
+					ZVAL_NULL(*zv);
+				}
+			} else {
+				/* For PS we copy stndup() the row buffers, so do nothing here */
 			}
 		}
 		zval_ptr_dtor(zv);
@@ -325,17 +328,21 @@
 	}
 
 	/* The zval is from our cache */
+	/* refcount is always > 1, because we call ZVAL_ADDREF(). Thus test refcount > 2
*/
 	if (ZVAL_REFCOUNT(*zv) > 2) {
 		/*
-		  Because the zval is first in mysqlnd_zval structure, then we can do
-		  upcasting from zval to mysqlnd_zval here. Because we know that this
+		  Because the zval is first element in mysqlnd_zval structure, then we can
+		  do upcasting from zval to mysqlnd_zval here. Because we know that this
 		  zval is part of our pre-allocated block.
 
 		  Now check whether this zval points to ZE allocated memory or to our
 		  buffers. If it points to the internal buffers, call copy_ctor()
 		  which will do estrndup for strings. And nothing for null, int, double.
+
+		  This branch will be skipped for PS, because there is no need to copy
+		  what is pointed by them, as they don't point to the internal buffers.
 		*/
-		if (((mysqlnd_zval *)*zv)->copy_alloced_on_result_free == FALSE) {
+		if (((mysqlnd_zval *)*zv)->copy_alloced_on_free_result == FALSE) {
 			/*
 			  In Unicode mode the destruction  of the zvals should not call
 			  zval_copy_ctor() because then we will leak.
@@ -343,10 +350,10 @@
 			  to check if we need to call copy_ctor().
 			*/
 			if (IS_UNICODE_DISABLED) {
-				zval_copy_ctor(*zv);			
+				zval_copy_ctor(*zv);
+				*copy_ctor_called = TRUE;
 			}
-			((mysqlnd_zval *)*zv)->copy_alloced_on_result_free = TRUE;
-			*copy_ctor_called = TRUE;
+			((mysqlnd_zval *)*zv)->copy_alloced_on_free_result = TRUE;
 		}
 		/*
 		  This will decrease the counter of the user-level (mysqlnd). When the engine
@@ -356,7 +363,7 @@
 		  memory allocated by us.
 		*/
 		zval_ptr_dtor(zv);
-		
+
 		/*
 		  Unfortunately, we can't return this variable to the free_list
 		  because it's still used. And this cleaning up will happen at request
@@ -371,18 +378,18 @@
 
 		++cache->put_hits;
 		++cache->free_items;
-		if (((mysqlnd_zval *)*zv)->copy_alloced_on_result_free == TRUE) {
+		if (((mysqlnd_zval *)*zv)->copy_alloced_on_free_result == TRUE) {
+			/* PS are here */
 			zval_dtor(*zv);
-			((mysqlnd_zval *)*zv)->copy_alloced_on_result_free = FALSE;	
-		}
-		ZVAL_DELREF(*zv);	/* Make it 1 */
-		if (!IS_UNICODE_DISABLED) {
+			((mysqlnd_zval *)*zv)->copy_alloced_on_free_result = FALSE;	
+		} else if (!IS_UNICODE_DISABLED) {
 			/*
 				When unicode is enabled we copy in rowp_read.
 				Thus we have to clean here.
 			*/
 			zval_dtor(*zv);
 		}
+		ZVAL_DELREF(*zv);	/* Make it 1 */
 		ZVAL_NULL(*zv);
 		*(--cache->free_list->last_added) = (mysqlnd_zval *)*zv;
 
@@ -413,9 +420,9 @@
 
 	LOCK_PCACHE(cache);
 	for (i = 0; i < cache->max_items; i++) {
-		if (cache->block[i].copy_alloced_on_result_free == TRUE) {
+		if (cache->block[i].copy_alloced_on_free_result == TRUE) {
 			zval_dtor(&(cache->block[i].zv));
-			cache->block[i].copy_alloced_on_result_free = FALSE;
+			cache->block[i].copy_alloced_on_free_result = FALSE;
 		}
 	}
 	UNLOCK_PCACHE(cache);
@@ -440,33 +447,33 @@
 
 			zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, "put_hits",
sizeof("put_hits") TSRMLS_CC);
 			add_u_assoc_long_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen + 1,
cache->put_hits);
-			efree(ustr);			
+			efree(ustr);
 			zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, "put_misses",
sizeof("put_misses") TSRMLS_CC);
 			add_u_assoc_long_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen + 1,
cache->put_hits);
-			efree(ustr);			
+			efree(ustr);
 			zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, "get_hits",
sizeof("get_hits") TSRMLS_CC);
 			add_u_assoc_long_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen + 1,
cache->put_hits);
-			efree(ustr);			
+			efree(ustr);
 			zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, "get_misses",
sizeof("get_misses") TSRMLS_CC);
 			add_u_assoc_long_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen + 1,
cache->put_hits);
-			efree(ustr);			
+			efree(ustr);
 			zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, "size", sizeof("size")
TSRMLS_CC);
 			add_u_assoc_long_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen + 1,
cache->put_hits);
-			efree(ustr);			
+			efree(ustr);
 			zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, "free_items",
sizeof("free_items") TSRMLS_CC);
 			add_u_assoc_long_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen + 1,
cache->put_hits);
-			efree(ustr);			
+			efree(ustr);
 			zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, "references",
sizeof("references") TSRMLS_CC);
 			add_u_assoc_long_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen + 1,
cache->put_hits);
-			efree(ustr);			
+			efree(ustr);
 		} else
 #endif
 		{
-			add_assoc_long_ex(return_value, "put_hits",		sizeof("put_hits"), 	cache->put_hits);
+			add_assoc_long_ex(return_value, "put_hits",		sizeof("put_hits"),		cache->put_hits);
 			add_assoc_long_ex(return_value,
"put_misses",	sizeof("put_misses"),	cache->put_misses);
-			add_assoc_long_ex(return_value, "get_hits", 	sizeof("get_hits"), 	cache->get_hits);
-			add_assoc_long_ex(return_value, "get_misses",	sizeof("get_misses"),
	cache->get_misses);
-			add_assoc_long_ex(return_value, "size", 		sizeof("size"), 		cache->max_items);
+			add_assoc_long_ex(return_value, "get_hits",		sizeof("get_hits"),		cache->get_hits);
+			add_assoc_long_ex(return_value,
"get_misses",	sizeof("get_misses"),	cache->get_misses);
+			add_assoc_long_ex(return_value, "size",			sizeof("size"),			cache->max_items);
 			add_assoc_long_ex(return_value,
"free_items",	sizeof("free_items"),	cache->free_items);
 			add_assoc_long_ex(return_value,
"references",	sizeof("references"),	cache->references);
 		}

Modified: trunk/mysqlnd/mysqlnd_palloc.h
===================================================================
--- trunk/mysqlnd/mysqlnd_palloc.h	2007-04-18 16:13:59 UTC (rev 341)
+++ trunk/mysqlnd/mysqlnd_palloc.h	2007-04-18 16:29:05 UTC (rev 342)
@@ -47,7 +47,7 @@
 typedef struct st_mysqlnd_zval {
 	/* Should be first */
 	zval		zv;
-	zend_bool	copy_alloced_on_result_free;
+	zend_bool	copy_alloced_on_free_result;
 } mysqlnd_zval;
 
 

Modified: trunk/mysqlnd/mysqlnd_wireprotocol.c
===================================================================
--- trunk/mysqlnd/mysqlnd_wireprotocol.c	2007-04-18 16:13:59 UTC (rev 341)
+++ trunk/mysqlnd/mysqlnd_wireprotocol.c	2007-04-18 16:29:05 UTC (rev 342)
@@ -351,7 +351,7 @@
 	}
 	/* Even for zero size payload we have to send a packet */
 	int3store(safe_storage, header_len == MYSQLND_HEADER_SIZE? left:left+1);
-	int1store(safe_storage + 3, net->packet_no);		
+	int1store(safe_storage + 3, net->packet_no);
 	net->packet_no++;
 	
 	ret = php_stream_write(net->stream, (char *)safe_storage, header_len);
@@ -1146,6 +1146,8 @@
 	zend_uchar *null_ptr, bit;
 	zval **current_field, **end_field, **start_field;
 	zend_bool as_unicode = conn->options.numeric_and_datetime_as_unicode;
+	zend_bool allocated;
+	void *obj;
 
 	end_field = (current_field = start_field = packet->fields) + packet->field_count;
 
@@ -1157,7 +1159,18 @@
 	bit	= 4;								/* first 2 bits are reserved */
 
 	for (i = 0; current_field < end_field; current_field++, i++) {
+#if 1
+		obj = mysqlnd_palloc_get_zval(conn->zval_cache, &allocated);
+		if (allocated) {
+			*current_field = (zval *) obj;
+		} else {
+			/* It's from the cache, so we can upcast here */
+			*current_field = &((mysqlnd_zval *) obj)->zv;			
+			((mysqlnd_zval *) obj)->copy_alloced_on_free_result = TRUE;
+		}
+#else
 		MAKE_STD_ZVAL(*current_field);
+#endif
 		if (*null_ptr & bit) {
 			ZVAL_NULL(*current_field);
 		} else {
@@ -1204,7 +1217,7 @@
 		} else {
 			/* It's from the cache, so we can upcast here */
 			*current_field = &((mysqlnd_zval *) obj)->zv;			
-			((mysqlnd_zval *) obj)->copy_alloced_on_result_free = FALSE;
+			((mysqlnd_zval *) obj)->copy_alloced_on_free_result = FALSE;
 		}
 
 		if (current_field > start_field && last_field_was_string) {

Thread
PHP mysqlnd svn commit: r342 - trunk/mysqlndahristov18 Apr