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}