Improve runtime of segment distribution algorithm

This commit reduces the time taken to balance segments across a cluster. On 55K segments, it reduces the time taken for one run of the master from 100+ seconds to <1 second.

It includes the following implementation changes:

1. Removes calls to CalcuateInitialCosts() and CalculateNormalizedCosts(). They were both O(n^2) and weren't necessary.
2. Just tracks the best server instead of keeping a priorityQueue in chooseBestServer.
3. Fixes the reservoir segment sampler so that it is actually random.

And the following architectural changes:

1. Makes the segment balancer algorithm follow the strategy pattern.
2. Adds a random segment balancer should we wish to use that.
3. Adds a profiler to test the speed of the balancer.