/
erasure-layout.go
121 lines (113 loc) · 3.42 KB
/
erasure-layout.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package grasure
type Pattern int
const (
Random Pattern = iota
// see http://www.accs.com/p_and_p/RAID/LinuxRAID.html for more infos
LeftSymmetric
LeftAsymmetric
RightSymmetric
RightAsymmetric
)
//Layout determines the block location relative to the nodes, usually stored on name node
type Layout struct {
//Pattern is how blocks are mapped to nodes
pattern Pattern
//distribution maps the shards of each stripe to node
distribution [][]int
//blockToOffset determines the block's offset with repsect to the node
blockToOffset [][]int
}
//NewLayout news a layout for certain patterns
//stripeNum = totalPoolSize // blockSize // stripeLen
//stripeLen = dataShards + parityShards
func NewLayout(pattern Pattern, stripeNum, dataShards, parityShards, nodeNum int) *Layout {
stripeLen := dataShards + parityShards
layout := &Layout{
pattern: pattern,
distribution: make([][]int, stripeNum),
blockToOffset: makeArr2DInt(stripeNum, stripeLen),
}
if pattern == Random {
countSum := make([]int, nodeNum)
for i := 0; i < stripeNum; i++ {
layout.distribution[i] = genRandomArr(nodeNum, 0)[:stripeLen]
for j := 0; j < stripeLen; j++ {
diskId := layout.distribution[i][j]
layout.blockToOffset[i][j] = countSum[diskId]
countSum[diskId]++
}
}
} else if pattern == LeftSymmetric {
countSum := make([]int, nodeNum)
for i := 0; i < stripeNum; i++ {
layout.distribution[i] = make([]int, stripeLen)
for c := 0; c < stripeLen; c++ {
layout.distribution[i][c] = (c + i) % stripeLen
diskId := layout.distribution[i][c]
layout.blockToOffset[i][c] = countSum[diskId]
countSum[diskId]++
}
}
} else if pattern == LeftAsymmetric {
countSum := make([]int, nodeNum)
for i := 0; i < stripeNum; i++ {
layout.distribution[i] = make([]int, stripeLen)
parity := dataShards
for c := 0; c < parityShards; c++ {
j := (dataShards - i%stripeLen + c + stripeLen) % stripeLen
layout.distribution[i][j] = parity
parity++
diskId := layout.distribution[i][j]
layout.blockToOffset[i][j] = countSum[diskId]
countSum[diskId]++
}
data := 0
for c := 0; c < stripeLen; c++ {
if layout.distribution[i][c] == 0 {
layout.distribution[i][c] = data
data++
diskId := layout.distribution[i][c]
layout.blockToOffset[i][c] = countSum[diskId]
countSum[diskId]++
}
}
}
} else if pattern == RightSymmetric {
countSum := make([]int, nodeNum)
for i := 0; i < stripeNum; i++ {
layout.distribution[i] = make([]int, stripeLen)
for c := 0; c < stripeLen; c++ {
j := (parityShards + c + i) % stripeLen
layout.distribution[i][j] = c
diskId := layout.distribution[i][j]
layout.blockToOffset[i][j] = countSum[diskId]
countSum[diskId]++
}
}
} else if pattern == RightAsymmetric {
countSum := make([]int, nodeNum)
for i := 0; i < stripeNum; i++ {
layout.distribution[i] = make([]int, stripeLen)
parity := dataShards
for c := 0; c < parityShards; c++ {
j := (i%stripeLen + c) % stripeLen
layout.distribution[i][j] = parity
parity++
diskId := layout.distribution[i][j]
layout.blockToOffset[i][j] = countSum[diskId]
countSum[diskId]++
}
data := 0
for c := 0; c < stripeLen; c++ {
if layout.distribution[i][c] == 0 {
layout.distribution[i][c] = data
data++
diskId := layout.distribution[i][c]
layout.blockToOffset[i][c] = countSum[diskId]
countSum[diskId]++
}
}
}
}
return layout
}