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.

120 lines
2.9 KiB

  1. package topology
  2. import (
  3. "github.com/chrislusf/seaweedfs/weed/storage/erasure_coding"
  4. "github.com/chrislusf/seaweedfs/weed/storage/needle"
  5. )
  6. func (dn *DataNode) GetEcShards() (ret []*erasure_coding.EcVolumeInfo) {
  7. dn.RLock()
  8. for _, ecVolumeInfo := range dn.ecShards {
  9. ret = append(ret, ecVolumeInfo)
  10. }
  11. dn.RUnlock()
  12. return ret
  13. }
  14. func (dn *DataNode) UpdateEcShards(actualShards []*erasure_coding.EcVolumeInfo) (newShards, deletedShards []*erasure_coding.EcVolumeInfo) {
  15. // prepare the new ec shard map
  16. actualEcShardMap := make(map[needle.VolumeId]*erasure_coding.EcVolumeInfo)
  17. for _, ecShards := range actualShards {
  18. actualEcShardMap[ecShards.VolumeId] = ecShards
  19. }
  20. // found out the newShards and deletedShards
  21. dn.ecShardsLock.RLock()
  22. for vid, ecShards := range dn.ecShards {
  23. if actualEcShards, ok := actualEcShardMap[vid]; !ok {
  24. // dn registered ec shards not found in the new set of ec shards
  25. deletedShards = append(deletedShards, ecShards)
  26. } else {
  27. // found, but maybe the actual shard could be missing
  28. a := actualEcShards.Minus(ecShards)
  29. if a.ShardIdCount() > 0 {
  30. newShards = append(newShards, a)
  31. }
  32. d := ecShards.Minus(actualEcShards)
  33. if d.ShardIdCount() > 0 {
  34. deletedShards = append(deletedShards, d)
  35. }
  36. }
  37. }
  38. for _, ecShards := range actualShards {
  39. if _, found := dn.ecShards[ecShards.VolumeId]; !found {
  40. newShards = append(newShards, ecShards)
  41. }
  42. }
  43. dn.ecShardsLock.RUnlock()
  44. if len(newShards) > 0 || len(deletedShards) > 0 {
  45. // if changed, set to the new ec shard map
  46. dn.ecShardsLock.Lock()
  47. dn.ecShards = actualEcShardMap
  48. dn.ecShardsLock.Unlock()
  49. }
  50. return
  51. }
  52. func (dn *DataNode) DeltaUpdateEcShards(newShards, deletedShards []*erasure_coding.EcVolumeInfo) {
  53. for _, newShard := range newShards {
  54. dn.AddOrUpdateEcShard(newShard)
  55. }
  56. for _, deletedShard := range deletedShards {
  57. dn.DeleteEcShard(deletedShard)
  58. }
  59. }
  60. func (dn *DataNode) AddOrUpdateEcShard(s *erasure_coding.EcVolumeInfo) {
  61. dn.ecShardsLock.Lock()
  62. defer dn.ecShardsLock.Unlock()
  63. if existing, ok := dn.ecShards[s.VolumeId]; !ok {
  64. dn.ecShards[s.VolumeId] = s
  65. } else {
  66. existing.ShardBits = existing.ShardBits.Plus(s.ShardBits)
  67. }
  68. }
  69. func (dn *DataNode) DeleteEcShard(s *erasure_coding.EcVolumeInfo) {
  70. dn.ecShardsLock.Lock()
  71. defer dn.ecShardsLock.Unlock()
  72. if existing, ok := dn.ecShards[s.VolumeId]; ok {
  73. existing.ShardBits = existing.ShardBits.Minus(s.ShardBits)
  74. if existing.ShardBits.ShardIdCount() == 0 {
  75. delete(dn.ecShards, s.VolumeId)
  76. }
  77. }
  78. }
  79. func (dn *DataNode) HasVolumesById(id needle.VolumeId) (hasVolumeId bool) {
  80. // check whether normal volumes has this volume id
  81. dn.RLock()
  82. _, ok := dn.volumes[id]
  83. if ok {
  84. hasVolumeId = true
  85. }
  86. dn.RUnlock()
  87. if hasVolumeId {
  88. return
  89. }
  90. // check whether ec shards has this volume id
  91. dn.ecShardsLock.RLock()
  92. _, ok = dn.ecShards[id]
  93. if ok {
  94. hasVolumeId = true
  95. }
  96. dn.ecShardsLock.RUnlock()
  97. return
  98. }