2019-05-23 13:44:28 +08:00
|
|
|
package topology
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/storage/erasure_coding"
|
2019-05-24 13:51:18 +08:00
|
|
|
"github.com/chrislusf/seaweedfs/weed/storage/needle"
|
2019-05-23 13:44:28 +08:00
|
|
|
)
|
|
|
|
|
2019-05-23 15:42:28 +08:00
|
|
|
func (dn *DataNode) GetEcShards() (ret []*erasure_coding.EcVolumeInfo) {
|
2019-05-23 13:44:28 +08:00
|
|
|
dn.RLock()
|
|
|
|
for _, ecVolumeInfo := range dn.ecShards {
|
|
|
|
ret = append(ret, ecVolumeInfo)
|
|
|
|
}
|
|
|
|
dn.RUnlock()
|
|
|
|
return ret
|
|
|
|
}
|
2019-05-23 15:42:28 +08:00
|
|
|
|
|
|
|
func (dn *DataNode) UpdateEcShards(actualShards []*erasure_coding.EcVolumeInfo) (newShards, deletedShards []*erasure_coding.EcVolumeInfo) {
|
2019-05-24 13:51:18 +08:00
|
|
|
// prepare the new ec shard map
|
|
|
|
actualEcShardMap := make(map[needle.VolumeId]*erasure_coding.EcVolumeInfo)
|
|
|
|
for _, ecShards := range actualShards {
|
2019-05-24 14:34:29 +08:00
|
|
|
actualEcShardMap[ecShards.VolumeId] = ecShards
|
2019-05-24 13:51:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// found out the newShards and deletedShards
|
2019-06-05 16:58:37 +08:00
|
|
|
var newShardCount, deletedShardCount int
|
2019-05-24 13:51:18 +08:00
|
|
|
dn.ecShardsLock.RLock()
|
2019-05-24 14:34:29 +08:00
|
|
|
for vid, ecShards := range dn.ecShards {
|
2019-05-24 13:51:18 +08:00
|
|
|
if actualEcShards, ok := actualEcShardMap[vid]; !ok {
|
|
|
|
// dn registered ec shards not found in the new set of ec shards
|
|
|
|
deletedShards = append(deletedShards, ecShards)
|
2019-06-05 16:58:37 +08:00
|
|
|
deletedShardCount += ecShards.ShardIdCount()
|
2019-05-24 13:51:18 +08:00
|
|
|
} else {
|
|
|
|
// found, but maybe the actual shard could be missing
|
|
|
|
a := actualEcShards.Minus(ecShards)
|
2019-05-25 17:02:44 +08:00
|
|
|
if a.ShardIdCount() > 0 {
|
2019-05-24 13:51:18 +08:00
|
|
|
newShards = append(newShards, a)
|
2019-06-05 16:58:37 +08:00
|
|
|
newShardCount += a.ShardIdCount()
|
2019-05-24 13:51:18 +08:00
|
|
|
}
|
|
|
|
d := ecShards.Minus(actualEcShards)
|
2019-05-25 17:02:44 +08:00
|
|
|
if d.ShardIdCount() > 0 {
|
2019-05-24 13:51:18 +08:00
|
|
|
deletedShards = append(deletedShards, d)
|
2019-06-05 16:58:37 +08:00
|
|
|
deletedShardCount += d.ShardIdCount()
|
2019-05-24 13:51:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, ecShards := range actualShards {
|
|
|
|
if _, found := dn.ecShards[ecShards.VolumeId]; !found {
|
|
|
|
newShards = append(newShards, ecShards)
|
2019-06-05 16:58:37 +08:00
|
|
|
newShardCount += ecShards.ShardIdCount()
|
2019-05-24 13:51:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
dn.ecShardsLock.RUnlock()
|
|
|
|
|
2019-05-24 14:34:29 +08:00
|
|
|
if len(newShards) > 0 || len(deletedShards) > 0 {
|
2019-05-24 13:51:18 +08:00
|
|
|
// if changed, set to the new ec shard map
|
|
|
|
dn.ecShardsLock.Lock()
|
|
|
|
dn.ecShards = actualEcShardMap
|
2019-06-05 16:58:37 +08:00
|
|
|
dn.UpAdjustEcShardCountDelta(int64(newShardCount - deletedShardCount))
|
2019-05-24 13:51:18 +08:00
|
|
|
dn.ecShardsLock.Unlock()
|
|
|
|
}
|
|
|
|
|
2019-05-23 15:42:28 +08:00
|
|
|
return
|
|
|
|
}
|
2019-05-26 15:21:17 +08:00
|
|
|
|
|
|
|
func (dn *DataNode) DeltaUpdateEcShards(newShards, deletedShards []*erasure_coding.EcVolumeInfo) {
|
|
|
|
|
|
|
|
for _, newShard := range newShards {
|
|
|
|
dn.AddOrUpdateEcShard(newShard)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, deletedShard := range deletedShards {
|
|
|
|
dn.DeleteEcShard(deletedShard)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (dn *DataNode) AddOrUpdateEcShard(s *erasure_coding.EcVolumeInfo) {
|
|
|
|
dn.ecShardsLock.Lock()
|
|
|
|
defer dn.ecShardsLock.Unlock()
|
|
|
|
|
2019-06-05 14:41:56 +08:00
|
|
|
delta := 0
|
2019-05-26 15:21:17 +08:00
|
|
|
if existing, ok := dn.ecShards[s.VolumeId]; !ok {
|
|
|
|
dn.ecShards[s.VolumeId] = s
|
2019-06-05 14:41:56 +08:00
|
|
|
delta = s.ShardBits.ShardIdCount()
|
2019-05-26 15:21:17 +08:00
|
|
|
} else {
|
2019-06-05 14:41:56 +08:00
|
|
|
oldCount := existing.ShardBits.ShardIdCount()
|
2019-05-26 15:21:17 +08:00
|
|
|
existing.ShardBits = existing.ShardBits.Plus(s.ShardBits)
|
2019-06-05 14:41:56 +08:00
|
|
|
delta = existing.ShardBits.ShardIdCount() - oldCount
|
2019-05-26 15:21:17 +08:00
|
|
|
}
|
|
|
|
|
2019-06-05 14:41:56 +08:00
|
|
|
dn.UpAdjustEcShardCountDelta(int64(delta))
|
|
|
|
|
2019-05-26 15:21:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (dn *DataNode) DeleteEcShard(s *erasure_coding.EcVolumeInfo) {
|
|
|
|
dn.ecShardsLock.Lock()
|
|
|
|
defer dn.ecShardsLock.Unlock()
|
|
|
|
|
|
|
|
if existing, ok := dn.ecShards[s.VolumeId]; ok {
|
2019-06-05 14:41:56 +08:00
|
|
|
oldCount := existing.ShardBits.ShardIdCount()
|
2019-05-26 15:21:17 +08:00
|
|
|
existing.ShardBits = existing.ShardBits.Minus(s.ShardBits)
|
2019-06-05 14:41:56 +08:00
|
|
|
delta := existing.ShardBits.ShardIdCount() - oldCount
|
|
|
|
dn.UpAdjustEcShardCountDelta(int64(delta))
|
2019-05-26 15:21:17 +08:00
|
|
|
if existing.ShardBits.ShardIdCount() == 0 {
|
|
|
|
delete(dn.ecShards, s.VolumeId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2019-05-26 15:49:15 +08:00
|
|
|
|
|
|
|
func (dn *DataNode) HasVolumesById(id needle.VolumeId) (hasVolumeId bool) {
|
|
|
|
|
|
|
|
// check whether normal volumes has this volume id
|
|
|
|
dn.RLock()
|
|
|
|
_, ok := dn.volumes[id]
|
|
|
|
if ok {
|
|
|
|
hasVolumeId = true
|
|
|
|
}
|
|
|
|
dn.RUnlock()
|
|
|
|
|
|
|
|
if hasVolumeId {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// check whether ec shards has this volume id
|
|
|
|
dn.ecShardsLock.RLock()
|
|
|
|
_, ok = dn.ecShards[id]
|
|
|
|
if ok {
|
|
|
|
hasVolumeId = true
|
|
|
|
}
|
|
|
|
dn.ecShardsLock.RUnlock()
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|