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.

69 lines
1.5 KiB

  1. package topology
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "code.google.com/p/weed-fs/weed/storage"
  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(n int, min int) ([]Node, bool) {
  29. var list []Node
  30. for _, n := range nl.nodes {
  31. if n.FreeSpace() >= min {
  32. list = append(list, n)
  33. }
  34. }
  35. if n > len(list) {
  36. return nil, false
  37. }
  38. for i := n; i > 0; i-- {
  39. r := rand.Intn(i)
  40. t := list[r]
  41. list[r] = list[i-1]
  42. list[i-1] = t
  43. }
  44. return list[len(list)-n:], true
  45. }
  46. func (nl *NodeList) ReserveOneVolume(randomVolumeIndex int, vid storage.VolumeId) (bool, *DataNode) {
  47. for _, node := range nl.nodes {
  48. freeSpace := node.FreeSpace()
  49. if randomVolumeIndex >= freeSpace {
  50. randomVolumeIndex -= freeSpace
  51. } else {
  52. if node.IsDataNode() && node.FreeSpace() > 0 {
  53. fmt.Println("vid =", vid, " assigned to node =", node, ", freeSpace =", node.FreeSpace())
  54. return true, node.(*DataNode)
  55. }
  56. children := node.Children()
  57. newNodeList := NewNodeList(children, nl.except)
  58. return newNodeList.ReserveOneVolume(randomVolumeIndex, vid)
  59. }
  60. }
  61. return false, nil
  62. }