Rust在写库时实现缓存

Rust在写库时实现缓存

依赖

在写库时,实现一个缓存请求,需要用到全局变量,所以我们可以添加cratelazy_static

Cargo.toml添加以下依赖

[dependencies]
chrono = "0.4.31"
lazy_static = "1.4.0"
reqwest = { version = "0.11.23", features = ["blocking", "json"] }
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0.108"

代码实现

use std::{sync::Mutex, collections::HashMap};

use chrono::{DateTime, Utc};
use lazy_static::lazy_static;
use serde_json::Value;

lazy_static! {
    static ref REQUESTS_RESPONSE_CACHE: Mutex<HashMap<String, RequestsResponseCache>> =
        Mutex::new(HashMap::new());
}

pub struct RequestsResponseCache {
    pub response: Value,
    pub datetime: DateTime<Utc>,
}

pub fn get_requests_response_cache(url: &str) -> Result<Value, reqwest::Error> {
    let mut cache = REQUESTS_RESPONSE_CACHE.lock().unwrap();
    if let Some(cache_entry) = cache.get(url) {
        let elapsed = Utc::now() - cache_entry.datetime;
        if elapsed.num_seconds() > 3600 {
            let response: Value = reqwest::blocking::get(url)?.json()?;
            let res = response.clone();
            let cache_entry = RequestsResponseCache {
                response,
                datetime: Utc::now(),
            };
            cache.insert(url.to_string(), cache_entry);
            return Ok(res);
        }
        return Ok(cache_entry.response.clone);
    }

    let response: Value = reqwest::blocking::get(url)?.json()?;
    let res = response.clone();
    let cache_entry = RequestsResponseCache {
        response,
        datetime: Utc::now(),
    };
    cache.insert(url.to_string(), cache_entry);
    Ok(res)
}

使用了 lazy_static 宏创建了一个静态的全局变量 REQUESTS_RESPONSE_CACHE,这个全局变量是一个 Mutex 包裹的 HashMap,用来存储请求的响应缓存。这个缓存是线程安全的,因为被 Mutex 包裹了起来,这样就可以在多个线程中安全地访问和修改这个缓存。

接着定义了一个 RequestsResponseCache 结构体,用来表示缓存中的一个条目,其中包含了响应数据 response 和缓存的时间戳 datetime

然后定义了一个 get_requests_response_cache 函数,用来从缓存中获取请求的响应。它首先尝试从缓存中获取指定 url 的响应数据,如果缓存中有对应的条目,并且距离上次缓存的时间超过了 3600 秒(1 小时),则重新发起请求并更新缓存,然后返回响应数据。如果缓存中没有对应的条目,或者缓存的时间未超过 3600 秒,则直接返回响应数据。

这样就提供了一个简单的请求响应的缓存功能,能够在需要时缓存请求的响应数据,并在一定时间内有效,从而减少对远程服务的重复请求,提高程序性能。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个用 Rust 语言实现透视变形的函数的示例代码: ```rust use image::{ImageBuffer, Rgb}; fn perspective_transform(src: &ImageBuffer<Rgb<u8>, Vec<u8>>, tl: (f32, f32), tr: (f32, f32), bl: (f32, f32), br: (f32, f32)) -> ImageBuffer<Rgb<u8>, Vec<u8>> { let (width, height) = src.dimensions(); let mut output = ImageBuffer::new(width, height); let a = tl.0 * (tr.1 - br.1) + tr.0 * (br.1 - tl.1) + br.0 * (tl.1 - tr.1); let b = tl.1 * (tr.0 - br.0) + tr.1 * (br.0 - tl.0) + br.1 * (tl.0 - tr.0); let c = tl.0 * (tr.1 * br.0 - br.1 * tr.0) + tr.0 * (br.1 * tl.0 - tl.1 * br.0) + br.0 * (tl.1 * tr.0 - tr.1 * tl.0); let d = bl.0 * (tr.1 - br.1) + br.0 * (bl.1 - tr.1) + tr.0 * (br.1 - bl.1); let e = bl.1 * (tr.0 - br.0) + br.1 * (bl.0 - tr.0) + tr.1 * (br.0 - bl.0); let f = bl.0 * (tr.1 * br.0 - br.1 * tr.0) + br.0 * (bl.1 * tr.0 - tr.1 * bl.0) + tr.0 * (br.1 * bl.1 - bl.1 * br.1); let g = tl.0 * (bl.1 - br.1) + bl.0 * (tl.1 - br.1) + br.0 * (bl.1 - tl.1); let h = tl.1 * (bl.0 - br.0) + bl.1 * (tl.0 - br.0) + br.1 * (bl.0 - tl.0); let i = tl.0 * (bl.1 * br.0 - br.1 * bl.0) + bl.0 * (tl.1 * br.0 - br.1 * tl.0) + br.0 * (bl.1 * tl.0 - tl.1 * bl.0); for y in 0..height { for x in 0..width { let w = a * x as f32 + b * y as f32 + c; let xp = ((d * x as f32) + (e * y as f32) + f) / w; let yp = ((g * x as f32) + (h * y as f32) + i) / w; if xp >= 0.0 && xp < width as f32 && yp >= 0.0 && yp < height as f32 { let pixel = src.get_pixel(xp as u32, yp as u32); output.put_pixel(x, y, *pixel); } } } output } ``` 这个函数接受一个 RGB 图像和四个点的坐标,返回一个透视变形后的图像。具体实现中,使用了透视变换的矩阵表达式,并遍历图像的每个像素,计算出它在透视变形后的位置,然后将原图像对应位置的像素值复制到输出图像中。注意,我们需要对计算出的像素位置进行边界检查,以确保它们在图像范围内。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值