refactor: use memo-map instead of improvised CHashMap

This commit is contained in:
Mingwei Samuel 2024-07-11 16:59:11 -07:00
parent 689b422935
commit bfb687ef5b
5 changed files with 13 additions and 45 deletions

View file

@ -45,6 +45,7 @@ required-features = [ "__proxy" ]
[dependencies] [dependencies]
futures = "0.3" futures = "0.3"
log = "0.4" log = "0.4"
memo-map = "0.3"
num_enum = "0.5" num_enum = "0.5"
parking_lot = "0.12" parking_lot = "0.12"
reqwest = { version = "0.11", default-features = false, features = [ "gzip", "json" ] } reqwest = { version = "0.11", default-features = false, features = [ "gzip", "json" ] }

View file

@ -1,20 +1,19 @@
use std::future::Future; use std::future::Future;
use std::sync::Arc;
use memo_map::MemoMap;
use reqwest::{RequestBuilder, StatusCode}; use reqwest::{RequestBuilder, StatusCode};
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]
use tracing::{self as log, Instrument}; use tracing::{self as log, Instrument};
use super::{RateLimit, RateLimitType}; use super::{RateLimit, RateLimitType};
use crate::time::{sleep, Duration}; use crate::time::{sleep, Duration};
use crate::util::InsertOnlyCHashMap;
use crate::{ResponseInfo, Result, RiotApiConfig, RiotApiError}; use crate::{ResponseInfo, Result, RiotApiConfig, RiotApiError};
pub struct RegionalRequester { pub struct RegionalRequester {
/// The app rate limit. /// The app rate limit.
app_rate_limit: RateLimit, app_rate_limit: RateLimit,
/// Method rate limits. /// Method rate limits.
method_rate_limits: InsertOnlyCHashMap<&'static str, RateLimit>, method_rate_limits: MemoMap<&'static str, RateLimit>,
} }
impl RegionalRequester { impl RegionalRequester {
@ -27,12 +26,12 @@ impl RegionalRequester {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
app_rate_limit: RateLimit::new(RateLimitType::Application), app_rate_limit: RateLimit::new(RateLimitType::Application),
method_rate_limits: InsertOnlyCHashMap::new(), method_rate_limits: MemoMap::new(),
} }
} }
pub fn execute<'a>( pub fn execute<'a>(
self: Arc<Self>, &'a self,
config: &'a RiotApiConfig, config: &'a RiotApiConfig,
method_id: &'static str, method_id: &'static str,
request: RequestBuilder, request: RequestBuilder,
@ -40,12 +39,12 @@ impl RegionalRequester {
async move { async move {
let mut retries: u8 = 0; let mut retries: u8 = 0;
loop { loop {
let method_rate_limit: Arc<RateLimit> = self let method_rate_limit = self
.method_rate_limits .method_rate_limits
.get_or_insert_with(method_id, || RateLimit::new(RateLimitType::Method)); .get_or_insert(&method_id, || RateLimit::new(RateLimitType::Method));
// Rate limit. // Rate limit.
let rate_limit = RateLimit::acquire_both(&self.app_rate_limit, &method_rate_limit); let rate_limit = RateLimit::acquire_both(&self.app_rate_limit, method_rate_limit);
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]
let rate_limit = rate_limit.instrument(tracing::info_span!("rate_limit")); let rate_limit = rate_limit.instrument(tracing::info_span!("rate_limit"));
rate_limit.await; rate_limit.await;

View file

@ -1,12 +1,11 @@
use std::future::Future; use std::future::Future;
use std::sync::Arc;
use memo_map::MemoMap;
use reqwest::{Client, Method, RequestBuilder}; use reqwest::{Client, Method, RequestBuilder};
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]
use tracing as log; use tracing as log;
use crate::req::RegionalRequester; use crate::req::RegionalRequester;
use crate::util::InsertOnlyCHashMap;
use crate::{ResponseInfo, Result, RiotApiConfig, RiotApiError}; use crate::{ResponseInfo, Result, RiotApiConfig, RiotApiError};
/// For retrieving data from the Riot Games API. /// For retrieving data from the Riot Games API.
@ -46,7 +45,7 @@ pub struct RiotApi {
client: Client, client: Client,
/// Per-region requesters. /// Per-region requesters.
regional_requesters: InsertOnlyCHashMap<&'static str, RegionalRequester>, regional_requesters: MemoMap<&'static str, RegionalRequester>,
} }
impl RiotApi { impl RiotApi {
@ -62,7 +61,7 @@ impl RiotApi {
client: client_builder client: client_builder
.build() .build()
.expect("Failed to create client from builder."), .expect("Failed to create client from builder."),
regional_requesters: InsertOnlyCHashMap::new(), regional_requesters: MemoMap::new(),
} }
} }
@ -193,9 +192,9 @@ impl RiotApi {
} }
/// Get or create the RegionalRequester for the given region. /// Get or create the RegionalRequester for the given region.
fn regional_requester(&self, region_platform: &'static str) -> Arc<RegionalRequester> { fn regional_requester(&self, region_platform: &'static str) -> &RegionalRequester {
self.regional_requesters self.regional_requesters
.get_or_insert_with(region_platform, || { .get_or_insert(&region_platform, || {
log::debug!( log::debug!(
"Creating requester for region platform {}.", "Creating requester for region platform {}.",
region_platform region_platform

View file

@ -1,28 +0,0 @@
use std::collections::HashMap;
use std::hash::Hash;
use std::sync::Arc;
use parking_lot::Mutex;
pub struct InsertOnlyCHashMap<K: Hash + Eq, V> {
base: Mutex<HashMap<K, Arc<V>>>,
}
impl<K: Hash + Eq, V> InsertOnlyCHashMap<K, V> {
#[inline]
pub fn new() -> Self {
Self {
base: Mutex::new(HashMap::new()),
}
}
#[inline]
pub fn get_or_insert_with<F: FnOnce() -> V>(&self, key: K, default: F) -> Arc<V> {
Arc::clone(
self.base
.lock()
.entry(key)
.or_insert_with(|| Arc::new(default())),
)
}
}

View file

@ -1,5 +1,2 @@
mod insert_only_chashmap;
pub use insert_only_chashmap::InsertOnlyCHashMap;
mod notify; mod notify;
pub use notify::Notify; pub use notify::Notify;