亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發(fā) > 綜合 > 正文

Lua源碼中字符串類型的實現(xiàn)

2024-07-21 23:04:27
字體:
供稿:網(wǎng)友

 概述

    Lua完全采用8位編碼,Lua字符串中的字符可以具有任何數(shù)值編碼,包括數(shù)值0。也就是說,可以將任意二進制數(shù)據(jù)存儲到一個字符串中。Lua的字符串是不可變的值(immutable values)。如果修改,實質(zhì)上是新建一個字符串。根據(jù)上文《Lua中數(shù)據(jù)類型的源碼實現(xiàn)》中知道,在Lua中,字符串是自動內(nèi)存管理機制所管理的對象,并且由聯(lián)合體TString來實現(xiàn)存儲字符串值的。下面將通過Lua 5.2.1的源碼來看字符串的實現(xiàn)以及總結(jié)了在Lua中使用字符串的注意事項。

    源碼實現(xiàn)

    首先來看字符串對應(yīng)的數(shù)據(jù)結(jié)構(gòu)TString,其源碼如下(lobject.h):

410 /* 411 ** Header for string value; string bytes follow the end of this structure 412 */ 413 typedef union TString { 414  L_Umaxalign dummy; /* ensures maximum alignment for strings */ 415  struct { 416   CommonHeader; 417   lu_byte extra; /* reserved words for short strings; "has hash" for longs */ 418   unsigned int hash; 419   size_t len; /* number of characters in string */ 420  } tsv; 421 } TString; 

對這個聯(lián)合體定義,有幾點值得說明:

    I、聯(lián)合體TString中成員L_Umaxalign dummy是用來保證與最大長度的C類型進行對齊,其定義如下(llimits.h):

48 /* type to ensure maximum alignment */ 49 #if !defined(LUAI_USER_ALIGNMENT_T) 50 #define LUAI_USER_ALIGNMENT_T  union { double u; void *s; long l; } 51 #endif 52    53 typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; 

在其他可會回收的對象(比如table)的實現(xiàn)中,也可看到這個聯(lián)合體成員,這樣做的目的是通過內(nèi)存對齊,加快CPU訪問內(nèi)存的速度。

    II、聯(lián)合體中成員tsv才是真正用來實現(xiàn)字符串的。其中成員CommonHeader用于GC,它會以宏的形式在所有的可回收對象中定義,代碼如下(lobject.h):

74 /* 75 ** Common Header for all collectable objects (in macro form, to be 76 ** included in other objects) 77 */ 78 #define CommonHeader  GCObject *next; lu_byte tt; lu_byte marked 

這個宏對應(yīng)的結(jié)構(gòu)體形式如下(lobject.h):

81 /* 82 ** Common header in struct form 83 */ 84 typedef struct GCheader { 85  CommonHeader; 86 } GCheader; 

結(jié)構(gòu)體GCheader在通用的可回收對象union GCObject的定義中有用到。

 III、lu_byte extra對于短字符串,用來記錄這個字符串是否為保留字,對于長字符串,可以用于惰性求Hash值;unsigned int hash成員是字符串對應(yīng)的Hash值(在后面會具體講Lua是怎么計算字符串的Hash值的);size_t len用來表示字符串的長度。

 IV、上面的結(jié)構(gòu)體只是描述了一個字符串的結(jié)構(gòu),真正的字符串數(shù)據(jù)保存是緊隨在結(jié)構(gòu)體后面保存。

 在Lua5.2.1之前,不區(qū)分字符串長和短的字符串,所有的字符串保存在一個全局的Hash表中,對于Lua虛擬機來說,相同的字符串只有一份數(shù)據(jù),從Lua5.2.1開始,只是把短的字符串字符串(當前定義是長度小于等于40)放在全局Hash表中,而長字符串都是獨立生成,同時在計算Hash值時,引入一個隨機種子,這樣做的目的防止Hash Dos——攻擊者構(gòu)造出非常多相同Hash值的不同字符串,從而降低Lua從外部壓入字符串進入全局的字符串Hash表的效率。下面是Lua5.2.1中,生成一個新字符串的步驟,其相應(yīng)的代碼都在lstring.c中:

 (1)若字符串長度大于LUAI_MAXSHORTLEN(默認值是40),則是長字符串,直接調(diào)用創(chuàng)建字符串接口的函數(shù)createstrobj(當然字符串的長度需要能保存在成員size_t len中,否則直接返回),代碼如下(lstring.c):

 95 /*  96 ** creates a new string object  97 */                                                   98 static TString *createstrobj (lua_State *L, const char *str, size_t l,                 99                int tag, unsigned int h, GCObject **list) {              100  TString *ts;                                            101  size_t totalsize; /* total size of TString object */                       102  totalsize = sizeof(TString) + ((l + 1) * sizeof(char));                      103  ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; 104  ts->tsv.len = l; 105  ts->tsv.hash = h; 106  ts->tsv.extra = 0;                                         107  memcpy(ts+1, str, l*sizeof(char)); 108  ((char *)(ts+1))[l] = '/0'; /* ending 0 */                            109  return ts; 110 }  

