Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 同步两个有序列表_Algorithm_Data Structures_Synchronization_Linked List_Html Lists - Fatal编程技术网

Algorithm 同步两个有序列表

Algorithm 同步两个有序列表,algorithm,data-structures,synchronization,linked-list,html-lists,Algorithm,Data Structures,Synchronization,Linked List,Html Lists,我们有两个离线系统,通常无法相互通信。两个系统都维护相同的有序项目列表。他们很少能够相互通信以同步列表 项目用修改时间戳标记以检测编辑。项目由UUID标识,以避免插入新项目时发生冲突(与使用自动递增整数相反)。同步时,检测到新UUID并将其复制到其他系统。删除也同样如此 上面的数据结构对于无序列表来说很好,但是我们如何处理排序呢?如果我们添加了一个整数“rank”,则在插入一个新项时需要重新编号(因此,由于只有1次插入,因此需要同步所有后续项)。或者,我们可以使用分数等级(使用前一项和后一项的等

我们有两个离线系统,通常无法相互通信。两个系统都维护相同的有序项目列表。他们很少能够相互通信以同步列表

项目用修改时间戳标记以检测编辑。项目由UUID标识,以避免插入新项目时发生冲突(与使用自动递增整数相反)。同步时,检测到新UUID并将其复制到其他系统。删除也同样如此

上面的数据结构对于无序列表来说很好,但是我们如何处理排序呢?如果我们添加了一个整数“rank”,则在插入一个新项时需要重新编号(因此,由于只有1次插入,因此需要同步所有后续项)。或者,我们可以使用分数等级(使用前一项和后一项的等级平均值),但这似乎不是一个可靠的解决方案,因为当插入许多新项时,它会很快遇到精度问题

我们还考虑将其实现为一个双链接列表,其中每个项都包含其前一项和后续项的UUID。但是,这仍然需要在插入1个新项目时同步3个项目(或在删除1个项目时同步其余2个项目)

我们最好使用数据结构或算法,其中只需要同步新插入的项。是否存在这样的数据结构


编辑:我们需要能够处理移动一个现有的项目到不同的位置太

您可以为每个项目添加两个字段-“创建时间戳”和“插入之后”(包含插入新项目之后的项目id)。同步列表后,发送所有新项目。这些信息足以让您在另一边构建列表

接收到新添加的项目列表后,执行以下操作(在接收端):按创建时间戳排序,然后逐个进行排序,并使用“插入后”字段将新项目添加到适当的位置

如果一个项目A被添加,然后B在A之后添加,然后A被删除,您可能会遇到麻烦。如果可能发生这种情况,您还需要同步(基本上同步自上次同步以来列表上发生的操作,而不仅仅是当前列表的内容)。它基本上是一种日志传送形式。

您可以看看“镜头”,这是一种双向编程概念。
例如,我的“匹配镜头”解决了您的问题,如中所述。

我认为这里合适的数据结构是。为了维护统计树,您还需要维护子树的大小以及其他数据,大小字段有助于根据需要轻松查找元素。所有操作,如排名、删除、更改位置、插入都是
O(logn)

我认为您可以在这里尝试某种事务性方法。例如,您不实际删除项目,而是将其标记为删除,并仅在同步期间提交更改。我不确定应该选择哪种数据类型,这取决于您希望哪种操作更有效率(插入、删除、搜索或迭代)

让我们在两个系统上都有以下初始状态:

|1|   |2|
---   ---
|A|   |A|
|B|   |B|
|C|   |C|
|D|   |D|
|1         |   |2           |
------------   --------------
|A         |   |A           |
|B[deleted]|   |B           |
|C         |   |BC[inserted]|
|D         |   |C           |
               |D           |
之后,第一个系统将元素
A
标记为删除,第二个系统在
B
C
之间插入元素
BC

|1|   |2|
---   ---
|A|   |A|
|B|   |B|
|C|   |C|
|D|   |D|
|1         |   |2           |
------------   --------------
|A         |   |A           |
|B[deleted]|   |B           |
|C         |   |BC[inserted]|
|D         |   |C           |
               |D           |
两个系统在考虑本地变化的情况下继续处理,系统1忽略元素
B
,系统2将元素
BC
视为正常元素

同步发生时:

|1|   |2|
---   ---
|A|   |A|
|B|   |B|
|C|   |C|
|D|   |D|
|1         |   |2           |
------------   --------------
|A         |   |A           |
|B[deleted]|   |B           |
|C         |   |BC[inserted]|
|D         |   |C           |
               |D           |
据我所知,每个系统都从其他系统接收列表快照,并且两个系统都冻结处理,直到同步完成

因此,每个系统依次迭代接收到的快照和本地列表,并在“提交事务”之后将更改写入本地列表(根据修改后的时间戳解决可能的冲突),最终应用所有本地更改并擦除有关更改的信息。 例如,对于系统1:

|1 pre-sync|             |2-SNAPSHOT  |   |1 result|
------------             --------------   ----------
|A         | <the same>  |A           |   |A       |
|B[deleted]| <delete B>  |B           |
             <insert BC> |BC[inserted]|   |BC      |
|C         | <same>      |C           |   |C       |
|D         | <same>      |D           |   |D       |
| 1预同步| 2快照| 1结果|
------------             --------------   ----------
|A | | A | | A|
|B[删除]| | B|
|BC[插入]| | BC|
|C | | C | | C|
|D | | D | | D|
系统唤醒并继续处理

项目按插入顺序排序,移动可以实现同时删除和插入。此外,我认为可以不传输整个列表,而只传输实际修改的项目列表。

我认为,大体上,可能与您在这里描述的问题有关。例如,考虑实时协同文本编辑的问题。p> 我们基本上有一个需要保持同步的项目(单词)排序列表,可以在列表中随机添加/修改/删除。我看到的唯一主要区别是列表修改的周期性。(你说这种情况不经常发生)

运营转型确实在该领域得到了很好的研究。我能找到一些指点和介绍。此外,尽管Google Wave存在诸多问题,但他们实际上在运营转型领域取得了重大进展。检查。关于这个问题,有相当多的文献可供查阅。看看这个,看看周围

另一个让我印象深刻的相似之处是文本编辑器中使用的数据结构。 因此,如果您有一个操作日志,比如说,“删除索引5”,“将索引6修改为ABC”,“插入索引8”,那么您现在可能需要做的是将更改日志从系统a传输到系统B,然后在另一个系统上按顺序重建操作