summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/contrib/srvrec.cc31
-rw-r--r--apt-pkg/contrib/srvrec.h5
2 files changed, 34 insertions, 2 deletions
diff --git a/apt-pkg/contrib/srvrec.cc b/apt-pkg/contrib/srvrec.cc
index c473192fc..70247c2ae 100644
--- a/apt-pkg/contrib/srvrec.cc
+++ b/apt-pkg/contrib/srvrec.cc
@@ -105,10 +105,37 @@ bool GetSrvRecords(std::string name, std::vector<SrvRec> &Result)
Result.push_back(rec);
}
- // sort them
+ // implement load balancing as specified in RFC-2782
+
+ // sort them by priority
std::stable_sort(Result.begin(), Result.end());
- // FIXME: implement weight selection as specified in RFC-2782
+ // assign random number ranges
+ int prev_weight = 0;
+ int prev_priority = 0;
+ for(std::vector<SrvRec>::iterator I = Result.begin();
+ I != Result.end(); ++I)
+ {
+ if(prev_priority != I->priority)
+ prev_weight = 0;
+ I->random_number_range_start = prev_weight;
+ I->random_number_range_end = prev_weight + I->weight;
+ prev_weight = I->random_number_range_end;
+ prev_priority = I->priority;
+ }
+
+ // go over the code in reverse order and note the max random range
+ int max = 0;
+ prev_priority = 0;
+ for(std::vector<SrvRec>::iterator I = Result.end();
+ I != Result.begin(); --I)
+ {
+ if(prev_priority != I->priority)
+ max = I->random_number_range_end;
+ I->random_number_range_max = max;
+ }
+
+ // now shuffle
return true;
}
diff --git a/apt-pkg/contrib/srvrec.h b/apt-pkg/contrib/srvrec.h
index fd71e697f..79b318b48 100644
--- a/apt-pkg/contrib/srvrec.h
+++ b/apt-pkg/contrib/srvrec.h
@@ -21,6 +21,11 @@ class SrvRec
u_int16_t weight;
u_int16_t port;
+ // each server is assigned a interval [start, end] in the space of [0, max]
+ int random_number_range_start;
+ int random_number_range_end;
+ int random_number_range_max;
+
bool operator<(SrvRec const &other) const {
return this->priority < other.priority;
}