可以看到把傳入的字符串具體內(nèi)存放在緊隨結(jié)構(gòu)體TString內(nèi)存后面,并且注意108行,字符串以”/0”結(jié)束與C語言字符串兼容的。

 (2)若字符串是短字符串,首先計算字符串的Hash值,找到對應(yīng)的鏈表(短字符串的全局Hash表,使用的是鏈接法的方法,即把所有沖突的元素放在同一個鏈表中),查找當前要創(chuàng)建的字符串是否已經(jīng)在Hash表中,若已經(jīng)存在,則直接返回這個字符串。否則會調(diào)用函數(shù)newshrstr,而函數(shù)newshrstr會調(diào)用上面的createstrobj函數(shù)創(chuàng)建新字符串,并把新創(chuàng)建的字符串放到Hash表中,代碼如下(lstring.c)):

130 /* 131 ** checks whether short string exists and reuses it or creates a new one 132 */ 133 static TString *internshrstr (lua_State *L, const char *str, size_t l) { 134  GCObject *o; 135  global_State *g = G(L); 136  unsigned int h = luaS_hash(str, l, g->seed); 137  for (o = g->strt.hash[lmod(h, g->strt.size)]; 138    o != NULL; 139    o = gch(o)->next) { 140   TString *ts = rawgco2ts(o); 141   if (h == ts->tsv.hash && 142     ts->tsv.len == l && 143     (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { 144    if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ 145     changewhite(o); /* resurrect it */ 146    return ts; 147   } 148  } 149  return newshrstr(L, str, l, h); /* not found; create a new string */ 150 } 

全局的字符串Hash表是保存在虛擬機全局狀態(tài)成員strt中的(lstate.h):

119  stringtable strt; /* hash table for strings */ 

而類型stringtable是一個結(jié)構(gòu)體,其定義如下(lstate.h):

59 typedef struct stringtable {                                     60  GCObject **hash; 61  lu_int32 nuse; /* number of elements */ 62  int size; 63 } stringtable; 

其中成員GCObject **hash是一個指針數(shù)組,數(shù)組中每個成員實質(zhì)指向TString(注意TString中包括宏CommonHeader,該宏中的next成員可以構(gòu)造出Hash表中開散的鏈表);nuse是數(shù)組hash中已經(jīng)被使用的元素個數(shù);size是當前數(shù)組hash的大小。

在函數(shù)newshrstr插入新的字符串前,都會判斷nuse值是否大于size,若大于,表明Hash表大小不夠需要擴充,則把Hash表的大小擴充到原來的2倍,對應(yīng)的代碼如下(lstring.c):

121  if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)                 122   luaS_resize(L, tb->size*2); /* too crowded */  

在gc的時候,會判斷nuse是否比size/2還?。ㄔ贚ua 5.1中是把nuse與size/4比較),如果是的話就重新resize這個stringtable的大小為原來的一半。對應(yīng)的代碼如下(lgc.c):

783   int hs = g->strt.size / 2; /* half the size of the string table */               784   if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */            785    luaS_resize(L, hs); /* halve its size */ 

