瞬表——Ephemeron Table

简介: 瞬表——Ephemeron Table

考虑一种情况

一个具有弱引用键的表中的值又引用了对应的键。


这种情况比看上去的更加常见。一个典型的示例是常量函数工厂。这种工厂的参数是一个对象,返回值是一个被调用时返回传入对象的函数:

function factory (o)
  return (function () return o end)
end


这种工厂是实现记忆的一种很好的手段,可以避免在闭包已经存在时又创建新的闭包。接下来展示一种改进方法:

do
  local mem = {}
  setmetatable(mem, {__mode = "k"})
  function factory (o)
    local res = mem[o]
    if not res then
      res = (function () return o end)
      mem[o] = res
    end
    return res
  end
end  


不过,这里另有玄机。请注意:表 mem 中与一个对象关联的值(常量函数)回指了它自己的键(对象本身)。虽然表中的键是弱引用的,但是表中的值却不是弱引用的。从一个弱引用表的标准理解看,记忆表中没有任何东西会被移除。由于值不是弱引用的,所以对于每一个函数来说都存在一个强引用。每一个函数都指向其对应的对象,因而对于每一个键来说都存在一个强引用。因此,即使有弱引用的键,这些对象也不会被回收。

不过,这种严格的理解不是特别有用。大多数人希望一个表中的值只能通过对应的键来访问。我们可以认为之前的情况是某种环,其中闭包引用了指回闭包(通过记忆表)的对象。


Lua 语言通过瞬表的概念来解决上述问题。在 Lua 语言中,一个具有弱引用键和强引用的值的表是一个瞬表。在一个瞬表中,一个键的可访问性控制着对应值的可访问性。更确切的说,考虑瞬表中的一个元素 (k,v) ,指向 v 的引用知道当存在某些指向k的其他外部引用存在时才是强引用,否则,即使 v (直接或间接地)引用了 k ,垃圾收集器最终会收集 k 并把元素从表中移除。


注意

瞬表是 Lua5.2 中引入的, Lua5.1 依然存在我们描述的问题。

目录
相关文章
|
7月前
|
索引
不推荐SELECT * FROM table原因
根据非索引查询 :B+树的叶子节点放数据表行数据,叶子节点存放主键,如果想获得行数据信息,则需要再跑到主键索引去拿数据,这叫回表,速度慢。但不管是主键还是非主键索引,他们的叶子结点数据都是有序的。比如在主键索引中,这些数据是根据主键id的大小,从小到大,进行排序的。**1.**根据索引查询 :B+树的父节点放索引数据,速度快,叶子(父)节点会存放完整的行数据西信息。
347 0
|
4月前
|
存储 SQL 关系型数据库
CREATE TABLE语句
在MySQL中,使用CREATE TABLE语句来创建表。你需要指定表名和列的定义,包括列名、数据类型以及约束等,结合实际存储和上一课学习的数据类型选取合适的。创建一个book_types表
155 0
|
6月前
|
数据库 OceanBase
使用 `INSERT INTO table_name SELECT * FROM table_name` 这种方式
使用 `INSERT INTO table_name SELECT * FROM table_name` 这种方式
45 1
|
7月前
|
数据库 OceanBase
INSERT INTO table_name SELECT * FROM table_name
INSERT INTO table_name SELECT * FROM table_name
37 1
|
JavaScript 前端开发 数据可视化
vxe-table
vxe-table
585 0
vxe-table
|
SQL 数据库
CREATE TABLE
CREATE TABLE
111 0
|
SQL 数据库
CREATE TABLE 语句
CREATE TABLE 语句
106 1
|
Java 索引
Table(表)
Table(表)
72 0
|
SQL Oracle 关系型数据库
SQL FOREIGN KEY Constraint on CREATE TABLE
SQL FOREIGN KEY Constraint on CREATE TABLE
63 1
ALTER TABLE
本文主要介绍如何对表相关的Sequence类型进行修改。