MySQL動(dòng)態(tài)字符串處理DYNAMIC_STRING
MySQL中,常常會(huì)看到一些關(guān)于動(dòng)態(tài)字符串的處理,列如:DYNAMIC_STRING。
為了記錄動(dòng)態(tài)字符串的實(shí)際長(zhǎng)度,緩沖區(qū)的最大長(zhǎng)度,以及每次字符串需要調(diào)整時(shí),及時(shí)分配新的內(nèi)存,以及調(diào)整長(zhǎng)度。MySQL使用了DYNAMIC_STRING來(lái)保存動(dòng)態(tài)字符串相關(guān)的信息:
typedef struct st_dynamic_string
{
char *str;
size_t length, max_length, alloc_increment;
} DYNAMIC_STRING;
在這個(gè)結(jié)構(gòu)體中,str存儲(chǔ)實(shí)際字符串的首地址,length記錄字符串的實(shí)際長(zhǎng)度,max_length記錄字符串緩沖區(qū)最多可以存放多少字符,alloc_increment表示當(dāng)字符串需要分配內(nèi)存時(shí),每次分配多少內(nèi)存。
下面看看這個(gè)結(jié)構(gòu)體的初始化過(guò)程:
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 );
}
從上述函數(shù)可以看到,初始化時(shí),初始分配的字符串緩沖區(qū)大小init_alloc會(huì)根據(jù)需要初始的字符串來(lái)做判斷。在分配好該DYNAMIC_STRING空間之后,我們會(huì)根據(jù)緩沖區(qū)的大小,字符串的實(shí)際長(zhǎng)度,以及alloc_increment來(lái)初始化:
length:字符串的實(shí)際長(zhǎng)度
max_length:緩沖區(qū)的最大長(zhǎng)度
alloc_increment:空間不夠時(shí),下次分配內(nèi)存的單元大小.
初始化這些內(nèi)容之后,如果下次需要在該緩沖區(qū)添加更多字符,就可以根據(jù)這些值來(lái)判斷是否需要對(duì)該緩沖區(qū)擴(kuò)容:
my_bool dynstr_append_mem( DYNAMIC_STRING *str, const char *append, size_t length )
{
char *new_ptr;
if ( str->length + length >= str->max_length ) /* 如果新增字符串后,總長(zhǎng)度超過(guò)緩沖區(qū)大小 */
{
/* 需要分配多少個(gè)alloc_increment 大小的內(nèi)存,才能存下新增后的字符串 */
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;
}
/* 將新分配的內(nèi)容,append到str之后 */
memcpy( str->str + str->length, append, length );
str->length += length; /* 擴(kuò)容之后str新的長(zhǎng)度 */
str->str[str->length] = 0; /* Safety for C programs */ /* 字符串最后一個(gè)字符為'\0' */
return(FALSE);
}
從上述代碼可以看到,在字符串初始化化好之后,之后如果需要給該字符串增加新的內(nèi)容,只需要根據(jù)之前存儲(chǔ)的信息來(lái)動(dòng)態(tài)的realloc就好了。由于該結(jié)構(gòu)體記錄了字符串相關(guān)的完整內(nèi)容,所以動(dòng)態(tài)的擴(kuò)容會(huì)非常方便處理。
當(dāng)然,除了這些,還有比如字符串截?cái)?,字符串初始設(shè)置,轉(zhuǎn)義OS的引號(hào)等等:
將字符串偏移大于N之后的截?cái)唷?/p>
my_bool dynstr_trunc( DYNAMIC_STRING *str, size_t n )
{
str->length -= n;
str->str[str->length] = '\0';
return(FALSE);
}
返回字符串中第一次出現(xiàn)某個(gè)字符的地址。若沒(méi)有,則返回字符串結(jié)尾的地址(指向'')
char *strcend( register const char *s, register pchar c )
{
for (;; )
{
if ( *s == (char) c )
return( (char *) s);
if ( !*s++ )
return( (char *) s - 1);
}
}
字符串內(nèi)容擴(kuò)容:
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 ) /* 如果新的字符串內(nèi)容超過(guò)緩沖區(qū)的最大長(zhǎng)度 */
{
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 );
}
對(duì)字符串用引號(hào)括起來(lái),對(duì)其中的單引號(hào)進(jìn)行轉(zhuǎn)義,主要用于執(zhí)行一些系統(tǒng)命令(system(cmd))。
比如:ls -al 會(huì)變成 ‘ls -al'
比如:ls -a'l會(huì)變成'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 is especially useful when
* building strings to be executed with the system() function.
*
* @param str Dynamic String which will have addtional strings appended.
* @param append String to be appended.
* @param ... Optional. Additional string(s) to be appended.
*
* @ note The final argument in the list must be 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] ) ) != '\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);
}
通過(guò)定義動(dòng)態(tài)字符串的結(jié)構(gòu)體信息,每次分次進(jìn)行字符串添加更多字符,都會(huì)根據(jù)字符串的當(dāng)前的長(zhǎng)度動(dòng)態(tài)的擴(kuò)容。而且每次擴(kuò)容后,該結(jié)構(gòu)體都記錄的當(dāng)前字符串的實(shí)際信息(當(dāng)前字符串的長(zhǎng)度,緩沖器可容納字符串的長(zhǎng)度,進(jìn)行擴(kuò)容的單元長(zhǎng)度)。這樣,動(dòng)態(tài)字符串的處理操作就變得非常方便了。
相關(guān)文章
sql語(yǔ)句中l(wèi)ike的用法詳細(xì)解析
以下是對(duì)sql語(yǔ)句中l(wèi)ike的用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-08-08
Mysql 5.7 服務(wù)下載安裝圖文教程(經(jīng)典版)
MySQL 5.7在諸多方面都進(jìn)行了大幅的改進(jìn),主要在于安全性、靈活性、易用性、可用性和性能等幾個(gè)方面。這篇文章主要介紹了Mysql5.7服務(wù)下載安裝圖文教程(經(jīng)典版),需要的朋友可以參考下2016-09-09
MySQL性能優(yōu)化之一條SQL在MySQL中執(zhí)行的過(guò)程詳解
天天和數(shù)據(jù)庫(kù)打交道,一天能寫(xiě)上幾十條 SQL 語(yǔ)句,但你知道系統(tǒng)是如何和數(shù)據(jù)庫(kù)交互的嗎?下面這篇文章主要給大家介紹了關(guān)于MySQL性能優(yōu)化之一條SQL在MySQL中執(zhí)行的過(guò)程的相關(guān)資料,需要的朋友可以參考下2023-02-02
MySQL關(guān)系型數(shù)據(jù)庫(kù)事務(wù)的ACID特性與實(shí)現(xiàn)
這篇文章主要介紹了MySQL關(guān)系型數(shù)據(jù)庫(kù)事務(wù)的ACID特性與實(shí)現(xiàn),ACID?是為保證事務(wù)transaction是正確可靠的,具備原子性、一致性、隔離性、持久性等特性2022-07-07
MySQL中START REPLICA語(yǔ)句的具體使用
MySQL從8.0.22版本開(kāi)始引入了START REPLICA語(yǔ)句,替代了原來(lái)的START SLAVE語(yǔ)句,本文主要介紹了MySQL中START REPLICA語(yǔ)句的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07
從零開(kāi)始學(xué)習(xí)SQL查詢(xún)語(yǔ)句執(zhí)行順序
sql語(yǔ)言中的查詢(xún)的執(zhí)行順序,以前不是很了解,最近查閱了相關(guān)資料,在sql語(yǔ)言中,第一個(gè)被處理的字句總是from字句,最后執(zhí)行的limit操作,現(xiàn)在小編來(lái)和大家一起學(xué)習(xí)一下2019-05-05

