picker.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package main
  2. import (
  3. "github.com/abh/dns"
  4. "math/rand"
  5. )
  6. func (label *Label) Picker(qtype uint16, max int) Records {
  7. if qtype == dns.TypeANY {
  8. result := make([]Record, 0)
  9. for rtype := range label.Records {
  10. rtype_records := label.Picker(rtype, max)
  11. tmp_result := make(Records, len(result)+len(rtype_records))
  12. copy(tmp_result, result)
  13. copy(tmp_result[len(result):], rtype_records)
  14. result = tmp_result
  15. }
  16. return result
  17. }
  18. if label_rr := label.Records[qtype]; label_rr != nil {
  19. // not "balanced", just return all
  20. if label.Weight[qtype] == 0 {
  21. return label_rr
  22. }
  23. rr_count := len(label_rr)
  24. if max > rr_count {
  25. max = rr_count
  26. }
  27. servers := make([]Record, len(label_rr))
  28. copy(servers, label_rr)
  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. }