You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.3 KiB

  1. package erasure_coding
  2. import (
  3. "math"
  4. "sort"
  5. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  6. "github.com/chrislusf/seaweedfs/weed/storage/needle"
  7. "github.com/chrislusf/seaweedfs/weed/storage/types"
  8. )
  9. type EcVolumeShards []*EcVolumeShard
  10. func (shards *EcVolumeShards) AddEcVolumeShard(ecVolumeShard *EcVolumeShard) bool {
  11. for _, s := range *shards {
  12. if s.ShardId == ecVolumeShard.ShardId {
  13. return false
  14. }
  15. }
  16. *shards = append(*shards, ecVolumeShard)
  17. sort.Slice(shards, func(i, j int) bool {
  18. return (*shards)[i].VolumeId < (*shards)[j].VolumeId ||
  19. (*shards)[i].VolumeId == (*shards)[j].VolumeId && (*shards)[i].ShardId < (*shards)[j].ShardId
  20. })
  21. return true
  22. }
  23. func (shards *EcVolumeShards) DeleteEcVolumeShard(ecVolumeShard *EcVolumeShard) bool {
  24. foundPosition := -1
  25. for i, s := range *shards {
  26. if s.ShardId == ecVolumeShard.ShardId {
  27. foundPosition = i
  28. }
  29. }
  30. if foundPosition < 0 {
  31. return false
  32. }
  33. *shards = append((*shards)[:foundPosition], (*shards)[foundPosition+1:]...)
  34. return true
  35. }
  36. func (shards *EcVolumeShards) FindEcVolumeShard(shardId ShardId) (ecVolumeShard *EcVolumeShard, found bool) {
  37. for _, s := range *shards {
  38. if s.ShardId == shardId {
  39. return s, true
  40. }
  41. }
  42. return nil, false
  43. }
  44. func (shards *EcVolumeShards) Close() {
  45. for _, s := range *shards {
  46. s.Close()
  47. }
  48. }
  49. func (shards *EcVolumeShards) ToVolumeEcShardInformationMessage() (messages []*master_pb.VolumeEcShardInformationMessage) {
  50. prevVolumeId := needle.VolumeId(math.MaxUint32)
  51. var m *master_pb.VolumeEcShardInformationMessage
  52. for _, s := range *shards {
  53. if s.VolumeId != prevVolumeId {
  54. m = &master_pb.VolumeEcShardInformationMessage{
  55. Id: uint32(s.VolumeId),
  56. Collection: s.Collection,
  57. }
  58. messages = append(messages, m)
  59. }
  60. prevVolumeId = s.VolumeId
  61. m.EcIndexBits = uint32(ShardBits(m.EcIndexBits).AddShardId(s.ShardId))
  62. }
  63. return
  64. }
  65. func (shards *EcVolumeShards) LocateEcShardNeedle(n *needle.Needle) (offset types.Offset, size uint32, intervals []Interval, err error) {
  66. shard := (*shards)[0]
  67. // find the needle from ecx file
  68. offset, size, err = shard.findNeedleFromEcx(n.Id)
  69. if err != nil {
  70. return types.Offset{}, 0, nil, err
  71. }
  72. // calculate the locations in the ec shards
  73. intervals = LocateData(ErasureCodingLargeBlockSize, ErasureCodingSmallBlockSize, shard.ecxFileSize, offset.ToAcutalOffset(), size)
  74. return
  75. }