seaweedfs/weed-fs/src/pkg/topology/node.go

186 lines
4.6 KiB
Go
Raw Normal View History

2012-08-24 11:56:09 +08:00
package topology
2012-08-24 13:56:14 +08:00
import (
2012-08-31 16:35:11 +08:00
"fmt"
"pkg/storage"
2012-08-24 13:56:14 +08:00
)
2012-08-24 11:56:09 +08:00
type NodeId string
type Node interface {
Id() NodeId
String() string
FreeSpace() int
2012-09-09 07:25:44 +08:00
ReserveOneVolume(r int, vid storage.VolumeId) (bool, *DataNode)
UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta int)
UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta int)
UpAdjustMaxVolumeId(vid storage.VolumeId)
GetActiveVolumeCount() int
GetMaxVolumeCount() int
GetMaxVolumeId() storage.VolumeId
SetParent(Node)
LinkChildNode(node Node)
UnlinkChildNode(nodeId NodeId)
2012-09-19 05:05:12 +08:00
CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64)
2012-09-03 16:50:04 +08:00
2012-09-09 07:25:44 +08:00
IsDataNode() bool
2012-09-03 16:50:04 +08:00
Children() map[NodeId]Node
Parent() Node
GetValue()interface{} //get reference to the topology,dc,rack,datanode
2012-08-24 11:56:09 +08:00
}
type NodeImpl struct {
id NodeId
activeVolumeCount int
maxVolumeCount int
parent Node
children map[NodeId]Node
maxVolumeId storage.VolumeId
//for rack, data center, topology
nodeType string
value interface{}
2012-09-01 17:20:59 +08:00
}
2012-08-31 16:35:11 +08:00
2012-09-09 07:25:44 +08:00
func (n *NodeImpl) IsDataNode() bool {
return n.nodeType == "DataNode"
}
func (n *NodeImpl) IsRack() bool {
return n.nodeType == "Rack"
}
func (n *NodeImpl) IsDataCenter() bool {
return n.nodeType == "DataCenter"
}
func (n *NodeImpl) String() string {
if n.parent != nil {
return n.parent.String() + ":" + string(n.id)
}
return string(n.id)
}
func (n *NodeImpl) Id() NodeId {
return n.id
}
func (n *NodeImpl) FreeSpace() int {
return n.maxVolumeCount - n.activeVolumeCount
}
func (n *NodeImpl) SetParent(node Node) {
n.parent = node
}
2012-09-03 16:50:04 +08:00
func (n *NodeImpl) Children() map[NodeId]Node {
return n.children
}
func (n *NodeImpl) Parent() Node {
return n.parent
2012-09-03 16:50:04 +08:00
}
func (n *NodeImpl) GetValue()interface{}{
return n.value
}
2012-09-09 07:25:44 +08:00
func (n *NodeImpl) ReserveOneVolume(r int, vid storage.VolumeId) (bool, *DataNode) {
ret := false
2012-09-09 07:25:44 +08:00
var assignedNode *DataNode
for _, node := range n.children {
freeSpace := node.FreeSpace()
2012-09-03 16:50:04 +08:00
//fmt.Println("r =", r, ", node =", node, ", freeSpace =", freeSpace)
if freeSpace <= 0 {
continue
}
2012-09-01 17:20:59 +08:00
if r >= freeSpace {
r -= freeSpace
} else {
2012-09-09 07:25:44 +08:00
if node.IsDataNode() && node.FreeSpace() > 0 {
2012-09-03 16:50:04 +08:00
//fmt.Println("vid =", vid, " assigned to node =", node, ", freeSpace =", node.FreeSpace())
2012-09-09 07:25:44 +08:00
return true, node.(*DataNode)
2012-09-03 16:50:04 +08:00
}
ret, assignedNode = node.ReserveOneVolume(r, vid)
if ret {
break
}
}
}
return ret, assignedNode
}
func (n *NodeImpl) UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta int) { //can be negative
n.maxVolumeCount += maxVolumeCountDelta
if n.parent != nil {
n.parent.UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta)
2012-08-31 16:35:11 +08:00
}
}
func (n *NodeImpl) UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta int) { //can be negative
n.activeVolumeCount += activeVolumeCountDelta
if n.parent != nil {
n.parent.UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta)
}
}
func (n *NodeImpl) UpAdjustMaxVolumeId(vid storage.VolumeId) { //can be negative
if n.maxVolumeId < vid {
n.maxVolumeId = vid
if n.parent != nil {
n.parent.UpAdjustMaxVolumeId(vid)
}
}
2012-09-01 17:20:59 +08:00
}
func (n *NodeImpl) GetMaxVolumeId() storage.VolumeId {
2012-08-31 16:35:11 +08:00
return n.maxVolumeId
2012-08-29 16:37:40 +08:00
}
func (n *NodeImpl) GetActiveVolumeCount() int {
return n.activeVolumeCount
}
func (n *NodeImpl) GetMaxVolumeCount() int {
return n.maxVolumeCount
}
2012-08-29 16:37:40 +08:00
func (n *NodeImpl) LinkChildNode(node Node) {
if n.children[node.Id()] == nil {
n.children[node.Id()] = node
n.UpAdjustMaxVolumeCountDelta(node.GetMaxVolumeCount())
n.UpAdjustMaxVolumeId(node.GetMaxVolumeId())
n.UpAdjustActiveVolumeCountDelta(node.GetActiveVolumeCount())
node.SetParent(n)
2012-09-17 14:21:18 +08:00
fmt.Println(n, "adds child", node)
}
}
func (n *NodeImpl) UnlinkChildNode(nodeId NodeId) {
2012-09-01 17:20:59 +08:00
node := n.children[nodeId]
node.SetParent(nil)
2012-09-01 17:20:59 +08:00
if node != nil {
delete(n.children, node.Id())
n.UpAdjustActiveVolumeCountDelta(-node.GetActiveVolumeCount())
n.UpAdjustMaxVolumeCountDelta(-node.GetMaxVolumeCount())
fmt.Println(n, "removes", node, "volumeCount =", n.activeVolumeCount)
}
}
2012-09-19 05:05:12 +08:00
func (n *NodeImpl) CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64) {
if n.IsRack() {
for _, c := range n.Children() {
dn := c.(*DataNode) //can not cast n to DataNode
if dn.LastSeen < freshThreshHold {
2012-09-19 05:05:12 +08:00
if !dn.Dead {
dn.Dead = true
n.GetTopology().chanDeadDataNodes <- dn
}
}
for _, v := range dn.volumes {
if uint64(v.Size) >= volumeSizeLimit {
n.GetTopology().chanFullVolumes <- &v
}
}
}
} else {
for _, c := range n.Children() {
2012-09-19 05:05:12 +08:00
c.CollectDeadNodeAndFullVolumes(freshThreshHold, volumeSizeLimit)
}
}
2012-09-19 05:05:12 +08:00
}
2012-09-19 05:05:12 +08:00
func (n *NodeImpl) GetTopology() *Topology{
var p Node
p = n
for p.Parent() != nil {
p = p.Parent()
}
return p.GetValue().(*Topology)
}