aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-23 11:52:18 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-23 11:52:18 +0000
commit1fd4a59f8b2223f7f727b06803552069ef7b508f (patch)
tree72c8789224b248f3ca47752f0a41817e73f0f383 /include
parente29afcb66573c0d7e28b705bfba2ce25d0a8b405 (diff)
minor optimization for stringfields: when a field is being set to a larger value than it currently contains and it happens to be the most recent field allocated from the currentl pool, it is possible to 'grow' it without having to waste the space it is currently using (or potentially even allocate a new pool)
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@132872 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'include')
-rw-r--r--include/asterisk/stringfields.h73
1 files changed, 45 insertions, 28 deletions
diff --git a/include/asterisk/stringfields.h b/include/asterisk/stringfields.h
index 8b32f9ee7..3a99cf5dc 100644
--- a/include/asterisk/stringfields.h
+++ b/include/asterisk/stringfields.h
@@ -123,6 +123,7 @@ struct ast_string_field_mgr {
size_t size; /*!< the total size of the current pool */
size_t space; /*!< the space available in the current pool */
size_t used; /*!< the space used in the current pool */
+ ast_string_field last_alloc; /*!< the last field allocated */
};
/*!
@@ -139,6 +140,24 @@ int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
/*!
\internal
+ \brief Attempt to 'grow' an already allocated field to a larger size
+ \param mgr Pointer to the pool manager structure
+ \param needed Amount of space needed for this field
+ \param fields Pointer to the first entry of the field array
+ \param index Index position of the field within the structure
+ \return 0 on success, non-zero on failure
+
+ This function will attempt to increase the amount of space allocated to
+ an existing field to the amount requested; this is only possible if the
+ field was the last field allocated from the current storage pool and
+ the pool has enough space available. If so, the additional space will be
+ allocated to this field and the field's address will not be changed.
+*/
+int __ast_string_field_index_grow(struct ast_string_field_mgr *mgr, size_t needed,
+ ast_string_field *fields, int index);
+
+/*!
+ \internal
\brief Allocate space for a field
\param mgr Pointer to the pool manager structure
\param needed Amount of space needed for this field
@@ -180,8 +199,8 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
\return nothing
*/
void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
- ast_string_field *fields, int num_fields,
- int index, const char *format, va_list a1, va_list a2);
+ ast_string_field *fields, int num_fields,
+ int index, const char *format, va_list a1, va_list a2);
/*!
\brief Declare a string field
@@ -234,36 +253,36 @@ void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
\return nothing
*/
#define ast_string_field_index_set(x, index, data) do { \
- char *__zz__ = (char*)(x)->__begin_field[index]; \
- size_t __dlen__ = strlen(data); \
- if( __dlen__ == 0 ) { (x)->__begin_field[index] = __ast_string_field_empty; \
+ char *__zz__ = (char*) (x)->__begin_field[index]; \
+ size_t __dlen__ = strlen(data) + 1; \
+ if ( __dlen__ == 1 ) {\
+ (x)->__begin_field[index] = __ast_string_field_empty; \
} else { \
- if( __zz__[0] != 0 && __dlen__ <= strlen(__zz__) ) { \
- strcpy(__zz__, data); \
- } else { \
- if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__ + 1, &(x)->__begin_field[0], ast_string_field_count(x)))) \
- strcpy((char*)(x)->__begin_field[index], data); \
- } \
- } \
+ if (!__ast_string_field_index_grow(&(x)->__field_mgr, __dlen__, &(x)->__begin_field[0], index)) { \
+ memcpy(__zz__, data, __dlen__); \
+ } else { \
+ if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__, &(x)->__begin_field[0], ast_string_field_count(x)))) \
+ memcpy((char*) (x)->__begin_field[index], data, __dlen__); \
+ } \
+ } \
} while (0)
-#ifdef FOR_TEST
#define ast_string_field_index_logset(x, index, data, logstr) do { \
- char *__zz__ = (char*)(x)->__begin_field[index]; \
- size_t __dlen__ = strlen(data); \
- if( __dlen__ == 0 ) { (x)->__begin_field[index] = __ast_string_field_empty; \
+ char *__zz__ = (char*) (x)->__begin_field[index]; \
+ size_t __dlen__ = strlen(data) + 1; \
+ if ( __dlen__ == 1 ) {\
+ (x)->__begin_field[index] = __ast_string_field_empty; \
} else { \
- if( __zz__[0] != 0 && __dlen__ <= strlen(__zz__) ) { \
- ast_verbose("%s: ======replacing '%s' with '%s'\n", logstr, __zz__, data); \
- strcpy(__zz__, data); \
- } else { \
- ast_verbose("%s: ++++++allocating room for '%s' to replace '%s'\n", logstr, data, __zz__); \
- if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__ + 1, &(x)->__begin_field[0], ast_string_field_count(x)))) \
- strcpy((char*)(x)->__begin_field[index], data); \
- } \
- } \
+ if (!__ast_string_field_index_grow(&(x)->__field_mgr, __dlen__, &(x)->__begin_field[0], index)) { \
+ ast_verbose("%s: ======replacing '%s' with '%s'\n", logstr, __zz__, data); \
+ memcpy(__zz__, data, __dlen__); \
+ } else { \
+ if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__, &(x)->__begin_field[0], ast_string_field_count(x)))) \
+ ast_verbose("%s: ++++++allocating room for '%s' to replace '%s'\n", logstr, data, __zz__); \
+ memcpy((char*) (x)->__begin_field[index], data, __dlen__); \
+ } \
+ } \
} while (0)
-#endif
/*!
\brief Set a field to a simple string value
@@ -275,10 +294,8 @@ void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
#define ast_string_field_set(x, field, data) \
ast_string_field_index_set(x, ast_string_field_index(x, field), data)
-#ifdef FOR_TEST
#define ast_string_field_logset(x, field, data, logstr) \
ast_string_field_index_logset(x, ast_string_field_index(x, field), data, logstr)
-#endif
/*!
\brief Set a field to a complex (built) value