THRIFT-3839 Performance issue with big message deserialization using php extension
This closes #1014
diff --git a/lib/php/lib/Thrift/Serializer/TBinarySerializer.php b/lib/php/lib/Thrift/Serializer/TBinarySerializer.php
index 7e0cf8b..aa2f71b 100644
--- a/lib/php/lib/Thrift/Serializer/TBinarySerializer.php
+++ b/lib/php/lib/Thrift/Serializer/TBinarySerializer.php
@@ -57,7 +57,7 @@
return $transport->getBuffer();
}
- public static function deserialize($string_object, $class_name)
+ public static function deserialize($string_object, $class_name, $buffer_size = 8192)
{
$transport = new TMemoryBuffer();
$protocol = new TBinaryProtocolAccelerated($transport);
@@ -72,7 +72,8 @@
$protocolTransport->flush();
return thrift_protocol_read_binary($protocol, $class_name,
- $protocol->isStrictRead());
+ $protocol->isStrictRead(),
+ $buffer_size);
} else {
$transport->write($string_object);
$object = new $class_name();
diff --git a/lib/php/lib/Thrift/Transport/TMemoryBuffer.php b/lib/php/lib/Thrift/Transport/TMemoryBuffer.php
index 5fc26bf..ca31c57 100644
--- a/lib/php/lib/Thrift/Transport/TMemoryBuffer.php
+++ b/lib/php/lib/Thrift/Transport/TMemoryBuffer.php
@@ -92,4 +92,9 @@
{
return TStringFuncFactory::create()->strlen($this->buf_);
}
+
+ public function putBack($data)
+ {
+ $this->buf_ = $data.$this->buf_;
+ }
}
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
index 65cfb16..a0de645 100644
--- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
+++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
@@ -994,7 +994,7 @@
}
}
-// 3 params: $transport $response_Typename $strict_read
+// 4 params: $transport $response_Typename $strict_read $buffer_size
PHP_FUNCTION(thrift_protocol_read_binary) {
int argc = ZEND_NUM_ARGS();
@@ -1017,8 +1017,19 @@
RETURN_NULL();
}
+ if (argc == 4 && Z_TYPE_PP(args[3]) != IS_LONG) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "4nd parameter is not an integer (typename of expected buffer size)");
+ efree(args);
+ RETURN_NULL();
+ }
+
try {
- PHPInputTransport transport(*args[0]);
+ size_t buffer_size = 8192;
+ if (argc == 4) {
+ buffer_size = Z_LVAL_PP(args[3]);
+ }
+
+ PHPInputTransport transport(*args[0], buffer_size);
char* obj_typename = Z_STRVAL_PP(args[1]);
convert_to_boolean(*args[2]);
bool strict_read = Z_BVAL_PP(args[2]);
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp
index e482762..c4c76cf 100644
--- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp
+++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp
@@ -959,18 +959,19 @@
}
-// 3 params: $transport $response_typename $strict_read
+// 4 params: $transport $response_Typename $strict_read $buffer_size
PHP_FUNCTION(thrift_protocol_read_binary) {
zval *protocol;
zend_string *obj_typename;
zend_bool strict_read;
+ size_t buffer_size = 8192;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "oSb", &protocol, &obj_typename, &strict_read) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "oSb|l", &protocol, &obj_typename, &strict_read, &buffer_size) == FAILURE) {
return;
}
try {
- PHPInputTransport transport(protocol);
+ PHPInputTransport transport(protocol, buffer_size);
int8_t messageType = 0;
int32_t sz = transport.readI32();