mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-03-31 17:55:36 +00:00
bench: add pareto plot util; use other shape in bench; refactor
This commit is contained in:
parent
5d462f808d
commit
ab457aaf82
7 changed files with 418 additions and 116 deletions
209
Cargo.lock
generated
209
Cargo.lock
generated
|
|
@ -27,12 +27,56 @@ dependencies = [
|
|||
"indexmap",
|
||||
"mio",
|
||||
"net2",
|
||||
"plotly",
|
||||
"quickcheck",
|
||||
"quickcheck_macros",
|
||||
"rand",
|
||||
"rand_distr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a1fb9e41eb366cbcd267da2094be5b7e62fdbca9f82091e7503e80f885050d"
|
||||
dependencies = [
|
||||
"askama_derive",
|
||||
"askama_escape",
|
||||
"askama_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_derive"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1012c270085fa35ece6a48a569544fde85b6d9ee41074c7b706cc912a03f939"
|
||||
dependencies = [
|
||||
"askama_shared",
|
||||
"nom",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_escape"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a577aeba5fec1aafb9f195d98cfcc38a78b588e4ebf9b15f62ca1c7aa33795a"
|
||||
|
||||
[[package]]
|
||||
name = "askama_shared"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ee517f4e33c27b129928e71d8a044d54c513e72e0b72ec5c4f5f1823e9de353"
|
||||
dependencies = [
|
||||
"askama_escape",
|
||||
"humansize",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
|
|
@ -119,6 +163,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humansize"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.3.2"
|
||||
|
|
@ -128,6 +178,12 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
|
@ -190,6 +246,16 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.3"
|
||||
|
|
@ -199,6 +265,83 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.12.0"
|
||||
|
|
@ -209,6 +352,20 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotly"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2734cda9d5551d513e535acacd6c0016c2631a55f1cdbf32bc1a0bd675db1ac"
|
||||
dependencies = [
|
||||
"askama",
|
||||
"num",
|
||||
"rand",
|
||||
"rand_distr",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.6"
|
||||
|
|
@ -346,6 +503,43 @@ version = "0.6.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.12"
|
||||
|
|
@ -378,12 +572,27 @@ dependencies = [
|
|||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
|
|
|
|||
|
|
@ -17,12 +17,16 @@ name = "bench_connect"
|
|||
[[bin]]
|
||||
name = "bench_announce_scrape"
|
||||
|
||||
[[bin]]
|
||||
name = "plot_pareto"
|
||||
|
||||
[dependencies]
|
||||
bittorrent_udp = { path = "../bittorrent_udp" }
|
||||
dashmap = "3"
|
||||
indexmap = "1"
|
||||
net2 = "0.2"
|
||||
rand_distr = "0.2"
|
||||
plotly = "0.4"
|
||||
|
||||
[dependencies.mio]
|
||||
version = "0.7"
|
||||
|
|
|
|||
|
|
@ -1,18 +1,23 @@
|
|||
//! Benchmark announce and scrape handlers
|
||||
|
||||
use std::time::{Duration, Instant};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use rand::{Rng, thread_rng, rngs::SmallRng, SeedableRng};
|
||||
use rand_distr::Pareto;
|
||||
|
||||
use aquatic::bench_utils::*;
|
||||
use aquatic::common::*;
|
||||
use aquatic::handler::*;
|
||||
|
||||
|
||||
const PARETO_SHAPE: f64 = 3.0;
|
||||
const ANNOUNCE_ITERATIONS: usize = 500_000;
|
||||
const SCRAPE_ITERATIONS: usize = 500_000;
|
||||
const PARETO_SHAPE: f64 = 0.1;
|
||||
const NUM_INFO_HASHES: usize = 10_000;
|
||||
|
||||
const ANNOUNCE_REQUESTS: usize = 100_000;
|
||||
|
||||
const SCRAPE_REQUESTS: usize = 1_000_000;
|
||||
const SCRAPE_NUM_HASHES: usize = 10;
|
||||
const NUM_INFO_HASHES: usize = 500_000;
|
||||
|
||||
|
||||
fn main(){
|
||||
|
|
@ -20,115 +25,145 @@ fn main(){
|
|||
let info_hashes = create_info_hashes(&mut rng);
|
||||
let state = State::new();
|
||||
|
||||
{
|
||||
println!("benchmark: handle_announce_requests\n");
|
||||
|
||||
println!("generating data..");
|
||||
|
||||
let mut responses = Vec::with_capacity(ANNOUNCE_ITERATIONS);
|
||||
|
||||
let mut announce_requests = create_announce_requests(&mut rng, &info_hashes);
|
||||
|
||||
let time = Time(Instant::now());
|
||||
|
||||
for (request, src) in announce_requests.iter() {
|
||||
let key = ConnectionKey {
|
||||
connection_id: request.connection_id,
|
||||
socket_addr: *src,
|
||||
};
|
||||
|
||||
state.connections.insert(key, time);
|
||||
}
|
||||
|
||||
let announce_requests = announce_requests.drain(..);
|
||||
|
||||
::std::thread::sleep(Duration::from_secs(1));
|
||||
|
||||
let now = Instant::now();
|
||||
|
||||
println!("running benchmark..");
|
||||
|
||||
handle_announce_requests(
|
||||
&state,
|
||||
&mut responses,
|
||||
announce_requests,
|
||||
);
|
||||
|
||||
let duration = Instant::now() - now;
|
||||
|
||||
println!("\nrequests/second: {:.2}", ANNOUNCE_ITERATIONS as f64 / (duration.as_millis() as f64 / 1000.0));
|
||||
println!("time per request: {:.2}ns", duration.as_nanos() as f64 / ANNOUNCE_ITERATIONS as f64);
|
||||
|
||||
let mut total_num_peers = 0.0f64;
|
||||
let mut max_num_peers = 0.0f64;
|
||||
|
||||
for (response, _src) in responses.drain(..) {
|
||||
if let Response::Announce(response) = response {
|
||||
let n = response.peers.len() as f64;
|
||||
|
||||
total_num_peers += n;
|
||||
max_num_peers = max_num_peers.max(n);
|
||||
}
|
||||
}
|
||||
|
||||
println!("avg num peers returned: {:.2}", total_num_peers / ANNOUNCE_ITERATIONS as f64);
|
||||
println!("max num peers returned: {:.2}", max_num_peers);
|
||||
}
|
||||
bench_announce(&mut rng, &state, &info_hashes);
|
||||
|
||||
state.connections.clear();
|
||||
|
||||
{
|
||||
println!("\n\nbenchmark: handle_scrape_requests\n");
|
||||
println!("\n");
|
||||
|
||||
println!("generating data..");
|
||||
::std::thread::sleep(Duration::from_secs(1));
|
||||
|
||||
let mut responses = Vec::with_capacity(SCRAPE_ITERATIONS);
|
||||
bench_scrape(&mut rng, &state, &info_hashes);
|
||||
}
|
||||
|
||||
let mut scrape_requests = create_scrape_requests(&mut rng, &info_hashes);
|
||||
|
||||
let time = Time(Instant::now());
|
||||
fn bench_announce(
|
||||
rng: &mut impl Rng,
|
||||
state: &State,
|
||||
info_hashes: &Vec<InfoHash>
|
||||
){
|
||||
println!("# benchmark: handle_announce_requests\n");
|
||||
|
||||
for (request, src) in scrape_requests.iter() {
|
||||
let key = ConnectionKey {
|
||||
connection_id: request.connection_id,
|
||||
socket_addr: *src,
|
||||
};
|
||||
println!("generating data..");
|
||||
|
||||
state.connections.insert(key, time);
|
||||
}
|
||||
let mut responses = Vec::with_capacity(ANNOUNCE_REQUESTS);
|
||||
|
||||
let scrape_requests = scrape_requests.drain(..);
|
||||
let mut announce_requests = create_announce_requests(rng, &info_hashes);
|
||||
|
||||
::std::thread::sleep(Duration::from_secs(1));
|
||||
let time = Time(Instant::now());
|
||||
|
||||
let now = Instant::now();
|
||||
for (request, src) in announce_requests.iter() {
|
||||
let key = ConnectionKey {
|
||||
connection_id: request.connection_id,
|
||||
socket_addr: *src,
|
||||
};
|
||||
|
||||
println!("running benchmark..");
|
||||
|
||||
handle_scrape_requests(
|
||||
&state,
|
||||
&mut responses,
|
||||
scrape_requests,
|
||||
);
|
||||
|
||||
let duration = Instant::now() - now;
|
||||
|
||||
println!("\nrequests/second: {:.2}", SCRAPE_ITERATIONS as f64 / (duration.as_millis() as f64 / 1000.0));
|
||||
println!("time per request: {:.2}ns", duration.as_nanos() as f64 / SCRAPE_ITERATIONS as f64);
|
||||
|
||||
let mut total_num_peers = 0.0f64;
|
||||
|
||||
for (response, _src) in responses.drain(..){
|
||||
if let Response::Scrape(response) = response {
|
||||
for stats in response.torrent_stats {
|
||||
total_num_peers += f64::from(stats.seeders.0);
|
||||
total_num_peers += f64::from(stats.leechers.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("avg num peers reported: {:.2}", total_num_peers / (SCRAPE_ITERATIONS as f64 * SCRAPE_NUM_HASHES as f64));
|
||||
state.connections.insert(key, time);
|
||||
}
|
||||
|
||||
let announce_requests = announce_requests.drain(..);
|
||||
|
||||
::std::thread::sleep(Duration::from_secs(1));
|
||||
|
||||
let now = Instant::now();
|
||||
|
||||
println!("running benchmark..");
|
||||
|
||||
handle_announce_requests(
|
||||
&state,
|
||||
&mut responses,
|
||||
announce_requests,
|
||||
);
|
||||
|
||||
let duration = Instant::now() - now;
|
||||
|
||||
println!("\nrequests/second: {:.2}", ANNOUNCE_REQUESTS as f64 / (duration.as_millis() as f64 / 1000.0));
|
||||
println!("time per request: {:.2}ns", duration.as_nanos() as f64 / ANNOUNCE_REQUESTS as f64);
|
||||
|
||||
let mut total_num_peers = 0.0f64;
|
||||
let mut max_num_peers = 0.0f64;
|
||||
let mut num_responses: usize = 0;
|
||||
|
||||
for (response, _src) in responses.drain(..) {
|
||||
if let Response::Announce(response) = response {
|
||||
let n = response.peers.len() as f64;
|
||||
|
||||
total_num_peers += n;
|
||||
max_num_peers = max_num_peers.max(n);
|
||||
num_responses += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if num_responses != ANNOUNCE_REQUESTS {
|
||||
println!("ERROR: only {} responses received", num_responses);
|
||||
}
|
||||
|
||||
println!("avg num peers returned: {:.2}", total_num_peers / ANNOUNCE_REQUESTS as f64);
|
||||
println!("max num peers returned: {:.2}", max_num_peers);
|
||||
}
|
||||
|
||||
|
||||
fn bench_scrape(
|
||||
rng: &mut impl Rng,
|
||||
state: &State,
|
||||
info_hashes: &Vec<InfoHash>
|
||||
){
|
||||
println!("# benchmark: handle_scrape_requests\n");
|
||||
println!("generating data..");
|
||||
|
||||
let mut responses = Vec::with_capacity(SCRAPE_REQUESTS);
|
||||
|
||||
let mut scrape_requests = create_scrape_requests(rng, &info_hashes);
|
||||
|
||||
let time = Time(Instant::now());
|
||||
|
||||
for (request, src) in scrape_requests.iter() {
|
||||
let key = ConnectionKey {
|
||||
connection_id: request.connection_id,
|
||||
socket_addr: *src,
|
||||
};
|
||||
|
||||
state.connections.insert(key, time);
|
||||
}
|
||||
|
||||
let scrape_requests = scrape_requests.drain(..);
|
||||
|
||||
::std::thread::sleep(Duration::from_secs(1));
|
||||
|
||||
let now = Instant::now();
|
||||
|
||||
println!("running benchmark..");
|
||||
|
||||
handle_scrape_requests(
|
||||
&state,
|
||||
&mut responses,
|
||||
scrape_requests,
|
||||
);
|
||||
|
||||
let duration = Instant::now() - now;
|
||||
|
||||
println!("\nrequests/second: {:.2}", SCRAPE_REQUESTS as f64 / (duration.as_millis() as f64 / 1000.0));
|
||||
println!("time per request: {:.2}ns", duration.as_nanos() as f64 / SCRAPE_REQUESTS as f64);
|
||||
|
||||
let mut total_num_peers = 0.0f64;
|
||||
let mut num_responses: usize = 0;
|
||||
|
||||
for (response, _src) in responses.drain(..){
|
||||
if let Response::Scrape(response) = response {
|
||||
for stats in response.torrent_stats {
|
||||
total_num_peers += f64::from(stats.seeders.0);
|
||||
total_num_peers += f64::from(stats.leechers.0);
|
||||
}
|
||||
|
||||
num_responses += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if num_responses != SCRAPE_REQUESTS {
|
||||
println!("ERROR: only {} responses received", num_responses);
|
||||
}
|
||||
|
||||
println!("avg num peers reported: {:.2}", total_num_peers / (SCRAPE_REQUESTS as f64 * SCRAPE_NUM_HASHES as f64));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -142,7 +177,7 @@ fn create_announce_requests(
|
|||
|
||||
let mut requests = Vec::new();
|
||||
|
||||
for _ in 0..ANNOUNCE_ITERATIONS {
|
||||
for _ in 0..ANNOUNCE_REQUESTS {
|
||||
let info_hash_index = pareto_usize(rng, pareto, max_index);
|
||||
|
||||
let request = AnnounceRequest {
|
||||
|
|
@ -169,7 +204,6 @@ fn create_announce_requests(
|
|||
}
|
||||
|
||||
|
||||
|
||||
fn create_scrape_requests(
|
||||
rng: &mut impl Rng,
|
||||
info_hashes: &Vec<InfoHash>
|
||||
|
|
@ -180,7 +214,7 @@ fn create_scrape_requests(
|
|||
|
||||
let mut requests = Vec::new();
|
||||
|
||||
for _ in 0..SCRAPE_ITERATIONS {
|
||||
for _ in 0..SCRAPE_REQUESTS {
|
||||
let mut request_info_hashes = Vec::new();
|
||||
|
||||
for _ in 0..SCRAPE_NUM_HASHES {
|
||||
|
|
@ -211,16 +245,4 @@ fn create_info_hashes(rng: &mut impl Rng) -> Vec<InfoHash> {
|
|||
}
|
||||
|
||||
info_hashes
|
||||
}
|
||||
|
||||
|
||||
fn pareto_usize(
|
||||
rng: &mut impl Rng,
|
||||
pareto: Pareto<f64>,
|
||||
max: usize,
|
||||
) -> usize {
|
||||
let p: f64 = rng.sample(pareto);
|
||||
let p = (p.min(101.0f64) - 1.0) / 100.0;
|
||||
|
||||
(p * max as f64) as usize
|
||||
}
|
||||
44
aquatic/src/bin/plot_pareto.rs
Normal file
44
aquatic/src/bin/plot_pareto.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
use plotly::{Plot, Scatter, Layout};
|
||||
use plotly::common::Title;
|
||||
use plotly::layout::Axis;
|
||||
use rand::{thread_rng, rngs::SmallRng, SeedableRng};
|
||||
use rand_distr::Pareto;
|
||||
|
||||
use aquatic::bench_utils::pareto_usize;
|
||||
|
||||
|
||||
fn main(){
|
||||
let mut plot = Plot::new();
|
||||
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
|
||||
|
||||
const LEN: usize = 1_000;
|
||||
const MAX_VAL: usize = LEN - 1;
|
||||
|
||||
for pareto_shape in [0.1, 0.2, 0.3, 0.4, 0.5].iter() {
|
||||
let pareto = Pareto::new(1.0, *pareto_shape).unwrap();
|
||||
|
||||
let mut y_axis = [0; LEN];
|
||||
|
||||
for _ in 1..1_000_000 {
|
||||
let index = pareto_usize(&mut rng, pareto, MAX_VAL);
|
||||
|
||||
y_axis[index] += 1;
|
||||
}
|
||||
|
||||
let x_axis: Vec<usize> = (0..MAX_VAL).into_iter().collect();
|
||||
|
||||
let trace = Scatter::new(x_axis, y_axis.to_vec())
|
||||
.name(&format!("pareto shape = {}", pareto_shape));
|
||||
|
||||
plot.add_trace(trace);
|
||||
}
|
||||
|
||||
let layout = Layout::new()
|
||||
.title(Title::new("Pareto distribution"))
|
||||
.xaxis(Axis::new().title(Title::new("Info hash index")))
|
||||
.yaxis(Axis::new().title(Title::new("Num requests")));
|
||||
|
||||
plot.set_layout(layout);
|
||||
|
||||
plot.show();
|
||||
}
|
||||
14
aquatic/src/lib/bench_utils.rs
Normal file
14
aquatic/src/lib/bench_utils.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use rand::Rng;
|
||||
use rand_distr::Pareto;
|
||||
|
||||
|
||||
pub fn pareto_usize(
|
||||
rng: &mut impl Rng,
|
||||
pareto: Pareto<f64>,
|
||||
max: usize,
|
||||
) -> usize {
|
||||
let p: f64 = rng.sample(pareto);
|
||||
let p = (p.min(101.0f64) - 1.0) / 100.0;
|
||||
|
||||
(p * max as f64) as usize
|
||||
}
|
||||
|
|
@ -118,7 +118,15 @@ pub fn handle_scrape_requests(
|
|||
){
|
||||
let empty_stats = create_torrent_scrape_statistics(0, 0);
|
||||
|
||||
responses.extend(requests.map(|(request, src)| {
|
||||
responses.extend(requests.filter_map(|(request, src)| {
|
||||
let connection_key = ConnectionKey {
|
||||
connection_id: request.connection_id,
|
||||
socket_addr: src,
|
||||
};
|
||||
|
||||
if !state.connections.contains_key(&connection_key){
|
||||
return None;
|
||||
}
|
||||
let mut stats: Vec<TorrentScrapeStatistics> = Vec::with_capacity(256);
|
||||
|
||||
for info_hash in request.info_hashes.iter() {
|
||||
|
|
@ -137,7 +145,7 @@ pub fn handle_scrape_requests(
|
|||
torrent_stats: stats,
|
||||
});
|
||||
|
||||
(response, src)
|
||||
Some((response, src))
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::time::Duration;
|
||||
|
||||
pub mod bench_utils;
|
||||
pub mod common;
|
||||
pub mod handler;
|
||||
pub mod network;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue