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.

95 lines
2.6 KiB

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