]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
minor optimization for stringfields: when a field is being set to a larger value...
authorKevin P. Fleming <kpfleming@digium.com>
Wed, 23 Jul 2008 11:52:18 +0000 (11:52 +0000)
committerKevin P. Fleming <kpfleming@digium.com>
Wed, 23 Jul 2008 11:52:18 +0000 (11:52 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@132872 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/stringfields.h
main/utils.c

index 8b32f9ee7992416107ebdf9f1b955e2081f146e1..3a99cf5dc767679f746688ae2f3a336e5f0786e2 100644 (file)
@@ -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 */
 };
 
 /*!
@@ -137,6 +138,24 @@ struct ast_string_field_mgr {
 int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
                            ast_string_field *fields, int num_fields);
 
+/*!
+  \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
@@ -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
index 74ecfaf578571f257e46711963d3884d4b20f684..8906eff11987f9c6487a580edd172cdda1b74dfd 100644 (file)
@@ -1223,6 +1223,7 @@ static int add_string_pool(struct ast_string_field_mgr *mgr, size_t size)
        mgr->size = size;
        mgr->space = size;
        mgr->used = 0;
+       mgr->last_alloc = NULL;
 
        return 0;
 }
@@ -1259,12 +1260,36 @@ ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr
        result = mgr->pool->base + mgr->used;
        mgr->used += needed;
        mgr->space -= needed;
+       mgr->last_alloc = result;
        return result;
 }
 
+int __ast_string_field_index_grow(struct ast_string_field_mgr *mgr, size_t needed,
+                                 ast_string_field *fields, int index)
+{
+       int grow = needed - (strlen(fields[index]) + 1);
+
+       if (grow <= 0) {
+               return 0;
+       }
+
+       if (fields[index] != mgr->last_alloc) {
+               return 1;
+       }
+
+       if (mgr->space < grow) {
+               return 1;
+       }
+
+       mgr->space -= grow;
+       mgr->used += grow;
+
+       return 0;
+}
+
 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 ap1, va_list ap2)
+                                      ast_string_field *fields, int num_fields,
+                                      int index, const char *format, va_list ap1, va_list ap2)
 {
        size_t needed;
 
@@ -1285,6 +1310,7 @@ void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
        }
 
        fields[index] = mgr->pool->base + mgr->used;
+       mgr->last_alloc = fields[index];
        mgr->used += needed;
        mgr->space -= needed;
 }