picker.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package main
  2. import (
  3. "math/rand"
  4. "github.com/abh/geodns/Godeps/_workspace/src/github.com/miekg/dns"
  5. )
  6. func (label *Label) Picker(qtype uint16, max int) Records {
  7. if qtype == dns.TypeANY {
  8. var result []Record
  9. for rtype := range label.Records {
  10. rtypeRecords := label.Picker(rtype, max)
  11. tmpResult := make(Records, len(result)+len(rtypeRecords))
  12. copy(tmpResult, result)
  13. copy(tmpResult[len(result):], rtypeRecords)
  14. result = tmpResult
  15. }
  16. return result
  17. }
  18. if labelRR := label.Records[qtype]; labelRR != nil {
  19. // not "balanced", just return all
  20. if label.Weight[qtype] == 0 {
  21. return labelRR
  22. }
  23. rrCount := len(labelRR)
  24. if max > rrCount {
  25. max = rrCount
  26. }
  27. servers := make([]Record, len(labelRR))
  28. copy(servers, labelRR)
  29. result := make([]Record, max)
  30. sum := label.Weight[qtype]
  31. for si := 0; si < max; si++ {
  32. n := rand.Intn(sum + 1)
  33. s := 0
  34. for i := range servers {
  35. s += int(servers[i].Weight)
  36. if s >= n {
  37. sum -= servers[i].Weight
  38. result[si] = servers[i]
  39. // remove the server from the list
  40. servers = append(servers[:i], servers[i+1:]...)
  41. break
  42. }
  43. }
  44. }
  45. return result
  46. }
  47. return nil
  48. }