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(¤t_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, ©_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,
+ ©_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/mysqlnd | ahristov | 18 Apr |