소스 검색

If records have weight, choose randomly based on weight

closes #3
Ask Bjørn Hansen 13 년 전
부모
커밋
7e73cbc77c
2개의 변경된 파일29개의 추가작업 그리고 6개의 파일을 삭제
  1. 28 5
      picker.go
  2. 1 1
      serve.go

+ 28 - 5
picker.go

@@ -2,6 +2,7 @@ package main
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"math/rand"
 )
 )
 
 
 func (label *Label) Picker(dnsType uint16, max int) Records {
 func (label *Label) Picker(dnsType uint16, max int) Records {
@@ -20,14 +21,36 @@ func (label *Label) Picker(dnsType uint16, max int) Records {
 			max = rr_count
 			max = rr_count
 		}
 		}
 
 
-		fmt.Println("Total weight", label.Weight[dnsType])
+		servers := make([]Record, len(label_rr))
+		copy(servers, label_rr)
+		result := make([]Record, max)
+		sum := label.Weight[dnsType]
+		sum2 := 0
+		for _, r := range servers {
+			sum2 += r.Weight
+		}
 
 
-		// TODO(ask) Pick random servers based on weight, not just the first 'max' entries
-		servers := label_rr[0:max]
+		for si := 0; si < max; si++ {
+			n := rand.Intn(sum + 1)
+			s := 0
+
+			for i := range servers {
+				s += int(servers[i].Weight)
+				if s >= n {
+					fmt.Println("Picked record", i, servers[i])
+					sum -= servers[i].Weight
+					result[si] = servers[i]
+
+					// remove the server from the list
+					servers = append(servers[:i], servers[i+1:]...)
+					break
+				}
+			}
+		}
 
 
-		fmt.Println("SERVERS", servers)
+		fmt.Println("SERVERS", result)
 
 
-		return servers
+		return result
 	}
 	}
 	return nil
 	return nil
 }
 }

+ 1 - 1
serve.go

@@ -24,7 +24,7 @@ func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {
 	logPrintf("[zone %s] incoming %s %s %d from %s\n", z.Origin, req.Question[0].Name,
 	logPrintf("[zone %s] incoming %s %s %d from %s\n", z.Origin, req.Question[0].Name,
 		dns.Rr_str[qtype], req.MsgHdr.Id, w.RemoteAddr())
 		dns.Rr_str[qtype], req.MsgHdr.Id, w.RemoteAddr())
 
 
-	fmt.Printf("ZONE DATA  %#v\n", z)
+	//fmt.Printf("ZONE DATA  %#v\n", z)
 
 
 	fmt.Println("Got request", req)
 	fmt.Println("Got request", req)