MySQL Dynamic String processing
In MySQL, you will often see some processing of dynamic strings, such as: Dynamic_string. In order to record the actual length of the dynamic string, the maximum length of the buffer, and each time the string needs to be adjusted, the new memory is allocated in time, and the length is adjusted. MySQL uses dynamic_string to save dynamic string-related information:
- typedef struct ST_DYNAMIC_STRING
- {
- Char *str;
- size_t length,max_length,alloc_increment;
In this struct, STR stores the first address of the actual string, length records the actual length of the string, how many characters the Max_length record string buffer can hold, and alloc_increment indicates how much memory is allocated each time the string needs to allocate memory.
Here's a look at the initialization process for this struct:
- My_bool init_dynamic_string (dynamic_string *str, const char *init_str,size_t init_alloc, size_t alloc_increment)
- {
- size_t length;
- Dbug_enter ("init_dynamic_string");
- if (!alloc_increment)
- alloc_increment=128;
- length=1;
- if (init_str && (length= strlen (INIT_STR) +1) < Init_alloc)
- Init_alloc= ((length+alloc_increment-1)/alloc_increment) *alloc_increment;
- if (!init_alloc)
- Init_alloc=alloc_increment;
- if (! ( Str->str= (char*) My_malloc (INIT_ALLOC,MYF (MY_WME))))
- Dbug_return (TRUE);
- str->length=length-1;
- if (INIT_STR)
- memcpy (str->str,init_str,length);
- str->max_length=init_alloc;
- str->alloc_increment=alloc_increment;
- Dbug_return (FALSE);
- }
As you can see from the above function, when initializing, the initial allocated string buffer size Init_alloc will be judged based on the string that needs to be initialized. After allocating the dynamic_string space, we initialize it based on the size of the buffer, the actual length of the string, and alloc_increment: length: The actual length of the string max_length: Maximum length of the buffer alloc_ Increment: When space is not enough, the next time you allocate memory for the cell size.
After initializing the content, if you need to add more characters to the buffer next time, you can determine whether the buffer needs to be expanded by these values:
- My_bool Dynstr_append_mem (dynamic_string *str, const char *append,
- size_t length)
- {
- Char *new_ptr;
- if (str->length+length >= str->max_length)//If a new string is added, the total length exceeds the buffer size
- {
- How many alloc_increment-sized memory needs to be allocated in order to save the new string
- size_t new_length= (str->length+length+str->alloc_increment)/
- str->alloc_increment;
- new_length*=str->alloc_increment;
- if (! ( New_ptr= (char*) My_realloc (STR->STR,NEW_LENGTH,MYF (MY_WME))))
- return TRUE;
- str->str=new_ptr;
- str->max_length=new_length;
- }
- Append the newly allocated content to Str
- memcpy (Str->str + str->length,append,length);
- str->length+=length; New length of Str after expansion
- str->str[str->length]=0; /* Safety for C programs *///The last character of the string is ' \ s '
- return FALSE;
- }
As can be seen from the above code, after the initialization of the string, and then if you need to add new content to the string, just based on the previously stored information to the dynamic realloc. Because the structure records the complete string-related content, dynamic expansion is very easy to handle.
Of course, in addition to these, there are examples such as string truncation, string initialization, escaping OS quotes, and so on: the truncation after the string offset is greater than N.
- My_bool Dynstr_trunc (dynamic_string *str, size_t N)
- {
- str->length-=n;
- str->str[str->length]= ' + ';
- return FALSE;
Returns the address of the first occurrence of a character in a string. If not, returns the address at the end of the string (point to '% ')
- Char *strcend (Register const char *s, register Pchar c)
- {
- for (;;)
- {
- if (*s = = (char) c) return (char*) s;
- if (!*s++) return (char*) s-1;
- }
String Content Expansion:
- My_bool Dynstr_realloc (dynamic_string *str, size_t additional_size)
- {
- Dbug_enter ("Dynstr_realloc");
- if (!additional_size) Dbug_return (FALSE);
- if (str->length + additional_size > Str->max_length)//If the new string content exceeds the maximum length of the buffer
- {
- Str->max_length= ((str->length + additional_size+str->alloc_increment-1)/
- Str->alloc_increment) *str->alloc_increment;
- if (! ( Str->str= (char*) My_realloc (STR->STR,STR->MAX_LENGTH,MYF (MY_WME))))
- Dbug_return (TRUE);
- }
- Dbug_return (FALSE);
Enclose the string in quotation marks, escaping the single quotation mark, which is used primarily to execute some system commands (systems (CMD)). For example: Ls-al will become \ ' ls-al\ ' such as: Ls-a ' l will become ' ls-a\\\ ' l\ '
- /*
- Concatenates any number of strings, escapes any OS quote in the result then
- Surround the whole affair in another set of quotes which is finally appended
- to specified dynamic_string. This function was especially useful when
- Building strings to is executed with the system () function.
- @param str Dynamic String which would have addtional strings appended.
- @param append String to is appended.
- @param ... Optional. Additional string (s) to is appended.
- @note The final argument in the list must is NullS even if no additional
- Options are passed.
- @return True = Success.
- */
- My_bool dynstr_append_os_quoted (dynamic_string *str, const char *append, ...)
- {
- const char *quote_str= "\";
- const UINT Quote_len= 1;
- My_bool ret= TRUE;
- Va_list Dirty_text;
- ret&= Dynstr_append_mem (str, QUOTE_STR, Quote_len); /* Leading Quote */
- Va_start (Dirty_text, append);
- while (Append! = NullS)
- {
- const char *cur_pos= append;
- const char *next_pos= cur_pos;
- /* Search for quote in each string and replace with escaped quote */
- while (* (* (next_pos= strcend (Cur_pos, quote_str[0]))! = ' + ')
- {
- ret&= Dynstr_append_mem (str, cur_pos, (UINT) (Next_pos-cur_pos));
- ret&= Dynstr_append_mem (str, "\ \", 1);
- ret&= Dynstr_append_mem (str, QUOTE_STR, Quote_len);
- cur_pos= Next_pos + 1;
- }
- ret&= Dynstr_append_mem (str, cur_pos, (UINT) (Next_pos-cur_pos));
- Append= Va_arg (Dirty_text, char *);
- }
- Va_end (Dirty_text);
- ret&= Dynstr_append_mem (str, QUOTE_STR, Quote_len); /* Trailing Quote */
- return ret;
- }
By defining the structure information of a dynamic string, each time a string is added more characters, it is dynamically expanded according to the current length of the string. And after each expansion, the struct records the actual information of the current string (the length of the current string, the buffer can hold the length of the string, the unit length for expansion). This makes it very convenient to manipulate dynamic strings.
http://www.bkjia.com/PHPjc/1079090.html www.bkjia.com true http://www.bkjia.com/PHPjc/1079090.html techarticle mysql dynamic string processing in MySQL, often see some of the dynamic string processing, such as: Dynamic_string. In order to record the actual length of the dynamic string, the buffer is the most ...