對于字符串比較,首先比較類型,若是不同類型字符串,則肯定不相同,然后區(qū)分短字符串和長字符串,對于短字符串,若兩者指針值相等,則相同,否則不相同;對應(yīng)長字符串,則首先比較指針值,若不同,則比較長度值和內(nèi)容逐字符比較。

  總結(jié)

 (1)Lua中的保留字和元方法名都是做為短字符串的,他們在虛擬機啟動的時候就已經(jīng)放入到全局短的字符串Hash表,并且是不回收的。

 (2)查找字符是比較高效的,但是修改或插入字符串都是比較低效的,這里面除了計算外,至少要把外面的字符串拷貝到虛擬機中。

 (3)對應(yīng)長字符串的Hash值,Lua是不會考察每個字符的,因而能避免快速計算長字符串的散列值,其相應(yīng)的代碼如下(lstring.c):

51 unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {               52  unsigned int h = seed ^ l;                                     53  size_t l1;                                             54  size_t step = (l >> LUAI_HASHLIMIT) + 1;                              55  for (l1 = l; l1 >= step; l1 -= step)                                56   h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1]));                       57  return h;                                             58 }  21 /*                                                 22 ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to                 23 ** compute its hash                                         24 */                                                  25 #if !defined(LUAI_HASHLIMIT)                                     26 #define LUAI_HASHLIMIT   5                                    27 #endif 

 (4)當有多個字符串連接時,不應(yīng)該直接用字符串連接運算符”..”,而是用table.concat操作或者是string.format來加快字符串連接的操作。

 (5)Lua中字符串Hash算法用的是JSHash,關(guān)于字符串的各種Hash函數(shù),網(wǎng)絡(luò)有篇文章對它進行了總結(jié):https://www.byvoid.com/blog/string-hash-compare

