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.

105 lines
2.9 KiB

  1. package topology
  2. import (
  3. "math"
  4. "sort"
  5. "github.com/chrislusf/seaweedfs/weed/glog"
  6. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  7. "github.com/chrislusf/seaweedfs/weed/storage/erasure_coding"
  8. "github.com/chrislusf/seaweedfs/weed/storage/needle"
  9. )
  10. const shardCount = erasure_coding.DataShardsCount + erasure_coding.ParityShardsCount
  11. type EcShardLocations struct {
  12. Collection string
  13. locations [shardCount][]*DataNode
  14. }
  15. func (t *Topology) SyncDataNodeEcShards(shardInfos []*master_pb.VolumeEcShardInformationMessage, dn *DataNode) (newShards, deletedShards []*erasure_coding.EcVolumeInfo) {
  16. // convert into in memory struct storage.VolumeInfo
  17. var shards []*erasure_coding.EcVolumeInfo
  18. sort.Slice(shardInfos, func(i, j int) bool {
  19. return shardInfos[i].Id < shardInfos[j].Id
  20. })
  21. prevVolumeId := uint32(math.MaxUint32)
  22. var ecVolumeInfo *erasure_coding.EcVolumeInfo
  23. for _, shardInfo := range shardInfos {
  24. if shardInfo.Id != prevVolumeId {
  25. ecVolumeInfo = erasure_coding.NewEcVolumeInfo(shardInfo.Collection, needle.VolumeId(shardInfo.Id))
  26. shards = append(shards, ecVolumeInfo)
  27. }
  28. ecVolumeInfo.AddShardId(erasure_coding.ShardId(shardInfo.EcIndex))
  29. }
  30. // find out the delta volumes
  31. newShards, deletedShards = dn.UpdateEcShards(shards)
  32. for _, v := range newShards {
  33. t.RegisterEcShards(v, dn)
  34. }
  35. for _, v := range deletedShards {
  36. t.UnRegisterEcShards(v, dn)
  37. }
  38. return
  39. }
  40. func NewEcShardLocations(collection string) *EcShardLocations {
  41. return &EcShardLocations{
  42. Collection: collection,
  43. }
  44. }
  45. func (loc *EcShardLocations) AddShard(shardId erasure_coding.ShardId, dn *DataNode) (added bool) {
  46. dataNodes := loc.locations[shardId]
  47. for _, n := range dataNodes {
  48. if n.Id() == dn.Id() {
  49. return false
  50. }
  51. }
  52. loc.locations[shardId] = append(dataNodes, dn)
  53. return true
  54. }
  55. func (loc *EcShardLocations) DeleteShard(shardId erasure_coding.ShardId, dn *DataNode) (deleted bool) {
  56. dataNodes := loc.locations[shardId]
  57. foundIndex := -1
  58. for index, n := range dataNodes {
  59. if n.Id() == dn.Id() {
  60. foundIndex = index
  61. }
  62. }
  63. if foundIndex < 0 {
  64. return false
  65. }
  66. loc.locations[shardId] = append(dataNodes[:foundIndex], dataNodes[foundIndex+1:]...)
  67. return true
  68. }
  69. func (t *Topology) RegisterEcShards(ecShardInfos *erasure_coding.EcVolumeInfo, dn *DataNode) {
  70. t.ecShardMapLock.Lock()
  71. defer t.ecShardMapLock.Unlock()
  72. locations, found := t.ecShardMap[ecShardInfos.VolumeId]
  73. if !found {
  74. locations = NewEcShardLocations(ecShardInfos.Collection)
  75. t.ecShardMap[ecShardInfos.VolumeId] = locations
  76. }
  77. for _, shardId := range ecShardInfos.ShardIds() {
  78. locations.AddShard(shardId, dn)
  79. }
  80. }
  81. func (t *Topology) UnRegisterEcShards(ecShardInfos *erasure_coding.EcVolumeInfo, dn *DataNode) {
  82. glog.Infof("removing ec shard info:%+v", ecShardInfos)
  83. t.ecShardMapLock.Lock()
  84. defer t.ecShardMapLock.Unlock()
  85. locations, found := t.ecShardMap[ecShardInfos.VolumeId]
  86. if !found {
  87. return
  88. }
  89. for _, shardId := range ecShardInfos.ShardIds() {
  90. locations.DeleteShard(shardId, dn)
  91. }
  92. }