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.

130 lines
3.3 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.UpAdjustEcShardCountDelta(int64(len(newShards) - len(deletedShards)))
  49. dn.ecShardsLock.Unlock()
  50. }
  51. return
  52. }
  53. func (dn *DataNode) DeltaUpdateEcShards(newShards, deletedShards []*erasure_coding.EcVolumeInfo) {
  54. for _, newShard := range newShards {
  55. dn.AddOrUpdateEcShard(newShard)
  56. }
  57. for _, deletedShard := range deletedShards {
  58. dn.DeleteEcShard(deletedShard)
  59. }
  60. }
  61. func (dn *DataNode) AddOrUpdateEcShard(s *erasure_coding.EcVolumeInfo) {
  62. dn.ecShardsLock.Lock()
  63. defer dn.ecShardsLock.Unlock()
  64. delta := 0
  65. if existing, ok := dn.ecShards[s.VolumeId]; !ok {
  66. dn.ecShards[s.VolumeId] = s
  67. delta = s.ShardBits.ShardIdCount()
  68. } else {
  69. oldCount := existing.ShardBits.ShardIdCount()
  70. existing.ShardBits = existing.ShardBits.Plus(s.ShardBits)
  71. delta = existing.ShardBits.ShardIdCount() - oldCount
  72. }
  73. dn.UpAdjustEcShardCountDelta(int64(delta))
  74. }
  75. func (dn *DataNode) DeleteEcShard(s *erasure_coding.EcVolumeInfo) {
  76. dn.ecShardsLock.Lock()
  77. defer dn.ecShardsLock.Unlock()
  78. if existing, ok := dn.ecShards[s.VolumeId]; ok {
  79. oldCount := existing.ShardBits.ShardIdCount()
  80. existing.ShardBits = existing.ShardBits.Minus(s.ShardBits)
  81. delta := existing.ShardBits.ShardIdCount() - oldCount
  82. dn.UpAdjustEcShardCountDelta(int64(delta))
  83. if existing.ShardBits.ShardIdCount() == 0 {
  84. delete(dn.ecShards, s.VolumeId)
  85. }
  86. }
  87. }
  88. func (dn *DataNode) HasVolumesById(id needle.VolumeId) (hasVolumeId bool) {
  89. // check whether normal volumes has this volume id
  90. dn.RLock()
  91. _, ok := dn.volumes[id]
  92. if ok {
  93. hasVolumeId = true
  94. }
  95. dn.RUnlock()
  96. if hasVolumeId {
  97. return
  98. }
  99. // check whether ec shards has this volume id
  100. dn.ecShardsLock.RLock()
  101. _, ok = dn.ecShards[id]
  102. if ok {
  103. hasVolumeId = true
  104. }
  105. dn.ecShardsLock.RUnlock()
  106. return
  107. }