2019-05-22 13:41:20 +08:00
|
|
|
package erasure_coding
|
|
|
|
|
|
|
|
import (
|
2019-05-25 04:28:44 +08:00
|
|
|
"math"
|
|
|
|
"sort"
|
2019-05-22 13:41:20 +08:00
|
|
|
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/storage/needle"
|
2019-05-28 02:59:03 +08:00
|
|
|
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
2019-05-22 13:41:20 +08:00
|
|
|
)
|
|
|
|
|
2019-05-28 12:40:51 +08:00
|
|
|
type EcVolume struct {
|
|
|
|
Shards []*EcVolumeShard
|
|
|
|
}
|
2019-05-22 13:41:20 +08:00
|
|
|
|
2019-05-28 12:40:51 +08:00
|
|
|
func (ev *EcVolume) AddEcVolumeShard(ecVolumeShard *EcVolumeShard) bool {
|
|
|
|
for _, s := range ev.Shards {
|
2019-05-22 13:41:20 +08:00
|
|
|
if s.ShardId == ecVolumeShard.ShardId {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
2019-05-28 12:40:51 +08:00
|
|
|
ev.Shards = append(ev.Shards, ecVolumeShard)
|
|
|
|
sort.Slice(ev, func(i, j int) bool {
|
|
|
|
return ev.Shards[i].VolumeId < ev.Shards[j].VolumeId ||
|
|
|
|
ev.Shards[i].VolumeId == ev.Shards[j].VolumeId && ev.Shards[i].ShardId < ev.Shards[j].ShardId
|
2019-05-25 04:28:44 +08:00
|
|
|
})
|
2019-05-22 13:41:20 +08:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-05-28 12:40:51 +08:00
|
|
|
func (ev *EcVolume) DeleteEcVolumeShard(shardId ShardId) bool {
|
2019-05-22 13:41:20 +08:00
|
|
|
foundPosition := -1
|
2019-05-28 12:40:51 +08:00
|
|
|
for i, s := range ev.Shards {
|
|
|
|
if s.ShardId == shardId {
|
2019-05-22 13:41:20 +08:00
|
|
|
foundPosition = i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if foundPosition < 0 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-05-28 12:40:51 +08:00
|
|
|
ev.Shards = append(ev.Shards[:foundPosition], ev.Shards[foundPosition+1:]...)
|
2019-05-22 13:41:20 +08:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-05-28 12:40:51 +08:00
|
|
|
func (ev *EcVolume) FindEcVolumeShard(shardId ShardId) (ecVolumeShard *EcVolumeShard, found bool) {
|
|
|
|
for _, s := range ev.Shards {
|
2019-05-27 16:29:46 +08:00
|
|
|
if s.ShardId == shardId {
|
|
|
|
return s, true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
2019-05-28 12:40:51 +08:00
|
|
|
func (ev *EcVolume) Close() {
|
|
|
|
for _, s := range ev.Shards {
|
2019-05-22 13:41:20 +08:00
|
|
|
s.Close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-28 12:40:51 +08:00
|
|
|
func (ev *EcVolume) ToVolumeEcShardInformationMessage() (messages []*master_pb.VolumeEcShardInformationMessage) {
|
2019-05-25 04:28:44 +08:00
|
|
|
prevVolumeId := needle.VolumeId(math.MaxUint32)
|
|
|
|
var m *master_pb.VolumeEcShardInformationMessage
|
2019-05-28 12:40:51 +08:00
|
|
|
for _, s := range ev.Shards {
|
2019-05-25 04:28:44 +08:00
|
|
|
if s.VolumeId != prevVolumeId {
|
|
|
|
m = &master_pb.VolumeEcShardInformationMessage{
|
|
|
|
Id: uint32(s.VolumeId),
|
|
|
|
Collection: s.Collection,
|
|
|
|
}
|
|
|
|
messages = append(messages, m)
|
2019-05-22 13:41:20 +08:00
|
|
|
}
|
2019-05-25 04:28:44 +08:00
|
|
|
prevVolumeId = s.VolumeId
|
|
|
|
m.EcIndexBits = uint32(ShardBits(m.EcIndexBits).AddShardId(s.ShardId))
|
2019-05-22 13:41:20 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-05-28 12:40:51 +08:00
|
|
|
func (ev *EcVolume) LocateEcShardNeedle(n *needle.Needle) (offset types.Offset, size uint32, intervals []Interval, err error) {
|
2019-05-22 13:41:20 +08:00
|
|
|
|
2019-05-28 12:40:51 +08:00
|
|
|
shard := ev.Shards[0]
|
2019-05-27 16:29:46 +08:00
|
|
|
// find the needle from ecx file
|
2019-05-28 02:59:03 +08:00
|
|
|
offset, size, err = shard.findNeedleFromEcx(n.Id)
|
2019-05-27 16:29:46 +08:00
|
|
|
if err != nil {
|
2019-05-28 02:59:03 +08:00
|
|
|
return types.Offset{}, 0, nil, err
|
2019-05-22 13:41:20 +08:00
|
|
|
}
|
|
|
|
|
2019-05-27 16:29:46 +08:00
|
|
|
// calculate the locations in the ec shards
|
2019-05-28 02:59:03 +08:00
|
|
|
intervals = LocateData(ErasureCodingLargeBlockSize, ErasureCodingSmallBlockSize, shard.ecxFileSize, offset.ToAcutalOffset(), size)
|
2019-05-27 16:29:46 +08:00
|
|
|
|
2019-05-28 02:59:03 +08:00
|
|
|
return
|
2019-05-22 13:41:20 +08:00
|
|
|
}
|