16dbb5987Sopenharmony_ci// Copyright (c) 2023 Huawei Device Co., Ltd. 26dbb5987Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 36dbb5987Sopenharmony_ci// you may not use this file except in compliance with the License. 46dbb5987Sopenharmony_ci// You may obtain a copy of the License at 56dbb5987Sopenharmony_ci// 66dbb5987Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 76dbb5987Sopenharmony_ci// 86dbb5987Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 96dbb5987Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 106dbb5987Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 116dbb5987Sopenharmony_ci// See the License for the specific language governing permissions and 126dbb5987Sopenharmony_ci// limitations under the License. 136dbb5987Sopenharmony_ci 146dbb5987Sopenharmony_ci//! Connection pool implementation. 156dbb5987Sopenharmony_ci 166dbb5987Sopenharmony_ciuse std::collections::hash_map::Entry; 176dbb5987Sopenharmony_ciuse std::collections::HashMap; 186dbb5987Sopenharmony_ciuse std::hash::Hash; 196dbb5987Sopenharmony_ciuse std::sync::{Arc, Mutex}; 206dbb5987Sopenharmony_ci 216dbb5987Sopenharmony_ciuse ylong_http::request::uri::{Authority, Scheme}; 226dbb5987Sopenharmony_ci 236dbb5987Sopenharmony_cipub(crate) struct Pool<K, V> { 246dbb5987Sopenharmony_ci pool: Arc<Mutex<HashMap<K, V>>>, 256dbb5987Sopenharmony_ci} 266dbb5987Sopenharmony_ci 276dbb5987Sopenharmony_ciimpl<K, V> Pool<K, V> { 286dbb5987Sopenharmony_ci pub(crate) fn new() -> Self { 296dbb5987Sopenharmony_ci Self { 306dbb5987Sopenharmony_ci pool: Arc::new(Mutex::new(HashMap::new())), 316dbb5987Sopenharmony_ci } 326dbb5987Sopenharmony_ci } 336dbb5987Sopenharmony_ci} 346dbb5987Sopenharmony_ci 356dbb5987Sopenharmony_ciimpl<K: Eq + Hash, V: Clone> Pool<K, V> { 366dbb5987Sopenharmony_ci pub(crate) fn get<F>(&self, key: K, create_fn: F) -> V 376dbb5987Sopenharmony_ci where 386dbb5987Sopenharmony_ci F: FnOnce() -> V, 396dbb5987Sopenharmony_ci { 406dbb5987Sopenharmony_ci let mut inner = self.pool.lock().unwrap(); 416dbb5987Sopenharmony_ci match (*inner).entry(key) { 426dbb5987Sopenharmony_ci Entry::Occupied(conns) => conns.get().clone(), 436dbb5987Sopenharmony_ci Entry::Vacant(e) => e.insert(create_fn()).clone(), 446dbb5987Sopenharmony_ci } 456dbb5987Sopenharmony_ci } 466dbb5987Sopenharmony_ci} 476dbb5987Sopenharmony_ci 486dbb5987Sopenharmony_ci#[derive(Debug, PartialEq, Eq, Hash, Clone)] 496dbb5987Sopenharmony_cipub(crate) struct PoolKey(Scheme, Authority); 506dbb5987Sopenharmony_ci 516dbb5987Sopenharmony_ciimpl PoolKey { 526dbb5987Sopenharmony_ci pub(crate) fn new(scheme: Scheme, authority: Authority) -> Self { 536dbb5987Sopenharmony_ci Self(scheme, authority) 546dbb5987Sopenharmony_ci } 556dbb5987Sopenharmony_ci} 566dbb5987Sopenharmony_ci 576dbb5987Sopenharmony_ci#[cfg(test)] 586dbb5987Sopenharmony_cimod ut_pool { 596dbb5987Sopenharmony_ci use ylong_http::request::uri::Uri; 606dbb5987Sopenharmony_ci 616dbb5987Sopenharmony_ci use crate::pool::{Pool, PoolKey}; 626dbb5987Sopenharmony_ci 636dbb5987Sopenharmony_ci /// UT test cases for `Pool::get`. 646dbb5987Sopenharmony_ci /// 656dbb5987Sopenharmony_ci /// # Brief 666dbb5987Sopenharmony_ci /// 1. Creates a `pool` by calling `Pool::new()`. 676dbb5987Sopenharmony_ci /// 2. Uses `pool::get` to get connection. 686dbb5987Sopenharmony_ci /// 3. Checks if the results are correct. 696dbb5987Sopenharmony_ci #[test] 706dbb5987Sopenharmony_ci fn ut_pool_get() { 716dbb5987Sopenharmony_ci let uri = Uri::from_bytes(b"http://example1.com:80/foo?a=1").unwrap(); 726dbb5987Sopenharmony_ci let key = PoolKey::new( 736dbb5987Sopenharmony_ci uri.scheme().unwrap().clone(), 746dbb5987Sopenharmony_ci uri.authority().unwrap().clone(), 756dbb5987Sopenharmony_ci ); 766dbb5987Sopenharmony_ci let data = String::from("Data info"); 776dbb5987Sopenharmony_ci let consume_and_return_data = move || data; 786dbb5987Sopenharmony_ci let pool = Pool::new(); 796dbb5987Sopenharmony_ci let res = pool.get(key, consume_and_return_data); 806dbb5987Sopenharmony_ci assert_eq!(res, "Data info".to_string()); 816dbb5987Sopenharmony_ci } 826dbb5987Sopenharmony_ci} 83