zoukankan      html  css  js  c++  java
  • lua-设计与实现-4表

    1 表

    typedef struct Table {
      CommonHeader;
      //表示这个表中提供了哪些元方法 最开始这个flags 的,也就是 ,当查找一次之后,如果该表中存在某个元方法
      lu_byte flags;  /* 1<<p means tagmethod(p) is not present */ 
      lu_byte lsizenode;  /* log2 of size of `node' array *///散列桶数组的大小的 log2(size)
      struct Table *metatable;
      TValue *array;  /* array part */
      Node *node;	//散列桶数组起始位置的指针
      Node *lastfree;  /* any free position is before this position *///散列桶数组最后位置的指针
      GCObject *gclist; //GC相关的链表
      int sizearray;  /* size of `array' array */
    } Table;
    
    • 桶中链地址实现的单链表靠key关联

    确定数组部分大小的标准是什么呢?

    • 希望在调整过后,**数组在每一个2次方位置(1开始)容纳的元素数量都超过该范围的50% ** (认为这个数组范围发挥了最大的效率)

    未解疑问

    • 如何触发rehash。(代码逻辑是mainPositions没有free-nil位置触发,待求证)
    • hash部分的表查询如果实现??

    nums数组解释:

    // 只有利用率超过50%的数组元素会进入数组,否则进去hash
    static int computesizes (int nums[], int *narray) {
      int i;
      int twotoi;  /* 2^i */
      int a = 0;  /* number of elements smaller than 2^i */
      int na = 0;  /* number of elements to go to array part */
      int n = 0;  /* optimal size for array part */
    
      // 这个循环完毕后,最重要的na存放的是数组部分的数据数量,而n是
      // na满足这个条件:在
      for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
        if (nums[i] > 0) {
          // 加上当前数量
          a += nums[i];
          // 如果数量已经超过半数, 那么数组的尺寸可以设置为这个大小
          if (a > twotoi/2) {  /* more than half elements present? */
            n = twotoi;  /* optimal size (till now) */
            // 记录下当前的数组大小
            na = a;  /* all elements smaller than n will go to array part */
          }
        }
        if (a == *narray) break;  /* all elements already counted */
      }
      *narray = n;
      lua_assert(*narray/2 <= na && na <= *narray);
      return na;
    }
    

    举例:
    1,2,5,7,8,9
    数组部分的长度为4时,就不符合大于50%的使用率了。(只有1,2落入数组)

    表查找

    在数组部分查找数据:

    • 查找成功,返回该key 的下一个数据

    否则在散列桶部分查找数据:

    • 查找成功,返回该key 的下一个数据
    • 注意点:
      1,key为1,1.0这两种情况,如何确保算出的hash值一样。答:底层都是用double来表示number。

    2 扩展笔记

    2.1 表"#"特性总结

    • 对数组table,#取长度,底层直接获取(此时的前提是hash部分的头部node为nil),并不是遍历 (时间复杂度O(1))--luaH_getn
    • 对混合型table,#取长度,结果不可靠。 并不是返回前面数组的长度(这是误解,而是根据元素情况不定,可能会使用二分查找遍历或者其他--具体不纠缠)
      Lua源码阅读笔记 - table的长度

    总结:

    数组在每一个2次方位置(1开始)容纳的元素数量都超过该范围的50%

    表的hash部分和C#的Dictionary原理大同小异

    对数组table,#取长度,底层直接获取 -时间复杂度O(1)

    对混合型table,#取长度,结果不可靠。

  • 相关阅读:
    [WPF]搜索列表项的四种实现方案点评
    一个生成均匀分布随机数的问题
    制作NSIS命令行窗口输出插件
    公司的Principle给出的高性能数据库设计,总觉得别扭
    用WordPress一步步建立自己的博客站点
    译作要严格尊重原著吗?——读〈Windows核心编程〉小感
    这么好的书怎么全国都缺货?
    【C语言】用c语言实现简单的五子棋
    【C语言】游戏菜单界面设计 与 游戏整合
    【C语言】基于五子棋框架上的 象棋 小游戏
  • 原文地址:https://www.cnblogs.com/Jaysonhome/p/13420211.html
Copyright © 2011-2022 走看看