Lua源码阅读三——lua字符串缓存

本文深入探讨Lua中的字符串管理,包括字符串缓存和内存分配策略。通过源码分析,阐述了如何创建新的字符串,如何计算字符串的哈希值用于缓存查找,以及当字符串数量过多时如何调整全局字符串表的大小。文章还介绍了luaM_malloc在内存分配中的作用和内存布局。
摘要由CSDN通过智能技术生成

本篇文章,主要探讨一下lua中的字符串缓存管理(涉及到的文件 lstring.c )。

 

在lua的9种数据类型中,字符串是属于可以被GC回收的类型。在lua中,操作字符串实际上是在操作字符串引用,当字符串不在被使用的时候,GC会通过一定算法回收。

 

--lua9种数据类型:

 

字符串分配

--源码:

 

 

ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));

--该行代码申请放置字符串的内存,luaM_malloc是申请内存的一个宏定义,调用上篇文章中提到的luaM_realloc_ 函数来来分配内存,在lua中字符串是用结构

 

表示的,所以申请的内存大小是(l+1)*sizeof(char)+sizeof(TString),内存分布:TString+str+'/0',然后给TString赋值hash code, len,marted,reserved,拷贝字符串。

  tb = &G(L)->strt;
  h = lmod(h, tb->size);
  ts->tsv.next = tb->hash[h];  /* chain new entry */
  tb->hash[h] = obj2gco(ts);
  tb->nuse++;

--接下来,将分配的字符串挂到全局字符串管理对象strt上

 

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

--对字符串大小的扩充

 

字符串缓存

--源码:

 

 

 

  unsigned int h = cast(unsigned int, l);  /* seed */
  size_t step = (l>>5)+1;  /* if string is too long, don't hash all its chars */
  size_t l1;
  for (l1=l; l1>=step; l1-=step)  /* compute hash */
    h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));

---根据字符串长度l和字符串内容str计算字符串hash code,字符串hash code用作该字符串的key,后续用作字符串缓存key,这个算法可以保证key-value一一对应。

 

  for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
       o != NULL;
       o = o->gch.next) {
    TString *ts = rawgco2ts(o);
    if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
      /* string may be dead */
      if (isdead(G(L), o)) changewhite(o);
      return ts;
    }
  }

--在字符串全局管理对象中查找该字符串,如果查到就使用该字符串返回,否则:

return newlstr(L, str, l, h);

申请内存放置字符串。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值