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.

83 lines
1.9 KiB

  1. package topology
  2. import (
  3. "code.google.com/p/weed-fs/go/glog"
  4. "code.google.com/p/weed-fs/go/storage"
  5. "math/rand"
  6. )
  7. type NodeList struct {
  8. nodes map[NodeId]Node
  9. except map[string]Node
  10. }
  11. func NewNodeList(nodes map[NodeId]Node, except map[string]Node) *NodeList {
  12. m := make(map[NodeId]Node, len(nodes)-len(except))
  13. for _, n := range nodes {
  14. if except[n.String()] == nil {
  15. m[n.Id()] = n
  16. }
  17. }
  18. nl := &NodeList{nodes: m}
  19. return nl
  20. }
  21. func (nl *NodeList) FreeSpace() int {
  22. freeSpace := 0
  23. for _, n := range nl.nodes {
  24. freeSpace += n.FreeSpace()
  25. }
  26. return freeSpace
  27. }
  28. func (nl *NodeList) RandomlyPickN(count int, minSpace int, firstNodeName string) ([]Node, bool) {
  29. var list []Node
  30. var preferredNode *Node
  31. if firstNodeName != "" {
  32. for _, n := range nl.nodes {
  33. if n.Id() == NodeId(firstNodeName) && n.FreeSpace() >= minSpace {
  34. preferredNode = &n
  35. break
  36. }
  37. }
  38. if preferredNode == nil {
  39. return list, false
  40. }
  41. }
  42. for _, n := range nl.nodes {
  43. if n.FreeSpace() >= minSpace && n.Id() != NodeId(firstNodeName) {
  44. list = append(list, n)
  45. }
  46. }
  47. if count > len(list) || count == len(list) && firstNodeName != "" {
  48. return nil, false
  49. }
  50. for i := len(list); i > 0; i-- {
  51. r := rand.Intn(i)
  52. list[r], list[i-1] = list[i-1], list[r]
  53. }
  54. if firstNodeName != "" {
  55. list[0] = *preferredNode
  56. }
  57. return list[:count], true
  58. }
  59. func (nl *NodeList) ReserveOneVolume(randomVolumeIndex int, vid storage.VolumeId) (bool, *DataNode) {
  60. for _, node := range nl.nodes {
  61. freeSpace := node.FreeSpace()
  62. if randomVolumeIndex >= freeSpace {
  63. randomVolumeIndex -= freeSpace
  64. } else {
  65. if node.IsDataNode() && node.FreeSpace() > 0 {
  66. glog.V(0).Infoln("vid =", vid, " assigned to node =", node, ", freeSpace =", node.FreeSpace())
  67. return true, node.(*DataNode)
  68. }
  69. children := node.Children()
  70. newNodeList := NewNodeList(children, nl.except)
  71. return newNodeList.ReserveOneVolume(randomVolumeIndex, vid)
  72. }
  73. }
  74. return false, nil
  75. }