pingora_load_balancing/selection/
algorithms.rs

1// Copyright 2025 Cloudflare, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Implementation of algorithms for weighted selection
16//!
17//! All [std::hash::Hasher] + [Default] can be used directly as a selection algorithm.
18
19use super::*;
20use std::hash::Hasher;
21use std::sync::atomic::{AtomicUsize, Ordering};
22
23impl<H> SelectionAlgorithm for H
24where
25    H: Default + Hasher,
26{
27    fn new() -> Self {
28        H::default()
29    }
30    fn next(&self, key: &[u8]) -> u64 {
31        let mut hasher = H::default();
32        hasher.write(key);
33        hasher.finish()
34    }
35}
36
37/// Round Robin selection
38pub struct RoundRobin(AtomicUsize);
39
40impl SelectionAlgorithm for RoundRobin {
41    fn new() -> Self {
42        Self(AtomicUsize::new(0))
43    }
44    fn next(&self, _key: &[u8]) -> u64 {
45        self.0.fetch_add(1, Ordering::Relaxed) as u64
46    }
47}
48
49/// Random selection
50pub struct Random;
51
52impl SelectionAlgorithm for Random {
53    fn new() -> Self {
54        Self
55    }
56    fn next(&self, _key: &[u8]) -> u64 {
57        use rand::Rng;
58        let mut rng = rand::thread_rng();
59        rng.gen()
60    }
61}