面向数据编程 Data-Oriented Programming [18]

具有不可变数据的状态管理

4.1 介绍

  到目前为止,我们已经看到DO是如何处理查询系统信息的请求的,通过通用函数访问系统数据,以哈希图的形式表示。
  在本章和下一章中,我们将说明如何处理突变,即更改系统状态的请求。我们不是就地更新状态,而是维护系统数据的多个版本。在特定时间点,系统状态指的是系统数据的特定版本。
  维护多个版本的系统数据要求数据是不可变的。这在计算和内存方面都是有效的,这是通过一种称为结构共享的技术来实现的,在这种技术中,两个版本之间共享的部分数据是共享的,而不是被复制的。

  在DO中,突变被分成两个不同的阶段:

  1. 在计算阶段,我们计算下一个版本的系统数据。
  2. 在提交阶段,我们向前移动系统状态,以便它引用由计算阶段计算的系统数据的版本。

  计算和提交阶段之间的这种区别允许我们将系统中有状态的部分减少到最低限度。只有提交阶段的代码是有状态的,而由泛型函数组成的突变无状态计算阶段的代码类似于查询的代码。
  提交阶段的实现对所有突变都是通用的。因此,在提交阶段中,我们能够确保状态始终引用系统数据的有效版本。
  这种状态管理方法的另一个好处是,我们可以跟踪系统数据以前版本的历史记录。如果需要,可以直接将系统恢复到以前的状态。

表4.1突变的两个阶段

阶段责任状态实现
计算计算系统数据的下一个版本无状态具体的
提交向前移动系统状态有状态普通的

  在本章中,我们假设在我们的系统中没有并发突变。在下一章中,我们将处理并发控制。

4.2 系统数据的多个版本

  在喝咖啡的时候,你和乔在街区里散步,这次讨论的话题是版本控制系统。您将讨论git如何跟踪整个提交历史,以及将代码恢复到上一次提交有多容易、多快。您还将讨论允许在提交代码之前验证代码的提交挂钩。

乔:到目前为止,我们已经了解了如何在DO中管理从系统检索信息的查询。现在我将向你们展示我们是如何处理突变的。所谓突变,我指的是改变系统状态的操作。

NOTE 突变是一种改变系统状态的操作。

你:DO中的查询和突变有根本区别吗?毕竟,系统的整个状态被表示为散列映射。我可以很容易地编写代码来修改部分hash map。它将类似于从hash map中检索信息的代码。

乔:你可以就地对数据进行变异,但要确保变异的代码不会使系统进入无效的日期,这将是一件具有挑战性的事情。此外,您还会丢失系统状态的以前版本的跟踪信息。

你:我明白了。那么,你是如何处理DO中的突变的呢?

乔:我们采用多版本状态方法,类似于Git这样的版本控制。我们管理不同版本的系统数据。在特定时间点,系统状态指的是系统数据的版本。在执行突变之后,我们向前移动引用。

你:我很困惑:系统状态是可变的还是不可变的?

乔:数据是不可变的,但是状态引用是可变的。

TIP 数据是不可变的,但状态引用是可变的。

图4.1 执行突变B后,系统状态为数据V12。在执行突变C之后,系统状态参照数据V13。

 

你:这是不是意味着在突变的代码运行之前,我们会复制一份系统数据?

乔:没有。这将是非常低效的,因为我们将不得不对数据进行深度复制。

你:那它是怎么工作的呢?

乔:它的工作原理是使用一种称为结构共享的技术,在这种技术中,状态的后续版本之间的大部分数据都是共享的,而不是被复制。该技术允许在内存和计算方面高效地创建系统数据的新版本。

你:我很感兴趣。

TIP 通过结构共享,它可以高效的(在内存和计算方面)创建新版本的数据。

乔:稍后我会详细地向你解释结构共享是如何工作的。

  再看一下图4.1中的图表,它说明了系统状态如何引用系统数据的一个版本,然后一个问题突然出现在您的脑海中。

您:是否保留了以前版本的系统数据?

乔:在一个简单的应用程序中,垃圾收集器会自动删除以前的版本。但在某些情况下,我们会保留对以前版本数据的历史引用。

你:什么样的情况?

乔:例如,我们可以在我们的系统中允许时间旅行。就像在git中一样,我们可以非常容易地将系统移回以前的状态版本。

你:现在,我明白你的意思了:数据是不变的,但是状态引用是可变的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值