2012-08-24 03:56:09 +00:00
|
|
|
package topology
|
|
|
|
|
2012-08-24 05:56:14 +00:00
|
|
|
import (
|
2012-08-31 08:35:11 +00:00
|
|
|
"fmt"
|
2012-08-29 07:58:03 +00:00
|
|
|
"pkg/storage"
|
2012-08-24 05:56:14 +00:00
|
|
|
)
|
2012-08-24 03:56:09 +00:00
|
|
|
|
2012-08-28 08:04:39 +00:00
|
|
|
type NodeId string
|
2012-09-02 21:33:48 +00:00
|
|
|
type Node interface {
|
|
|
|
Id() NodeId
|
|
|
|
String() string
|
|
|
|
FreeSpace() int
|
2012-09-08 23:25:44 +00:00
|
|
|
ReserveOneVolume(r int, vid storage.VolumeId) (bool, *DataNode)
|
2012-09-02 21:33:48 +00:00
|
|
|
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-10 07:18:07 +00:00
|
|
|
CollectWritableVolumes(freshThreshHold int64, volumeSizeLimit uint64) []storage.VolumeId
|
2012-09-03 08:50:04 +00:00
|
|
|
|
2012-09-08 23:25:44 +00:00
|
|
|
IsDataNode() bool
|
2012-09-03 08:50:04 +00:00
|
|
|
Children() map[NodeId]Node
|
2012-09-10 07:18:07 +00:00
|
|
|
Parent() Node
|
2012-08-24 03:56:09 +00:00
|
|
|
}
|
2012-09-02 21:33:48 +00:00
|
|
|
type NodeImpl struct {
|
|
|
|
id NodeId
|
|
|
|
activeVolumeCount int
|
|
|
|
maxVolumeCount int
|
|
|
|
parent Node
|
|
|
|
children map[NodeId]Node
|
|
|
|
maxVolumeId storage.VolumeId
|
2012-08-29 07:58:03 +00:00
|
|
|
|
2012-09-02 21:33:48 +00:00
|
|
|
//for rack, data center, topology
|
|
|
|
nodeType string
|
2012-09-01 09:20:59 +00:00
|
|
|
}
|
2012-08-31 08:35:11 +00:00
|
|
|
|
2012-09-08 23:25:44 +00:00
|
|
|
func (n *NodeImpl) IsDataNode() bool {
|
|
|
|
return n.nodeType == "DataNode"
|
2012-09-02 21:33:48 +00:00
|
|
|
}
|
|
|
|
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 08:50:04 +00:00
|
|
|
func (n *NodeImpl) Children() map[NodeId]Node {
|
|
|
|
return n.children
|
|
|
|
}
|
|
|
|
func (n *NodeImpl) Parent() Node {
|
2012-09-10 07:18:07 +00:00
|
|
|
return n.parent
|
2012-09-03 08:50:04 +00:00
|
|
|
}
|
2012-09-08 23:25:44 +00:00
|
|
|
func (n *NodeImpl) ReserveOneVolume(r int, vid storage.VolumeId) (bool, *DataNode) {
|
2012-09-02 21:33:48 +00:00
|
|
|
ret := false
|
2012-09-08 23:25:44 +00:00
|
|
|
var assignedNode *DataNode
|
2012-08-29 07:58:03 +00:00
|
|
|
for _, node := range n.children {
|
2012-09-02 21:33:48 +00:00
|
|
|
freeSpace := node.FreeSpace()
|
2012-09-03 08:50:04 +00:00
|
|
|
//fmt.Println("r =", r, ", node =", node, ", freeSpace =", freeSpace)
|
2012-09-02 21:33:48 +00:00
|
|
|
if freeSpace <= 0 {
|
|
|
|
continue
|
|
|
|
}
|
2012-09-01 09:20:59 +00:00
|
|
|
if r >= freeSpace {
|
2012-08-29 07:58:03 +00:00
|
|
|
r -= freeSpace
|
|
|
|
} else {
|
2012-09-08 23:25:44 +00:00
|
|
|
if node.IsDataNode() && node.FreeSpace() > 0 {
|
2012-09-03 08:50:04 +00:00
|
|
|
//fmt.Println("vid =", vid, " assigned to node =", node, ", freeSpace =", node.FreeSpace())
|
2012-09-08 23:25:44 +00:00
|
|
|
return true, node.(*DataNode)
|
2012-09-03 08:50:04 +00:00
|
|
|
}
|
2012-09-02 21:33:48 +00:00
|
|
|
ret, assignedNode = node.ReserveOneVolume(r, vid)
|
|
|
|
if ret {
|
|
|
|
break
|
|
|
|
}
|
2012-08-29 07:58:03 +00:00
|
|
|
}
|
|
|
|
}
|
2012-09-01 09:43:43 +00:00
|
|
|
return ret, assignedNode
|
2012-08-29 07:58:03 +00:00
|
|
|
}
|
|
|
|
|
2012-09-02 21:33:48 +00:00
|
|
|
func (n *NodeImpl) UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta int) { //can be negative
|
|
|
|
n.maxVolumeCount += maxVolumeCountDelta
|
|
|
|
if n.parent != nil {
|
|
|
|
n.parent.UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta)
|
2012-08-31 08:35:11 +00:00
|
|
|
}
|
2012-09-02 21:33:48 +00:00
|
|
|
}
|
|
|
|
func (n *NodeImpl) UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta int) { //can be negative
|
|
|
|
n.activeVolumeCount += activeVolumeCountDelta
|
2012-08-29 07:58:03 +00:00
|
|
|
if n.parent != nil {
|
2012-09-02 21:33:48 +00:00
|
|
|
n.parent.UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta)
|
2012-08-29 07:58:03 +00:00
|
|
|
}
|
2012-08-27 20:52:02 +00:00
|
|
|
}
|
2012-09-02 21:33:48 +00:00
|
|
|
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 09:20:59 +00:00
|
|
|
}
|
2012-08-29 07:58:03 +00:00
|
|
|
|
2012-09-02 21:33:48 +00:00
|
|
|
func (n *NodeImpl) GetMaxVolumeId() storage.VolumeId {
|
2012-08-31 08:35:11 +00:00
|
|
|
return n.maxVolumeId
|
2012-08-29 08:37:40 +00:00
|
|
|
}
|
2012-09-02 21:33:48 +00:00
|
|
|
func (n *NodeImpl) GetActiveVolumeCount() int {
|
|
|
|
return n.activeVolumeCount
|
|
|
|
}
|
|
|
|
func (n *NodeImpl) GetMaxVolumeCount() int {
|
|
|
|
return n.maxVolumeCount
|
|
|
|
}
|
2012-08-29 08:37:40 +00:00
|
|
|
|
2012-09-02 21:33:48 +00:00
|
|
|
func (n *NodeImpl) LinkChildNode(node Node) {
|
|
|
|
if n.children[node.Id()] == nil {
|
|
|
|
n.children[node.Id()] = node
|
2012-09-17 00:31:15 +00:00
|
|
|
n.UpAdjustMaxVolumeCountDelta(node.GetMaxVolumeCount())
|
|
|
|
n.UpAdjustMaxVolumeId(node.GetMaxVolumeId())
|
|
|
|
n.UpAdjustActiveVolumeCountDelta(node.GetActiveVolumeCount())
|
2012-09-02 21:33:48 +00:00
|
|
|
node.setParent(n)
|
|
|
|
fmt.Println(n, "adds", node, "volumeCount =", n.activeVolumeCount)
|
2012-08-29 07:58:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-02 21:33:48 +00:00
|
|
|
func (n *NodeImpl) UnlinkChildNode(nodeId NodeId) {
|
2012-09-01 09:20:59 +00:00
|
|
|
node := n.children[nodeId]
|
2012-09-02 21:33:48 +00:00
|
|
|
node.setParent(nil)
|
2012-09-01 09:20:59 +00:00
|
|
|
if node != nil {
|
2012-09-02 21:33:48 +00:00
|
|
|
delete(n.children, node.Id())
|
|
|
|
n.UpAdjustActiveVolumeCountDelta(-node.GetActiveVolumeCount())
|
|
|
|
n.UpAdjustMaxVolumeCountDelta(-node.GetMaxVolumeCount())
|
|
|
|
fmt.Println(n, "removes", node, "volumeCount =", n.activeVolumeCount)
|
2012-08-29 07:58:03 +00:00
|
|
|
}
|
2012-08-27 20:52:02 +00:00
|
|
|
}
|
2012-09-10 07:18:07 +00:00
|
|
|
|
|
|
|
func (n *NodeImpl) CollectWritableVolumes(freshThreshHold int64, volumeSizeLimit uint64) []storage.VolumeId {
|
|
|
|
var ret []storage.VolumeId
|
|
|
|
if n.IsRack() {
|
|
|
|
for _, c := range n.Children() {
|
|
|
|
dn := c.(*DataNode) //can not cast n to DataNode
|
|
|
|
if dn.lastSeen > freshThreshHold {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for _, v := range dn.volumes {
|
|
|
|
if uint64(v.Size) < volumeSizeLimit {
|
|
|
|
ret = append(ret, v.Id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for _, c := range n.Children() {
|
|
|
|
ret = append(ret, c.CollectWritableVolumes(freshThreshHold, volumeSizeLimit)...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret
|
|
|
|
}
|