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.

205 lines
5.4 KiB

13 years ago
13 years ago
13 years ago
  1. package topology
  2. import (
  3. "code.google.com/p/weed-fs/go/glog"
  4. "code.google.com/p/weed-fs/go/storage"
  5. )
  6. type NodeId string
  7. type Node interface {
  8. Id() NodeId
  9. String() string
  10. FreeSpace() int
  11. ReserveOneVolume(r int, vid storage.VolumeId, dataCenter string) (bool, *DataNode)
  12. UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta int)
  13. UpAdjustVolumeCountDelta(volumeCountDelta int)
  14. UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta int)
  15. UpAdjustMaxVolumeId(vid storage.VolumeId)
  16. GetVolumeCount() int
  17. GetActiveVolumeCount() int
  18. GetMaxVolumeCount() int
  19. GetMaxVolumeId() storage.VolumeId
  20. SetParent(Node)
  21. LinkChildNode(node Node)
  22. UnlinkChildNode(nodeId NodeId)
  23. CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64)
  24. IsDataNode() bool
  25. IsRack() bool
  26. IsDataCenter() bool
  27. Children() map[NodeId]Node
  28. Parent() Node
  29. GetValue() interface{} //get reference to the topology,dc,rack,datanode
  30. }
  31. type NodeImpl struct {
  32. id NodeId
  33. volumeCount int
  34. activeVolumeCount int
  35. maxVolumeCount int
  36. parent Node
  37. children map[NodeId]Node
  38. maxVolumeId storage.VolumeId
  39. //for rack, data center, topology
  40. nodeType string
  41. value interface{}
  42. }
  43. func (n *NodeImpl) IsDataNode() bool {
  44. return n.nodeType == "DataNode"
  45. }
  46. func (n *NodeImpl) IsRack() bool {
  47. return n.nodeType == "Rack"
  48. }
  49. func (n *NodeImpl) IsDataCenter() bool {
  50. return n.nodeType == "DataCenter"
  51. }
  52. func (n *NodeImpl) String() string {
  53. if n.parent != nil {
  54. return n.parent.String() + ":" + string(n.id)
  55. }
  56. return string(n.id)
  57. }
  58. func (n *NodeImpl) Id() NodeId {
  59. return n.id
  60. }
  61. func (n *NodeImpl) FreeSpace() int {
  62. return n.maxVolumeCount - n.volumeCount
  63. }
  64. func (n *NodeImpl) SetParent(node Node) {
  65. n.parent = node
  66. }
  67. func (n *NodeImpl) Children() map[NodeId]Node {
  68. return n.children
  69. }
  70. func (n *NodeImpl) Parent() Node {
  71. return n.parent
  72. }
  73. func (n *NodeImpl) GetValue() interface{} {
  74. return n.value
  75. }
  76. func (n *NodeImpl) ReserveOneVolume(r int, vid storage.VolumeId, dataCenter string) (bool, *DataNode) {
  77. ret := false
  78. var assignedNode *DataNode
  79. for _, node := range n.children {
  80. freeSpace := node.FreeSpace()
  81. // fmt.Println("r =", r, ", node =", node, ", freeSpace =", freeSpace)
  82. if freeSpace <= 0 {
  83. continue
  84. }
  85. if dataCenter != "" && node.IsDataCenter() && node.Id() != NodeId(dataCenter) {
  86. continue
  87. }
  88. if r >= freeSpace {
  89. r -= freeSpace
  90. } else {
  91. if node.IsDataNode() && node.FreeSpace() > 0 {
  92. // fmt.Println("vid =", vid, " assigned to node =", node, ", freeSpace =", node.FreeSpace())
  93. return true, node.(*DataNode)
  94. }
  95. ret, assignedNode = node.ReserveOneVolume(r, vid, dataCenter)
  96. if ret {
  97. break
  98. }
  99. }
  100. }
  101. return ret, assignedNode
  102. }
  103. func (n *NodeImpl) UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta int) { //can be negative
  104. n.maxVolumeCount += maxVolumeCountDelta
  105. if n.parent != nil {
  106. n.parent.UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta)
  107. }
  108. }
  109. func (n *NodeImpl) UpAdjustVolumeCountDelta(volumeCountDelta int) { //can be negative
  110. n.volumeCount += volumeCountDelta
  111. if n.parent != nil {
  112. n.parent.UpAdjustVolumeCountDelta(volumeCountDelta)
  113. }
  114. }
  115. func (n *NodeImpl) UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta int) { //can be negative
  116. n.activeVolumeCount += activeVolumeCountDelta
  117. if n.parent != nil {
  118. n.parent.UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta)
  119. }
  120. }
  121. func (n *NodeImpl) UpAdjustMaxVolumeId(vid storage.VolumeId) { //can be negative
  122. if n.maxVolumeId < vid {
  123. n.maxVolumeId = vid
  124. if n.parent != nil {
  125. n.parent.UpAdjustMaxVolumeId(vid)
  126. }
  127. }
  128. }
  129. func (n *NodeImpl) GetMaxVolumeId() storage.VolumeId {
  130. return n.maxVolumeId
  131. }
  132. func (n *NodeImpl) GetVolumeCount() int {
  133. return n.volumeCount
  134. }
  135. func (n *NodeImpl) GetActiveVolumeCount() int {
  136. return n.activeVolumeCount
  137. }
  138. func (n *NodeImpl) GetMaxVolumeCount() int {
  139. return n.maxVolumeCount
  140. }
  141. func (n *NodeImpl) LinkChildNode(node Node) {
  142. if n.children[node.Id()] == nil {
  143. n.children[node.Id()] = node
  144. n.UpAdjustMaxVolumeCountDelta(node.GetMaxVolumeCount())
  145. n.UpAdjustMaxVolumeId(node.GetMaxVolumeId())
  146. n.UpAdjustVolumeCountDelta(node.GetVolumeCount())
  147. n.UpAdjustActiveVolumeCountDelta(node.GetActiveVolumeCount())
  148. node.SetParent(n)
  149. glog.V(0).Infoln(n, "adds child", node.Id())
  150. }
  151. }
  152. func (n *NodeImpl) UnlinkChildNode(nodeId NodeId) {
  153. node := n.children[nodeId]
  154. node.SetParent(nil)
  155. if node != nil {
  156. delete(n.children, node.Id())
  157. n.UpAdjustVolumeCountDelta(-node.GetVolumeCount())
  158. n.UpAdjustActiveVolumeCountDelta(-node.GetActiveVolumeCount())
  159. n.UpAdjustMaxVolumeCountDelta(-node.GetMaxVolumeCount())
  160. glog.V(0).Infoln(n, "removes", node, "volumeCount =", n.activeVolumeCount)
  161. }
  162. }
  163. func (n *NodeImpl) CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64) {
  164. if n.IsRack() {
  165. for _, c := range n.Children() {
  166. dn := c.(*DataNode) //can not cast n to DataNode
  167. if dn.LastSeen < freshThreshHold {
  168. if !dn.Dead {
  169. dn.Dead = true
  170. n.GetTopology().chanDeadDataNodes <- dn
  171. }
  172. }
  173. for _, v := range dn.volumes {
  174. if uint64(v.Size) >= volumeSizeLimit {
  175. //fmt.Println("volume",v.Id,"size",v.Size,">",volumeSizeLimit)
  176. n.GetTopology().chanFullVolumes <- v
  177. }
  178. }
  179. }
  180. } else {
  181. for _, c := range n.Children() {
  182. c.CollectDeadNodeAndFullVolumes(freshThreshHold, volumeSizeLimit)
  183. }
  184. }
  185. }
  186. func (n *NodeImpl) GetTopology() *Topology {
  187. var p Node
  188. p = n
  189. for p.Parent() != nil {
  190. p = p.Parent()
  191. }
  192. return p.GetValue().(*Topology)
  193. }