其实Zeon的设计目的既不是什么不可变性,也不是什么唯一性透明性通用性,而是一个强迫症(划掉)其实是孤独症者对只存在于自己内心的那个理想世界的建模。(如果不知道的话,我对孤独症者核心特点的理解是「活在自己的世界里」,能够真正理解的只有自己建模出来的虚拟世界。)因此很难说它有什么要满足的「需求」,我只是把脑海中的那个正确的「世界式」描摹出来罢了。至于它能有什么用,还是那句老话,就让时间使之发芽吧。
【为什么不可变性很重要?便利的可追溯、回溯和迁移,透明性,唯一性和准确性】
以下提及所有无符号整数和有符号整数理论最大长度均为128位(在BCBC中以LEB128编码)。
每个Zeon服务端实例管理的数据的总集【?】,我们称之为存储库 (repository / repo)。
从「空间」的角度,Zeon的基本单元是对象 (object)。
每个对象都有其类型,我们称之为对象类型 (object type)。(Zeon中不同的「类型」概念很多,请读者一定要注意区分。)每个Zeon存储库中,对象类型ID(object type id)为无符号整数,随着对象类型在存储库中的增加而自增。
每个对象都有其在对应的对象类型中的ID,我们称之为对象类型内ID (object inner id),为无符号整数,随着对象在指定对象类型中的增加而自增,或者使用范围内随机增加算法(将另外列出)。
对象类型ID和对象类型内ID连接起来的整体,我们称之为对象ID (object id)。
对象自身只是一个对象ID【?】,无法存储任何数据,也无法实现任何功能。对象储存数据是通过向对象附加trait实现的。
每个对象类型需指定至少一个trait作为必需trait集合 (essential traits set),属于该对象类型的所有对象都必须附加这些trait。除元数据类型外,必需trait集合在创建类型之后可以增加或者减少,方式是通过具有系统管理员权限的操作者向该对象类型的元数据对象以及该对象类型的所有对象【一定要是系统管理员提交所有对象的修改么?如果要保证在一个提交内完成的话,一个提交是不是可以有多个操作者?是不是可以有author和committer的区别?】提交migration commit。
必需trait集合中包含操作者及相关权限的trait的对象类型被称为操作者类型 (operator type),属于该对象类型的对象是操作者 (operator)。操作者可以对拥有相应权限的对象进行提交(包括创建新的对象)。
每个存储库中都有一些固定的对象类型,其必需trait集合和作用是确定的,用于储存每个存储库的元数据,这些对象类型被称为元数据类型。元数据类型中包含该存储库中的对象类型
trait是对象存储数据、实现功能的凭依。每个trait中包含若干属性。 【versioning?】
属性在其对应trait中的ID,我们称之为trait属性ID (trait attr id),为无符号整数,按照trait schema中的顺序依次编号。
属性类型 (attr type)根据其每次提交的值与该属性的值的关系分为6种:
值在被第一次提交之后即不能被之后的提交改变的属性被称为常量属性 (const)。
值为最新一次提交的值(即每次提交都会覆盖上次提交的值)的属性被称为变量属性 (mut)。
以下两个属性类型统称为迭代属性 (iter),有按操作者查询值 (query by operator)的功能。
值为每次提交的值的列表的属性被称为迭代列表属性 (iterlist)。iterlist的值包含一个操作者的全部历史提交,按操作者查询值时取到的是按时间排序的值的列表。
值为每个操作者最新一次提交的值的列表的属性被称为迭代集合属性 (iterset)。iterset的值仅包含一个操作者的最新提交,按操作者查询值时取到的是一个最新值。
值为指向另外一个对象的对象id,且被指向的对象也有一个该属性类型的属性指向该对象的对象id,这样的属性被称为成对属性 (pair)。成对属性在提交时,必须在一个提交内同时提交两侧,否则将无法通过检查。
值为每次提交的diff值(diff算法将另外列出)的总和的属性被称为复杂结构属性 (complex)。复杂结构属性实质上是一种高级的变量属性,它可以被用于值为复杂数据类型的情况,这样就不需要每次修改都保存完整的数据,而只需要保存diff值。
属性可以为可默认 (defaultable)。可默认属性可以在对象类型元数据里设置默认值;如果设置了默认值,创建对象时可以不提交该属性;进行非提交查询时,查询到的是默认值。
从「时间」的角度,Zeon的基本单元是提交 (commit)。
提交分为提交头 (commit header)和提交体 (commit body)两部分。
提交头包含提交ID (commit id)、提交签名 (commit signature)、提交附加信息三部分。
以下是提交ID的构成:
时间戳,分两部分:
其一为有符号整数,记录自UTC时间2001年1月1日0时整经过的秒数;
其二为无符号整数,记录自上述秒数后经过的微秒数,值在0-1_000_000之间。
序列码,为无符号整数,根据实现决定,目的是防止多机器接收提交等情况产生碰撞;
操作者的对象ID。
提交附加信息中,可以附加如提交来源IP地址等信息。
提交体是一个键-值对,以下是键的构成:
被操作对象的对象ID;
被操作trait的ID;
被操作属性的trait属性ID。
提交ID和提交体的一个键被称为对应被操作属性值的一个修改指针。
Zeon使用BCBC (Berylsoft Common Binary Codec)作为通用的二进制序列化格式。
BCBC的数据类型如下:
单元/单位类型 (unit),表示一个空的占位符,对于构造有效的迭代属性可能有用。
布尔类型 (bool),有真和假两个值。
无符号和有符号整数类型,有8、16、32、64位,类型名用LLVM表示法表示(如64位无符号整数表示为u64)。
浮点数类型,计算时遵循IEEE754标准,有16、32、64位,类型名用LLVM表示法表示(如32位浮点数表示为f32)。 【实现细节:使用对应位数的无符号整数作为中间表示】
字符串类型 (string),为有效UTF-8字符串。长度允许为0,最大为【】字节。
字节串类型 (bytes),为任意字节串。长度允许为0,最大为【】字节。
可选类型 (option),可能含有一个特定类型的值,也可能不含有值。
列表类型 (list),为特定类型的值的列表。长度允许为0,最大为【】项。 【BCBL要使用的无限列表】
键值对类型 (map),为特定两个类型的值的键-值对。长度允许为0,最大为【】对。
元组类型 (tuple),为有序的特定的多个类型的值的列表。长度允许为0,最大为2^8【?】项。
别名类型 (alias),为另一个【应禁止创建是自己的别名的类型】特定类型的别名。 【可以用validater为其值增加限制】
枚举类型 (enum),为可能为有序的特定的枚举值的类型。枚举值数允许为0,最大为【】种。
可区分联合类型 (union)【?】,为可能为有序的特定的枚举值,每个枚举值中含有一个指定类型的值的类型。枚举值数允许为0,最大为【】种。
结构体类型 (struct),为有序的特定的多个类型的值,每个值在类型定义中有名字的列表。长度允许为0,最大为2^8【?】项。
类型类型 (type),值表示一个类型的类型。
类型ID类型 (type-id),值表示一个类型ID。 【类型ID是否同时作为trait ID?】