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.

90 lines
2.3 KiB

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