com php-src: Cache arguments type info in MessageFormatter.: ext/intl/msgformat/msgformat_attr.c ext/intl/msgformat/ms gformat_data.c
ext/intl/msgformat/msgformat_data.h ext/intl/msgformat/msgformat_format.c ext/intl/msgformat/ msgformat_helpers.cpp ext/intl/msgformat/msgformat_help
ers.h ext/intl/tests/msgfmt_setPattern_cache.phpt
| From: | Gustavo André dos Santos Lopes | Date: | Sun, 13 May 2012 19:53:05 +0000 |
| Subject: | com php-src: Cache arguments type info in MessageFormatter.: ext/intl/msgformat/msgformat_attr.c ext/intl/msgformat/ms gformat_data.c ext/intl/msgformat/msgformat_data.h ext/intl/msgformat/msgformat_format.c ext/intl/msgformat/ msgformat_helpers.cpp ext/intl/msgformat/msgformat_help ers.h ext/intl/tests/msgfmt_setPattern_cache.phpt |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-69053@lists.php.net to get a copy of this message | ||
Commit: 20dd5ccf19916a290973a2e25de4eed59b169093
Author: Gustavo André dos Santos Lopes <cataphract@php.net> Sun, 6 May 2012
16:31:52 +0200
Parents: 407455876e486df45a6b6c91b483060b0479a0b3
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=20dd5ccf19916a290973a2e25de4eed59b169093
Log:
Cache arguments type info in MessageFormatter.
Changed paths:
M ext/intl/msgformat/msgformat_attr.c
M ext/intl/msgformat/msgformat_data.c
M ext/intl/msgformat/msgformat_data.h
M ext/intl/msgformat/msgformat_format.c
M ext/intl/msgformat/msgformat_helpers.cpp
M ext/intl/msgformat/msgformat_helpers.h
A ext/intl/tests/msgfmt_setPattern_cache.phpt
Diff:
diff --git a/ext/intl/msgformat/msgformat_attr.c b/ext/intl/msgformat/msgformat_attr.c
index cf34665..c7a4d1c 100755
--- a/ext/intl/msgformat/msgformat_attr.c
+++ b/ext/intl/msgformat/msgformat_attr.c
@@ -100,6 +100,12 @@ PHP_FUNCTION( msgfmt_set_pattern )
}
mfo->mf_data.orig_format = estrndup(value, value_len);
mfo->mf_data.orig_format_len = value_len;
+ /* invalidate cached format types */
+ if (mfo->mf_data.arg_types) {
+ zend_hash_destroy(mfo->mf_data.arg_types);
+ efree(mfo->mf_data.arg_types);
+ mfo->mf_data.arg_types = NULL;
+ }
RETURN_TRUE;
}
diff --git a/ext/intl/msgformat/msgformat_data.c b/ext/intl/msgformat/msgformat_data.c
index 95e81d3..9ed129f 100755
--- a/ext/intl/msgformat/msgformat_data.c
+++ b/ext/intl/msgformat/msgformat_data.c
@@ -31,6 +31,7 @@ void msgformat_data_init( msgformat_data* mf_data TSRMLS_DC )
mf_data->umsgf = NULL;
mf_data->orig_format = NULL;
+ mf_data->arg_types = NULL;
intl_error_reset( &mf_data->error TSRMLS_CC );
}
/* }}} */
@@ -38,21 +39,27 @@ void msgformat_data_init( msgformat_data* mf_data TSRMLS_DC )
/* {{{ void msgformat_data_free( msgformat_data* mf_data )
* Clean up memory allocated for msgformat_data
*/
-void msgformat_data_free( msgformat_data* mf_data TSRMLS_DC )
+void msgformat_data_free(msgformat_data* mf_data TSRMLS_DC)
{
- if( !mf_data )
+ if (!mf_data)
return;
- if( mf_data->umsgf )
- umsg_close( mf_data->umsgf );
+ if (mf_data->umsgf)
+ umsg_close(mf_data->umsgf);
- if(mf_data->orig_format) {
+ if (mf_data->orig_format) {
efree(mf_data->orig_format);
mf_data->orig_format = NULL;
}
+ if (mf_data->arg_types) {
+ zend_hash_destroy(mf_data->arg_types);
+ efree(mf_data->arg_types);
+ mf_data->arg_types = NULL;
+ }
+
mf_data->umsgf = NULL;
- intl_error_reset( &mf_data->error TSRMLS_CC );
+ intl_error_reset(&mf_data->error TSRMLS_CC);
}
/* }}} */
diff --git a/ext/intl/msgformat/msgformat_data.h b/ext/intl/msgformat/msgformat_data.h
index 4400175..5a82003 100755
--- a/ext/intl/msgformat/msgformat_data.h
+++ b/ext/intl/msgformat/msgformat_data.h
@@ -31,6 +31,7 @@ typedef struct {
UMessageFormat* umsgf;
char* orig_format;
ulong orig_format_len;
+ HashTable* arg_types;
} msgformat_data;
msgformat_data* msgformat_data_create( TSRMLS_D );
diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.c
index 099dbcb..412a5f7 100755
--- a/ext/intl/msgformat/msgformat_format.c
+++ b/ext/intl/msgformat/msgformat_format.c
@@ -57,7 +57,7 @@ static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *ret
zend_hash_copy(args_copy, Z_ARRVAL_P(args), (copy_ctor_func_t)zval_add_ref,
NULL, sizeof(zval*));
- umsg_format_helper(MSG_FORMAT_OBJECT(mfo), args_copy,
+ umsg_format_helper(mfo, args_copy,
&formatted, &formatted_len, &INTL_DATA_ERROR_CODE(mfo) TSRMLS_CC);
zend_hash_destroy(args_copy);
diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp
index 503dca9..1a7dc89 100755
--- a/ext/intl/msgformat/msgformat_helpers.cpp
+++ b/ext/intl/msgformat/msgformat_helpers.cpp
@@ -100,7 +100,9 @@ double umsg_helper_zval_to_millis(zval *z, UErrorCode *status TSRMLS_DC) {
return rv;
}
-static HashTable *umsg_parse_format(const MessagePattern& mp, UErrorCode& uec)
+static HashTable *umsg_parse_format(MessageFormatter_object *mfo,
+ const MessagePattern& mp,
+ UErrorCode& uec)
{
HashTable *ret;
int32_t parts_count;
@@ -109,6 +111,11 @@ static HashTable *umsg_parse_format(const MessagePattern& mp,
UErrorCode& uec)
return NULL;
}
+ if (mfo->mf_data.arg_types) {
+ /* already cached */
+ return mfo->mf_data.arg_types;
+ }
+
/* Hash table will store Formattable::Type objects directly,
* so no need for destructor */
ALLOC_HASHTABLE(ret);
@@ -235,22 +242,24 @@ static HashTable *umsg_parse_format(const MessagePattern& mp,
UErrorCode& uec)
return NULL;
}
+ mfo->mf_data.arg_types = ret;
+
return ret;
}
-U_CFUNC void umsg_format_helper(UMessageFormat *fmt, HashTable *args, UChar **formatted, int
*formatted_len, UErrorCode *status TSRMLS_DC)
+U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, HashTable *args, UChar **formatted,
int *formatted_len, UErrorCode *status TSRMLS_DC)
{
int arg_count = zend_hash_num_elements(args);
std::vector<Formattable> fargs;
std::vector<UnicodeString> farg_names;
- MessageFormat *mf = (MessageFormat *) fmt;
+ MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf;
const MessagePattern mp = MessageFormatAdapter::getMessagePattern(mf);
HashTable *types;
fargs.resize(arg_count);
farg_names.resize(arg_count);
- types = umsg_parse_format(mp, *status);
+ types = umsg_parse_format(mfo, mp, *status);
if (U_FAILURE(*status)) {
return;
}
@@ -391,9 +400,6 @@ string_arg: //XXX: make function
}
} // visiting each argument
- zend_hash_destroy(types);
- efree(types);
-
if (U_FAILURE(*status)){
return;
}
diff --git a/ext/intl/msgformat/msgformat_helpers.h b/ext/intl/msgformat/msgformat_helpers.h
index 4e10471..7a04248 100755
--- a/ext/intl/msgformat/msgformat_helpers.h
+++ b/ext/intl/msgformat/msgformat_helpers.h
@@ -18,7 +18,7 @@
#define MSG_FORMAT_HELPERS_H
int32_t umsg_format_arg_count(UMessageFormat *fmt);
-void umsg_format_helper(UMessageFormat *fmt, HashTable *args,
+void umsg_format_helper(MessageFormatter_object *mfo, HashTable *args,
UChar **formatted, int *formatted_len, UErrorCode *status TSRMLS_DC);
void umsg_parse_helper(UMessageFormat *fmt, int *count, zval ***args,
UChar *source, int source_len, UErrorCode *status);
diff --git a/ext/intl/tests/msgfmt_setPattern_cache.phpt
b/ext/intl/tests/msgfmt_setPattern_cache.phpt
new file mode 100644
index 0000000..35ec463
--- /dev/null
+++ b/ext/intl/tests/msgfmt_setPattern_cache.phpt
@@ -0,0 +1,26 @@
+--TEST--
+MessageFormatter::setPattern() invalidates arg types cache
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+
+$mf = new MessageFormatter('en_US',
+ "{0,number} -- {1,ordinal}");
+
+var_dump($mf->format(array(1.3, 1.3)));
+var_dump($mf->format(array(1.3, 1.3)));
+$mf->setPattern("{0,ordinal} -- {1,number}");
+var_dump($mf->format(array(1.3, 1.3)));
+
+?>
+==DONE==
+--EXPECT--
+string(10) "1.3 -- 1st"
+string(10) "1..3 -- 1st"
+string(10) "1st -- 1.3"
+==DONE==
\ No newline at end of file