Conversation
dev/epaxos_exec.md
Outdated
|
|
||
| 实际上执行的过程就是有向图强连通分量的`Tarjan`算法 | ||
|
|
||
| - `Tarjan`需要用到两个数组,`DFN[u]`为节点u搜索的次序编号,`LOW(u)`为u或u的子树能够追溯到的最早的栈中节点的次序号 |
dev/epaxos_exec.md
Outdated
| ----------- | ||
| ``` | ||
|
|
||
| - 找到一个`DFN[idx]=LOW[idx]`,也就是强连通分量的根,这里就是`instance1`,栈里面的元素集合就是一个强连通分量,这里是 |
There was a problem hiding this comment.
1个小建议, 文档和代码一样, 以容易读懂为最主要目的, instancei如果都换成insi 或直接用数字i 表示每个instance, 更好看1点.
dev/epaxos_exec.md
Outdated
| - 找到一个`DFN[idx]=LOW[idx]`,也就是强连通分量的根,这里就是`instance1`,栈里面的元素集合就是一个强连通分量,这里是 | ||
| `instance1 instance2 instance3 instance4` | ||
|
|
||
| - 每个`instance`有一个`seq`,通过它对强连通分量里面的`instance`进行排序,按照这个顺序去执行这个`instance` |
dev/epaxos_exec.md
Outdated
|
|
||
| - 比如三个`Replica`, 每个`instance`定义一个数组`Deps[3]` | ||
|
|
||
| - `Dep[0]`表示依赖`Replica 0`上的的`instance` |
dev/epaxos_exec.md
Outdated
| - 找到一个`DFN[idx]=LOW[idx]`,也就是强连通分量的根,这里就是`instance1`,栈里面的元素集合就是一个强连通分量,这里是 | ||
| `instance1 instance2 instance3 instance4` |
There was a problem hiding this comment.
这个表示1 2 3 4是一个强连通分量,就是相互依赖。这个不是顺序,找到这个分量后,还需要通过Seq进行排序,排序后的顺序就是执行的顺序
There was a problem hiding this comment.
文博的问题是这样的: 不需要一定是1234,这里只是假设一个遍历得到了1234这样的结果.
There was a problem hiding this comment.
哦哦。dfs遍历也可以从2开始,或者3先遍历4。都可以,到时候得到的强连通分量还是1234,顺序可能不一样。
| } | ||
| ``` | ||
|
|
||
| - `Deps`:表示当前`instance`所依赖的其它`Replica`上的`instance id` |
There was a problem hiding this comment.
deps为啥要包括自己呢? 是论文里约定吗? 我不太记得见到这个了.
感觉R1上的inst[j] 依赖 R1上的inst[j]有点奇怪啊. 正常创建这个inst的时候, 应该是inst[j] 依赖inst[j-1].
There was a problem hiding this comment.
还是说也包含自己的是指包含replica不是instance...
There was a problem hiding this comment.
func (r *Replica) updateAttributes(cmds []state.Command, seq int32, deps [DS]int32, replica int32, instance int32) (int32, [DS]int32, bool) {
changed := false
for q := 0; q < r.N; q++ {
if r.Id != replica && int32(q) == replica {
continue
}
for i := 0; i < len(cmds); i++ {
if d, present := (r.conflicts[q])[cmds[i].K]; present {
if d > deps[q] {
deps[q] = d
if seq <= r.InstanceSpace[q][d].Seq {
seq = r.InstanceSpace[q][d].Seq + 1
}
changed = true
break
}
}
}
}
for i := 0; i < len(cmds); i++ {
if s, present := r.maxSeqPerKey[cmds[i].K]; present {
if seq <= s {
changed = true
seq = s + 1
}
}
}
return seq, deps, changed
}
看实现是依赖当前Replica中最大的那个包含相同key的那个instanceid,并不一定是inst[j-1],key有交集的最大的那个,可能是inst[j-5],不会是它自己
|
|
||
| ```go | ||
| type Instance struct { | ||
| Deps [ReplicaCount]int32 |
There was a problem hiding this comment.
能保证只依赖一个副本上的一个instance吗?
例如:一个read操作可能依赖于另外一个read和write操作
There was a problem hiding this comment.
你看下最下面的说明,“其它实现细节”,我理解是保存了当前副本最大的那个。执行的时候是需要执行小于等于这个id的所有instance
No description provided.