1 个不稳定版本
0.1.0 | 2024年2月17日 |
---|
#159 在 缓存
52KB
1K SLoC
dir-cache
- 一个非常低成本的目录缓存
一种映射接口,可以将写入磁盘以某种可浏览的格式传播。
设计得简单易用易懂,效果并不特别出色。
性能
很糟糕。
性能第2部分
如果你懒散地写入磁盘,那么还可以。由于(可能取决于选项)每个映射操作至少对应一次磁盘操作,因此映射不适合高频率操作。
由于特定的值将产生一个磁盘表示形式,其大小严格大于原始内容大小。这意味着,dir-cache
在空间效率上并不高。
最后,文件系统的特定属性可能会使许多键的性能不佳(NTFS 就是一个例子)。
应使用场景
如果你有一个玩具项目,它正在调用外部 API,并且你只想简单地缓存某些请求的响应以减少对对方服务器的负载,或者类似的情况。
生产使用案例中你应该检查什么
如果你想在 Rust
中使用嵌入式 KV-store,请考虑 Sled。
如果你想在 Rust
之外使用嵌入式 KV-store,请考虑 RocksDB (github),RocksDB(docs.rs)。
如果你想在 Rust
之外使用嵌入式 SQL-store,请考虑 Sqlite(网站),同步 Rust crate(Rusqlite),异步 Rust crate (Sqlx)。
为什么
现在我们已经谈过了以上内容,我们可以深入了解为什么这个 crate 存在。
在我使用 Rust
探索公共 API 的过程中,我多次遇到了相同的问题
我正在探索一个 API,分析响应并编写代码,但我不希望每次迭代都发出新的网络请求,出于延迟和对他人的尊重。
在这些情况下,我通常会将响应保存到磁盘上,并在它们上执行离线分析。这可行,但很麻烦,它处理的是同样的老错误 std::fs::...
,确定合适的目录结构,最糟糕的是,需要编写两个独立的代码部分,一个是获取,另一个是分析。
目的
我想写这个
fn iterate_on_api_response_handling(dir_cache: &mut Cache) {
// This is preferably not dynamic
let req_key = Path::new("examplerequest");
// If this has run before then don't send an http request
let resp = dir_cache.get_or_insert_with(req_key, || {
let resp = http::client::get("https://example.com")?;
Ok(resp)
});
// Mess around with resp here
println!("Got length {}", resp.len());
}
有了上面的方法,获取和分析代码可以放在同一个地方。
功能
功能集保持相当简单,以支持上述用例。
类似于映射的接口
在 DirCache
上有 get
、get_or_insert_with
、insert
和 remove
方法。
可浏览的磁盘表示
值被写入到磁盘上的 cache-location/{key}/
,这使得检查保存的文件变得容易,在我的案例中通常是 json
文件。
响应的最大年龄
由于值可能会过时,这取决于迭代所需的时间,可以通过持续时间设置最大年龄,在此之后,值将被视为不存在。这意味着,第一次运行相同的 get_or_insert_with
会获取数据,直到最大年龄过去,每次返回缓存数据,最大年龄过去后获取新数据。
数据可选地以代数保存
覆盖相同的键可以选择将旧键向下移动一代,保留在磁盘上。
在某些情况下很有用,其中响应随时间变化,并且您希望保留历史记录。尽管这绝对是功能最不强大的一项。
可选压缩代数数据
我在处理一个非常稀疏的 json
数据集时发现这很有用,其中响应非常大,可以使用具有 lz4
压缩功能的 lz4
压缩来选择旧代。
注意事项
除了性能外,还有一点需要注意。
磁盘危险
键是 PathBufs
,并与 dir-cache
基目录连接。这打开了一个潘多拉盒子,最糟糕的是,不小心与绝对路径连接,请参阅 Path::join 的文档。
这可能导致具有破坏性的结果。
有一些缓解措施
- 如果右侧是绝对路径,则永远不会连接路径,并且路径不允许是除 Component::Normal 之外的内容。同时确保解析的组件组合长度与提供的
OsStr
长度合理(缓解意外有效路径)。 - 仅对特定文件名执行写入操作
dir-cache-generation-{manifest.txt | n}
。(降低意外覆盖重要文件的风险)。 - 仅对上述特定文件名以及空目录执行删除操作。
这涵盖了我想到的所有情况,但当然,不包括我想不到的情况。
如果使用此库,建议不要使用动态键。模糊测试仅在 Linux
上进行,因此在其他操作系统上使用动态键存在额外风险,尽管在 Linux
上进行模糊测试也不一定安全。
许可证
该项目在 MPL-2.0 许可证下授权。
依赖项
~195KB