package erasure_coding import ( "math" "sort" "github.com/chrislusf/seaweedfs/weed/pb/master_pb" "github.com/chrislusf/seaweedfs/weed/storage/needle" "github.com/chrislusf/seaweedfs/weed/storage/types" ) type EcVolumeShards []*EcVolumeShard func (shards *EcVolumeShards) AddEcVolumeShard(ecVolumeShard *EcVolumeShard) bool { for _, s := range *shards { if s.ShardId == ecVolumeShard.ShardId { return false } } *shards = append(*shards, ecVolumeShard) sort.Slice(shards, func(i, j int) bool { return (*shards)[i].VolumeId < (*shards)[j].VolumeId || (*shards)[i].VolumeId == (*shards)[j].VolumeId && (*shards)[i].ShardId < (*shards)[j].ShardId }) return true } func (shards *EcVolumeShards) DeleteEcVolumeShard(ecVolumeShard *EcVolumeShard) bool { foundPosition := -1 for i, s := range *shards { if s.ShardId == ecVolumeShard.ShardId { foundPosition = i } } if foundPosition < 0 { return false } *shards = append((*shards)[:foundPosition], (*shards)[foundPosition+1:]...) return true } func (shards *EcVolumeShards) FindEcVolumeShard(shardId ShardId) (ecVolumeShard *EcVolumeShard, found bool) { for _, s := range *shards { if s.ShardId == shardId { return s, true } } return nil, false } func (shards *EcVolumeShards) Close() { for _, s := range *shards { s.Close() } } func (shards *EcVolumeShards) ToVolumeEcShardInformationMessage() (messages []*master_pb.VolumeEcShardInformationMessage) { prevVolumeId := needle.VolumeId(math.MaxUint32) var m *master_pb.VolumeEcShardInformationMessage for _, s := range *shards { if s.VolumeId != prevVolumeId { m = &master_pb.VolumeEcShardInformationMessage{ Id: uint32(s.VolumeId), Collection: s.Collection, } messages = append(messages, m) } prevVolumeId = s.VolumeId m.EcIndexBits = uint32(ShardBits(m.EcIndexBits).AddShardId(s.ShardId)) } return } func (shards *EcVolumeShards) LocateEcShardNeedle(n *needle.Needle) (offset types.Offset, size uint32, intervals []Interval, err error) { shard := (*shards)[0] // find the needle from ecx file offset, size, err = shard.findNeedleFromEcx(n.Id) if err != nil { return types.Offset{}, 0, nil, err } // calculate the locations in the ec shards intervals = LocateData(ErasureCodingLargeBlockSize, ErasureCodingSmallBlockSize, shard.ecxFileSize, offset.ToAcutalOffset(), size) return }