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.

250 lines
6.6 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. "errors"
  6. "math/rand"
  7. )
  8. type NodeId string
  9. type Node interface {
  10. Id() NodeId
  11. String() string
  12. FreeSpace() int
  13. ReserveOneVolume(r int) (*DataNode, error)
  14. UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta int)
  15. UpAdjustVolumeCountDelta(volumeCountDelta int)
  16. UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta int)
  17. UpAdjustMaxVolumeId(vid storage.VolumeId)
  18. GetVolumeCount() int
  19. GetActiveVolumeCount() int
  20. GetMaxVolumeCount() int
  21. GetMaxVolumeId() storage.VolumeId
  22. SetParent(Node)
  23. LinkChildNode(node Node)
  24. UnlinkChildNode(nodeId NodeId)
  25. CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64)
  26. IsDataNode() bool
  27. IsRack() bool
  28. IsDataCenter() bool
  29. Children() map[NodeId]Node
  30. Parent() Node
  31. GetValue() interface{} //get reference to the topology,dc,rack,datanode
  32. }
  33. type NodeImpl struct {
  34. id NodeId
  35. volumeCount int
  36. activeVolumeCount int
  37. maxVolumeCount int
  38. parent Node
  39. children map[NodeId]Node
  40. maxVolumeId storage.VolumeId
  41. //for rack, data center, topology
  42. nodeType string
  43. value interface{}
  44. }
  45. // the first node must satisfy filterFirstNodeFn(), the rest nodes must have one free slot
  46. func (n *NodeImpl) RandomlyPickNodes(numberOfNodes int, filterFirstNodeFn func(dn Node) bool) (firstNode Node, restNodes []Node, err error) {
  47. candidates := make([]Node, 0, len(n.children))
  48. for _, node := range n.children {
  49. if filterFirstNodeFn(node) {
  50. candidates = append(candidates, node)
  51. }
  52. }
  53. if len(candidates) == 0 {
  54. return nil, nil, errors.New("No matching data node found!")
  55. }
  56. firstNode = candidates[rand.Intn(len(candidates))]
  57. glog.V(2).Infoln(n.Id(), "picked main node:", firstNode.Id())
  58. restNodes = make([]Node, numberOfNodes-1)
  59. candidates = candidates[:0]
  60. for _, node := range n.children {
  61. if node.Id() == firstNode.Id() {
  62. continue
  63. }
  64. if node.FreeSpace() <= 0 {
  65. continue
  66. }
  67. glog.V(2).Infoln("select rest node candidate:", node.Id())
  68. candidates = append(candidates, node)
  69. }
  70. glog.V(2).Infoln(n.Id(), "picking", numberOfNodes-1, "from rest", len(candidates), "node candidates")
  71. ret := len(restNodes) == 0
  72. for k, node := range candidates {
  73. if k < len(restNodes) {
  74. restNodes[k] = node
  75. if k == len(restNodes)-1 {
  76. ret = true
  77. }
  78. } else {
  79. r := rand.Intn(k + 1)
  80. if r < len(restNodes) {
  81. restNodes[r] = node
  82. }
  83. }
  84. }
  85. if !ret {
  86. glog.V(2).Infoln(n.Id(), "failed to pick", numberOfNodes-1, "from rest", len(candidates), "node candidates")
  87. err = errors.New("Not enough data node found!")
  88. }
  89. return
  90. }
  91. func (n *NodeImpl) IsDataNode() bool {
  92. return n.nodeType == "DataNode"
  93. }
  94. func (n *NodeImpl) IsRack() bool {
  95. return n.nodeType == "Rack"
  96. }
  97. func (n *NodeImpl) IsDataCenter() bool {
  98. return n.nodeType == "DataCenter"
  99. }
  100. func (n *NodeImpl) String() string {
  101. if n.parent != nil {
  102. return n.parent.String() + ":" + string(n.id)
  103. }
  104. return string(n.id)
  105. }
  106. func (n *NodeImpl) Id() NodeId {
  107. return n.id
  108. }
  109. func (n *NodeImpl) FreeSpace() int {
  110. return n.maxVolumeCount - n.volumeCount
  111. }
  112. func (n *NodeImpl) SetParent(node Node) {
  113. n.parent = node
  114. }
  115. func (n *NodeImpl) Children() map[NodeId]Node {
  116. return n.children
  117. }
  118. func (n *NodeImpl) Parent() Node {
  119. return n.parent
  120. }
  121. func (n *NodeImpl) GetValue() interface{} {
  122. return n.value
  123. }
  124. func (n *NodeImpl) ReserveOneVolume(r int) (assignedNode *DataNode, err error) {
  125. for _, node := range n.children {
  126. freeSpace := node.FreeSpace()
  127. // fmt.Println("r =", r, ", node =", node, ", freeSpace =", freeSpace)
  128. if freeSpace <= 0 {
  129. continue
  130. }
  131. if r >= freeSpace {
  132. r -= freeSpace
  133. } else {
  134. if node.IsDataNode() && node.FreeSpace() > 0 {
  135. // fmt.Println("vid =", vid, " assigned to node =", node, ", freeSpace =", node.FreeSpace())
  136. return node.(*DataNode), nil
  137. }
  138. assignedNode, err = node.ReserveOneVolume(r)
  139. if err != nil {
  140. return
  141. }
  142. }
  143. }
  144. return
  145. }
  146. func (n *NodeImpl) UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta int) { //can be negative
  147. n.maxVolumeCount += maxVolumeCountDelta
  148. if n.parent != nil {
  149. n.parent.UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta)
  150. }
  151. }
  152. func (n *NodeImpl) UpAdjustVolumeCountDelta(volumeCountDelta int) { //can be negative
  153. n.volumeCount += volumeCountDelta
  154. if n.parent != nil {
  155. n.parent.UpAdjustVolumeCountDelta(volumeCountDelta)
  156. }
  157. }
  158. func (n *NodeImpl) UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta int) { //can be negative
  159. n.activeVolumeCount += activeVolumeCountDelta
  160. if n.parent != nil {
  161. n.parent.UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta)
  162. }
  163. }
  164. func (n *NodeImpl) UpAdjustMaxVolumeId(vid storage.VolumeId) { //can be negative
  165. if n.maxVolumeId < vid {
  166. n.maxVolumeId = vid
  167. if n.parent != nil {
  168. n.parent.UpAdjustMaxVolumeId(vid)
  169. }
  170. }
  171. }
  172. func (n *NodeImpl) GetMaxVolumeId() storage.VolumeId {
  173. return n.maxVolumeId
  174. }
  175. func (n *NodeImpl) GetVolumeCount() int {
  176. return n.volumeCount
  177. }
  178. func (n *NodeImpl) GetActiveVolumeCount() int {
  179. return n.activeVolumeCount
  180. }
  181. func (n *NodeImpl) GetMaxVolumeCount() int {
  182. return n.maxVolumeCount
  183. }
  184. func (n *NodeImpl) LinkChildNode(node Node) {
  185. if n.children[node.Id()] == nil {
  186. n.children[node.Id()] = node
  187. n.UpAdjustMaxVolumeCountDelta(node.GetMaxVolumeCount())
  188. n.UpAdjustMaxVolumeId(node.GetMaxVolumeId())
  189. n.UpAdjustVolumeCountDelta(node.GetVolumeCount())
  190. n.UpAdjustActiveVolumeCountDelta(node.GetActiveVolumeCount())
  191. node.SetParent(n)
  192. glog.V(0).Infoln(n, "adds child", node.Id())
  193. }
  194. }
  195. func (n *NodeImpl) UnlinkChildNode(nodeId NodeId) {
  196. node := n.children[nodeId]
  197. node.SetParent(nil)
  198. if node != nil {
  199. delete(n.children, node.Id())
  200. n.UpAdjustVolumeCountDelta(-node.GetVolumeCount())
  201. n.UpAdjustActiveVolumeCountDelta(-node.GetActiveVolumeCount())
  202. n.UpAdjustMaxVolumeCountDelta(-node.GetMaxVolumeCount())
  203. glog.V(0).Infoln(n, "removes", node, "volumeCount =", n.activeVolumeCount)
  204. }
  205. }
  206. func (n *NodeImpl) CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64) {
  207. if n.IsRack() {
  208. for _, c := range n.Children() {
  209. dn := c.(*DataNode) //can not cast n to DataNode
  210. if dn.LastSeen < freshThreshHold {
  211. if !dn.Dead {
  212. dn.Dead = true
  213. n.GetTopology().chanDeadDataNodes <- dn
  214. }
  215. }
  216. for _, v := range dn.volumes {
  217. if uint64(v.Size) >= volumeSizeLimit {
  218. //fmt.Println("volume",v.Id,"size",v.Size,">",volumeSizeLimit)
  219. n.GetTopology().chanFullVolumes <- v
  220. }
  221. }
  222. }
  223. } else {
  224. for _, c := range n.Children() {
  225. c.CollectDeadNodeAndFullVolumes(freshThreshHold, volumeSizeLimit)
  226. }
  227. }
  228. }
  229. func (n *NodeImpl) GetTopology() *Topology {
  230. var p Node
  231. p = n
  232. for p.Parent() != nil {
  233. p = p.Parent()
  234. }
  235. return p.GetValue().(*Topology)
  236. }