Skip to content

Commit cd1be5a

Browse files
author
DreamAndDead
committed
a little fin about table
1 parent 0d0d75a commit cd1be5a

File tree

2 files changed

+60
-8
lines changed

2 files changed

+60
-8
lines changed

notes/compiler.org

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
* compiler
1+
#+SETUPFILE: setup.org
2+
3+
* TODO compiler
24

35
类比
46
- opcode -> 机器码
@@ -10,7 +12,6 @@
1012

1113
传统是 source -> token -> ast -> ir -> ... -> bytecode
1214

13-
1415
lua 为了效率,直接从 source -> token -> bytecode
1516
相应代码不是那么容易阅读
1617
需要一些编译原理的了解

notes/table.org

+57-6
Original file line numberDiff line numberDiff line change
@@ -298,14 +298,29 @@ TODO 当 next 返回 0 时,意味着结束,上层一定进行了封装,以
298298
这里直接进行了栈操作,参考 c api
299299

300300
*** TODO rehash
301+
:LOGBOOK:
302+
- Note taken on [2020-12-03 四 17:49] \\
303+
TODO resize 操作
304+
- Note taken on [2020-12-03 四 17:46] \\
305+
TODO 理解 computesizes
306+
:END:
307+
308+
在 newkey 进行插入的时候,如果发生了空间不足
309+
就会引发 rehash 操作
301310

302-
rehash -> resize
311+
因为不同于 hash bucket,允许碰撞插入
303312

304-
- 先进行 size 计算,多少用于 array,多少用于 hash
305-
- 巧妙,使用 log pow 来统计
313+
table 是数组链表的形式,没有空间就没办法了,只能进行扩展。
306314

307315

308-
computesizes 中
316+
入口是 rehash 方法
317+
- 先进行 array 部分的统计
318+
这里的统计很巧妙,使用 log2 数组进行统计,a[i] 表示数组索引在 2^(i-1) - 2^i 的数量
319+
- 先统计 array part 的数量
320+
- 再统计 dict part 的数量
321+
- 不要遗漏最新要添加的值(没有判断去重?和调用 rehash 的时机有关,在 newkey 的时候,必定是不会重复的)
322+
323+
computesizes,计算新的 array part 的大小,需要一些理解
309324

310325
twotoi/2 < *narray 的条件,是因为如果不符合,则 twotoi 一定不符合
311326
因为其中所有元素小于 size 的一半,一定不符合 array size 的选择
@@ -325,13 +340,46 @@ a 统计的是 < 2^i 的个数 == twotoi
325340

326341
不符合查找条件
327342

343+
344+
得到大小之后,进行 resize 操作
345+
346+
347+
328348
*** TODO len
329349

330-
getn
350+
如何确定 table 的长度?
351+
352+
长度是针对 array 的含义而言的
331353

332-
unbound_search
354+
getn,含义针对于数组,因为并没有对 dict 进行搜索,只针对整数索引
355+
- 先取得 sizearray 的大小
356+
- 如果最后的值是 nil,就要在数组中搜索出一个边界,使用二分法,找到 i j
357+
i 不是 nil 而 j 是 nil
358+
i 就是所谓的长度
359+
- 若数组是满的
360+
- 没有 dict 部分,直接返回
361+
- 有 dict 部分,则继续搜索,因为可能有部分整数值,在 dict 部分存储
362+
- 先 2 倍进行扩张
363+
- 如果超过最值,bad purpose?
364+
- 在 i 和 j (2 * i) 中进行 2 分,找到一个边界值
333365

334366

367+
368+
369+
#+begin_src lua
370+
> t = {1,2,3,4,5,6}
371+
> print(#t)
372+
6
373+
> t[3] = nil
374+
> print(#t)
375+
6
376+
> t[6] = nil
377+
> print(#t)
378+
2
379+
#+end_src
380+
381+
=#= 本身的行为,在 array 有空洞的时候,对于不理解底层机制的用户,表现出的行为是“不确定的”
382+
335383
** TODO metatable
336384

337385
tagmethod cache
@@ -343,3 +391,6 @@ tagmethod cache
343391
new/free
344392

345393
get/set num/str
394+
395+
考虑将 rehash 的部分放到这里,非重点
396+

0 commit comments

Comments
 (0)