以上所述誰就是本文的全部內(nèi)容了,希望能對大家學習lua有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
国产a级免费视频| 涩多多在线观看| 成人激情免费在线| 国产黄色一级大片| 奇米777影视成人四色| а√天堂www在线а√天堂视频| 91精品国产综合久久国产大片| 一区二区三区麻豆| 国产精品久久影视| 久久夜色精品国产欧美乱极品| 日韩人妻一区二区三区蜜桃视频| 99re6热在线精品视频播放速度| 国产精品视频一区国模私拍| 懂色av一区二区在线播放| 粉嫩绯色av一区二区在线观看| 超碰99在线| 一本久道高清无码视频| 国产全是老熟女太爽了| 在线h片观看| 亚洲欧洲日夜超级视频| 欧美日韩精品免费观看视欧美高清免费大片| 九九久久综合网站| 日韩av一二三区| 懂色aⅴ精品一区二区三区蜜月| 国产精品亚洲电影久久成人影院| 欧美激情视频网站| 国产在线98福利播放视频| 青青草原一区二区| 国产精品12| 欧美欧美黄在线二区| 99久免费精品视频在线观看| 三妻四妾完整版在线观看电视剧| 久久99国产精品一区| 国外成人免费在线播放| 日韩精品欧美大片| 蜜臀av午夜精品久久| freemovies性欧美| 欧美日韩精品区| 色婷婷综合久久久中文一区二区| 日韩精品在线一区二区| 男人的天堂va| 石原莉奈一区二区三区高清在线| 亚洲午夜久久久久中文字幕久| 日本成人超碰在线观看| 中文字幕天堂av| 91欧美日韩麻豆精品| 91精品免费在线观看| 欧美有码在线视频| 开心激情综合| 亚洲特级毛片| 亚洲图片欧美一区| 亚洲欧美在线观看视频| 黄色免费视频网站| 亚洲午夜剧场| 欧美日本黄色片| 性欧美丰满熟妇xxxx性仙踪林| 亚洲三级理论片| 一级片a一级片| 综合激情在线| 久久精品影视伊人网| 热久久久久久| 国产精品黄色影片导航在线观看| 日韩中文一区二区三区| 蜜桃视频一区二区三区在线观看| 黄色网在线视频| 91高清免费看| japanese国产精品| 国产精品日韩一区二区| 日韩免费在线电影| 2021天天操| 亚洲国产日日夜夜| 成人免费福利视频| 国产午夜精品一区理论片飘花| 日本h视频在线观看| 久艹在线免费观看| 日本一二三区在线观看| av大片在线免费观看| 97超碰国产精品女人人人爽| 国产欧美日本在线| 色中色综合成人| 久久国产精品无码网站| 天堂网在线最新版www中文网| 国产色综合视频| 国产黄色的视频| 在线天堂视频| 天堂社区 天堂综合网 天堂资源最新版| 在线影院福利| 国产免费看av| 日韩欧美在线观看一区二区三区| 四虎影视最新网站入口在线观看| 国产日韩一区二区三区在线| 国产精品videossex撒尿| 欧美99久久| 国产91在线播放精品| 欧美经典三级视频一区二区三区| 亚洲综合自拍网| 亚洲免费福利视频| 日韩毛片在线免费观看| 九七久久人人| 精品国产乱码久久久久久婷婷| 秋霞午夜鲁丝一区二区| 中文字幕在线日韩| 中国av一区| 97人妻一区二区精品视频| 国产私拍福利精品视频二区| 中文字幕在线永久| 激情美女网站| 欧美系列一区| 69堂精品视频在线播放| 国产精品刘玥久久一区| 国产乱码精品一区二区三区四区| chinese少妇国语对白| 精品国产导航| 5月丁香婷婷综合| 91精品国产综合久久国产大片| 亚洲成人在线播放| 亚洲精品视频大全| 福利在线小视频| 国产精品亚洲综合在线观看| 天天干天天干天天干天天干天天干| 美女尤物国产一区| 丁香花在线电影小说观看| 宅男噜噜噜66一区二区66| 亚洲婷婷丁香| 久久爱.com| 国产精品网站在线观看| 日本少妇xxxxx| 亚洲精品美女久久7777777| 亚洲美女视频在线| 欧美高跟鞋交xxxxhd| 一道本一区二区| 91视频观看免费| 黄色视屏在线免费观看| 国产精品久久久久久人| 国产高清999| 性欧美xxxx| 精东粉嫩av免费一区二区三区| 日本中文字幕高清| 影音先锋中文在线播放| 亚洲日本在线视频观看| 99久久久久免费精品国产| 国产黄色av片| 一区二区三区在线观看www| 91九色在线看| 午夜精品久久17c| 久久午夜a级毛片| 成人精品网站在线观看| 久草在线在线| 日韩精品免费一区二区在线观看| 亚洲成人综合网站| 天天操天天摸天天爽| 亚洲图片欧洲图片日韩av| 欧美日韩精品一区二区三区视频播放| 日本色图欧美色图| 黑色丝袜福利片av久久| 亚洲偷熟乱区亚洲香蕉av| 久久丫精品久久丫| 日韩 欧美 精品| 日韩中文字幕精品视频| 欧美少妇性生活视频| 精品视频无码一区二区三区| 一区二区高清在线| 日本中文字幕视频一区| av亚洲男人天堂| 国产aⅴ精品一区二区四区| 亚洲国产91精品在线观看| 国产在视频线精品视频www666| 精品久久一区二区三区| 无码精品国产一区二区三区免费| av久久网站| 自拍偷拍欧美视频| 538prom精品视频线放| 国产男女无套在线播放| bdsmchinese医疗折磨| 最新二区三区av| 最新91在线| 青娱乐国产精品| 青娱乐国产精品视频| 在线电影欧美成精品| 亚洲色成人www永久在线观看| 精品久久国产字幕高潮| 欧美一卡在线观看| 亚洲嫩模一区| av在线官网| 一区二区日韩av| 欧美大尺度做爰床戏| 四虎影院在线播放| 久久蜜臀中文字幕| 欧美日韩电影在线| 天天综合成人网| 亚洲av毛片成人精品| 青青草成人免费视频| 午夜宅男久久久| 少妇精品无码一区二区| 91亚洲国产| 亚洲精品卡一卡二| 北条麻妃在线视频| 狠狠干婷婷色| 国产精品网友自拍| 欧美色婷婷天堂网站| 久操视频免费在线观看| 精品久久免费观看| 成年网站在线播放| 国产3p露脸普通话对白| 欧美精品少妇一区二区三区| 国产精品一区二区三区99| 少妇精品久久久一区二区| 亚洲va久久久噜噜噜久久| 99在线欧洲视频| 成人av电影在线观看| 日韩大陆av| 国产精品久久久久久久久久久久冷| 亚洲成人中文在线| 免费网站观看www在线观| 精品视频第一区| 亚洲精品视频久久| av人人综合网| 欧美性久久久久| 精彩视频一区二区三区| 精品久久久久久电影| 国产成人在线精品| 亚洲av片一区二区三区| 99re热视频这里只精品| 少妇光屁股影院| 午夜激情影院在线观看| av电影在线观看一区二区三区| 欧美精品系列| 毛片av一区二区三区| а√中文在线8| 亚洲自拍小视频| 免费男女羞羞的视频网站中文字幕| 欧洲美女女同性互添| 最近中文字幕大全中文字幕免费| 亚洲av电影一区| 久久精品噜噜噜成人av农村| 亚洲黄色免费网站| 一道本在线免费视频| 精品一区二区精品| 国产欧美自拍视频| 国产日韩欧美在线观看| 欧美日韩喷水| 超碰在线公开免费| 成人短片线上看| 自拍偷拍欧美激情| 亚洲黄色影院| 精品少妇久久久久久888优播| 无码一区二区三区在线观看| 911精品产国品一二三产区| 91l九色lporny| 中文字幕有码热在线视频| 中文有码在线观看| 午夜精品短视频| 9自拍视频在线观看| 真实乱视频国产免费观看| 日韩av免费在线看| 91麻豆精品国产91久久久更新资源速度超快| 日本在线小视频| 亚洲奶大毛多的老太婆| 亚洲精品国产偷自在线观看| 久久精品播放| 成人三级视频在线观看一区二区| 无国产精品白浆是免费| 天堂在线观看av| 国产喷水福利在线视频| 国产成人综合精品三级| 婷婷综合成人| 51久久夜色精品国产麻豆| 国产精品国产三级国产三级人妇| 亚洲福利视频久久| 欧美狂猛xxxxx乱大交3| 日本福利一区二区| 欧美猛男超大videosgay| 欧美在线观看视频一区| 国产精品xvideos88| 男女做暖暖视频| 伊人av免费在线观看| 欧美激情无毛| 国产主播第一页| 午夜精品三级视频福利| 国产盗摄视频在线观看| 欧美成人免费小视频| 日韩精品一区二区三区国语自制| 狠狠精品干练久久久无码中文字幕| 亚洲av激情无码专区在线播放| 国产精品系列在线观看| 午夜电影网亚洲视频| 亚洲国产综合人成综合网站| 99久久精品国产麻豆演员表| 黄色毛片av| 日韩一级中文字幕| 高潮白浆女日韩av免费看| 日本道精品一区二区三区| 毛片毛片毛片| 精品久久久久久亚洲综合网| 亚洲免费在线观看视频| 婷婷激情五月综合| 亚洲aⅴ怡春院| 97精品久久久中文字幕免费| 一本一道综合狠狠老| 一二三四日本在线| 免费在线一区二区| 欧美日韩在线看| chinesespank调教| 欧美成人一区二区| 午夜激情一区二区| 美国av一区二区| 成人一区不卡| 蜜桃麻豆影像在线观看| 色综合久久av| 懂色av一区二区| avtt天堂资源网| 蜜臀久久久久久999| 看电视剧不卡顿的网站| 欧美中文在线字幕| 欧美图片第一页| 91精品国产自产观看在线| 亚洲成人精品av| 国产丰满果冻videossex| 国产又粗又黄又猛| 免费一区二区三区在线观看| 性色av一区二区怡红| 亚洲熟妇av乱码在线观看| 欧美最猛性xxxxx亚洲精品| 久久99久国产精品黄毛片色诱| 日韩免费视频一区二区| 中文字幕剧情在线观看一区| 日本成人超碰在线观看| av免费在线一区二区三区|