From 7ce5be60f7626030a2e19cab3e712348057bcb69 Mon Sep 17 00:00:00 2001
From: Croxx
Date: Sat, 14 Sep 2024 14:27:48 +0800
Subject: [PATCH 01/53] doc: remove details tag in change log for better
searching (#711)
Signed-off-by: MrCroxx
---
CHANGELOG.md | 243 ++++++++++++++++++---------------------------------
1 file changed, 84 insertions(+), 159 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17b3fa6b..af62fc78 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
## 2024-09-12
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.11.2 |
@@ -9,8 +11,6 @@
| foyer-storage | 0.10.2 |
| foyer-bench | 0.3.2 |
-
-
### Changes
- Support windows (for `foyer` only).
@@ -20,10 +20,10 @@
- Use bytes size for `foyer-bench`.
- Fix install deps script.
-
-
## 2024-08-31
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.11.1 |
@@ -33,8 +33,6 @@
| foyer-storage | 0.10.1 |
| foyer-bench | 0.3.1 |
-
-
### Changes
- Add metrics for serde.
@@ -43,10 +41,10 @@
- Implement `Default` for `TokioRuntimeConfig`.
- Fix typos and format code with unstable features.
-
-
## 2024-08-21
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.11.0 |
@@ -56,8 +54,6 @@
| foyer-storage | 0.10.0 |
| foyer-bench | 0.3.0 |
-
-
### Changes
- Support disk cache on raw block device.
@@ -69,42 +65,38 @@
- Update `foyer-bench` with more fine-grained configurations.
- Fix panics with `None` recover mode.
-
-
## 2024-08-15
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.10.4 |
| foyer-storage | 0.9.3 |
| foyer-bench | 0.2.3 |
-
-
### Changes
- Support serde for recover mode configuration.
-
-
## 2024-08-14
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.10.2 |
| foyer-storage | 0.9.2 |
| foyer-bench | 0.2.2 |
-
-
### Changes
- Fix panic with "none" recovery mode.
-
-
## 2024-07-08
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.10.1 |
@@ -114,16 +106,14 @@
| foyer-storage | 0.9.1 |
| foyer-bench | 0.2.1 |
-
-
### Changes
- Refine write model, make flush buffer threshold configurable to mitigate memory usage spike and OOM.
-
-
## 2024-07-02
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.10.0 |
@@ -133,37 +123,33 @@
| foyer-storage | 0.9.0 |
| foyer-bench | 0.2.0 |
-
-
### Changes
- Introduce tail-based tracing framework with [minitrace](https://github.com/tikv/minitrace-rust). [Tail-based Tracing Example](https://github.com/foyer-rs/foyer/tree/main/examples/tail_based_tracing.rs).
- Fix `fetch()` disk cache refill on in-memory cache miss.
- Publish *foyer* logo!
-
-
-
+
## 2024-06-14
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.9.4 |
| foyer-storage | 0.8.5 |
| foyer-bench | 0.1.4 |
-
-
### Changes
- Fix phantom entries after foyer storage recovery. [#560](https://github.com/foyer-rs/foyer/pull/560)
- Fix hybrid cache hit metrics with `fetch()` interface. [#563](https://github.com/foyer-rs/foyer/pull/563)
-
-
## 2024-06-05
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.9.3 |
@@ -173,31 +159,27 @@
| foyer-storage | 0.8.4 |
| foyer-bench | 0.1.3 |
-
-
### Changes
- Hybrid cache `fetch()` use the dedicated runtime by default if enabled.
- Separate `fetch()` and `fetch_with_runtime()` interface for in-memory cache.
-
-
## 2024-06-04
+### Releases
+
| crate | version |
| - | - |
| foyer-storage | 0.8.3 |
-
-
### Changes
- Fix "invalid argument (code: 22)" on target aarch64.
-
-
## 2024-06-03
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.9.2 |
@@ -207,16 +189,14 @@
| foyer-storage | 0.8.2 |
| foyer-bench | 0.1.2 |
-
-
### Changes
- Support customized cache event listener.
-
-
## 2024-05-31
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.9.1 |
@@ -226,8 +206,6 @@
| foyer-storage | 0.8.1 |
| foyer-bench | 0.1.1 |
-
-
### Changes
- Fix "attempt to subtract with overflow" panic after cloning cache entry. [#543](https://github.com/foyer-rs/foyer/issues/543).
@@ -240,10 +218,10 @@
- Remove `pop()` related interface from the in-memory cache.
- Refine intrusive data structure implementation.
-
-
## 2024-05-27
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.9.0 |
@@ -253,8 +231,6 @@
| foyer-storage | 0.8.0 |
| foyer-bench | 0.1.0 |
-
-
### Changes
- Refine the storage engine to reduce the overhead and boost the performance.
@@ -267,10 +243,10 @@
- Reduce unnecessary dependencies.
- More details: [foyer - Development Roadmap](https://github.com/orgs/foyer-rs/projects/2).
-
-
## 2024-04-28
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.9 |
@@ -279,17 +255,15 @@
| foyer-storage | 0.7.6 |
| foyer-storage-bench | 0.7.5 |
-
-
### Changes
- feat: Add config to control the recover mode.
- feat: Add config to enable/disable direct i/o. (Enabled by default for large entries optimization.)
-
-
## 2024-04-28
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.8 |
@@ -297,60 +271,52 @@
| foyer-storage | 0.7.5 |
| foyer-storage-bench | 0.7.4 |
-
-
### Changes
- feat: Impl `Debug` for `HybridCache`.
- feat: Impl `serde`, `Default` for eviction configs.
- refactor: Add internal trait `EvictionConfig` to bound eviction algorithm configs.
-
-
## 2024-04-27
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.7 |
-
-
### Changes
- Make `HybridCache` clonable.
-
-
## 2024-04-27
+### Releases
+
| crate | version |
| - | - |
| foyer-memory | 0.3.4 |
-
-
### Changes
- Fix S3FIFO ghost queue.
-
-
## 2024-04-26
+### Releases
+
| crate | version |
| - | - |
| foyer-storage | 0.7.4 |
-
-
### Changes
- Fix `FsDeviceBuilder` on a non-exist directory without capacity given.
-
-
## 2024-04-26
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.6 |
@@ -360,23 +326,19 @@
| foyer-storage | 0.7.3 |
| foyer-storage-bench | 0.7.3 |
-
-
### Changes
- Remove unused dependencies.
- Remove hakari workspace hack.
-
-
## 2024-04-26
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.5 |
-
-
### Changes
- Expose `EntryState`, `HybridEntry`.
@@ -385,38 +347,34 @@
- Re-export `ahash::RandomState`.
- Loose `entry()` args trait bounds.
-
-
## 2024-04-25
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.4 |
-
-
### Changes
- Expose `HybridCacheEntry`.
-
-
## 2024-04-25
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.3 |
-
-
### Changes
- Expose `Key`, `Value`, `StorageKey`, `StorageValue` traits.
-
-
## 2024-04-24
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.2 |
@@ -427,16 +385,14 @@
| foyer-storage-bench | 0.7.2 |
| foyer-workspace-hack | 0.5.2 |
-
-
### Changes
- Add `nightly` feature to make it compatible with night toolchain.
-
-
## 2024-04-24
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.1 |
@@ -447,18 +403,16 @@
| foyer-storage-bench | 0.7.1 |
| foyer-workspace-hack | 0.5.1 |
-
-
### Changes
- Add `with_flush` to enable flush for each io.
- Loose MSRV to 1.76 .
- Flush the device on store close.
-
-
## 2024-04-23
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.8.0 |
@@ -469,8 +423,6 @@
| foyer-storage-bench | 0.7.0 |
| foyer-workspace-hack | 0.5.0 |
-
-
### Changes
- Combine in-memory cache and disk cache into `HybridCache`.
@@ -482,10 +434,10 @@
- Fix S3FIFO eviction bugs.
- Add more examples.
-
-
## 2024-04-11
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.7.0 |
@@ -496,90 +448,78 @@
| foyer-storage-bench | 0.6.0 |
| foyer-workspace-hack | 0.4.0 |
-
-
### Changes
- Make `foyer` compatible with rust stable toolchain (MSRV = 1.77.2). 🎉
-
-
## 2024-04-09
+### Releases
+
| crate | version |
| - | - |
| foyer-storage | 0.5.1 |
| foyer-memory | 0.1.4 |
-
-
### Changes
- fix: Fix panics on `state()` for s3fifo entry.
- fix: Enable `offset_of` feature for `foyer-storage`.
-
-
## 2024-04-08
+### Releases
+
| crate | version |
| - | - |
| foyer-intrusive | 0.3.1 |
| foyer-memory | 0.1.3 |
-
-
### Changes
- feat: Introduce s3fifo to `foyer-memory`.
- fix: Fix doctest for `foyer-intrusive`.
-
-
## 2024-03-21
+### Releases
+
| crate | version |
| - | - |
| foyer-memory | 0.1.2 |
-
-
### Changes
- fix: `foyer-memory` export `DefaultCacheEventListener`.
-
-
## 2024-03-14
+### Releases
+
| crate | version |
| - | - |
| foyer-memory | 0.1.1 |
-
-
### Changes
- Make eviction config clonable.
-
-
## 2024-03-13
+### Releases
+
| crate | version |
| - | - |
| foyer-storage-bench | 0.5.1 |
-
-
### Changes
- Fix `foyer-storage-bench` build with `trace` feature.
-
-
## 2024-03-12
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.6.0 |
@@ -590,17 +530,15 @@
| foyer-storage-bench | 0.5.0 |
| foyer-workspace-hack | 0.3.0 |
-
-
### Changes
- Release foyer in-memory cache as crate `foyer-memory`.
- Bump other components with changes.
-
-
## 2023-12-28
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.5.0 |
@@ -610,21 +548,16 @@
| foyer-storage-bench | 0.4.0 |
| foyer-workspace-hack | 0.2.0 |
-
-
### Changes
- Bump rust-toolchain to "nightly-2023-12-26".
- Introduce time-series distribution args to bench tool. [#253](https://github.com/foyer-rs/foyer/pull/253)
-
-### Fixes
-
- Fix duplicated insert drop metrics.
-
-
## 2023-12-22
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.4.0 |
@@ -632,45 +565,40 @@
| foyer-storage-bench | 0.3.0 |
| foyer-workspace-hack | 0.1.1 |
-
-
### Changes
- Remove config `flusher_buffer_capacity`.
-
-### Fixes
-
- Fix benchmark tool cache miss ratio.
-
-
## 2023-12-20
+### Releases
+
| crate | version |
| - | - |
| foyer-storage | 0.2.2 |
-
+### Changes
- Fix metrics for writer dropping.
- Add interface `insert_async_with_callback` and `insert_if_not_exists_async_with_callback` for callers to get the insert result.
-
-
## 2023-12-18
+### Releases
+
| crate | version |
| - | - |
| foyer-storage | 0.2.1 |
-
+### Changes
- Introduce the entry size histogram, update metrics.
-
-
## 2023-12-18
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.3.0 |
@@ -678,16 +606,16 @@
| foyer-storage | 0.2.0 |
| foyer-storage-bench | 0.2.0 |
-
+### Changes
- Introduce the associated type `Cursor` for trait `Key` and `Value` to reduce unnecessary buffer copy if possible.
- Remove the ring buffer and continuum tracker for they are no longer needed.
- Update the configuration of the storage engine and the benchmark tool.
-
-
## 2023-11-29
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.2.0 |
@@ -697,7 +625,7 @@
| foyer-storage-bench | 0.1.0 |
| foyer-workspace-hack | 0.1.0 |
-
+### Changes
The first version that can be used as file cache.
@@ -715,17 +643,14 @@ Brief description about the subcrates:
- foyer-storage-bench: Runnable benchmark tool for the file cache storage engine.
- foyer-workspace-hack: Generated by [hakari](https://crates.io/crates/hakari) to prevent building each crate from triggering building from scratch.
-
-
-
## 2023-05-12
+### Releases
+
| crate | version |
| - | - |
| foyer | 0.1.0 |
-
+### Changes
Initial version with just basic interfaces.
-
-
From 4878ef25eb4d6cfe42802e26d82096ba1174658c Mon Sep 17 00:00:00 2001
From: Croxx
Date: Sat, 14 Sep 2024 22:57:06 +0800
Subject: [PATCH 02/53] chore: add some metadata for changelog (#712)
* chore: add some metadata for changelog
Signed-off-by: MrCroxx
* chore: add more meta
Signed-off-by: MrCroxx
* chore: just more
Signed-off-by: MrCroxx
---------
Signed-off-by: MrCroxx
---
CHANGELOG.md | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index af62fc78..327c191f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,24 @@
+---
+title: Changelog
+description: Changelog for foyer.
+authors:
+ - name: Croxx
+ title: Author of foyer
+ url: https://github.com/mrcroxx
+ image_url: https://github.com/mrcroxx.png
+ socials:
+ x: CroxxMr
+ github: mrcroxx
+ linkedin: mrcroxx
+ newsletter: https://blog.mrcroxx.com
+tags: [changelog]
+date: 2023-05-12T11:02:09+08:00
+---
+
+# Changelog
+
+
+
## 2024-09-12
### Releases
From 714b3c3d64ff1104b94384a0bfcaf986b3c60978 Mon Sep 17 00:00:00 2001
From: Croxx
Date: Sat, 14 Sep 2024 23:18:11 +0800
Subject: [PATCH 03/53] chore: ignore changelog author details (#713)
Signed-off-by: MrCroxx
---
CHANGELOG.md | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 327c191f..47a2dd24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,16 +1,7 @@
---
title: Changelog
description: Changelog for foyer.
-authors:
- - name: Croxx
- title: Author of foyer
- url: https://github.com/mrcroxx
- image_url: https://github.com/mrcroxx.png
- socials:
- x: CroxxMr
- github: mrcroxx
- linkedin: mrcroxx
- newsletter: https://blog.mrcroxx.com
+authors: mrcroxx
tags: [changelog]
date: 2023-05-12T11:02:09+08:00
---
From c28c6c1a81c793ce3d20c4ba73943a01df47f0c9 Mon Sep 17 00:00:00 2001
From: Croxx
Date: Thu, 19 Sep 2024 14:24:15 +0800
Subject: [PATCH 04/53] chore: update readme, add website (#719)
Signed-off-by: MrCroxx
---
README.md | 24 +++++++++++++++++++-----
foyer/src/lib.rs | 4 ++++
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index 6ea75be1..a878d205 100644
--- a/README.md
+++ b/README.md
@@ -2,12 +2,18 @@
+
+
+![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&style=for-the-badge&logo=rust&labelColor=555555)
+![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555)
+![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555)
+
+
+
# foyer
-![Crates.io Version](https://img.shields.io/crates/v/foyer)
-![Crates.io MSRV](https://img.shields.io/crates/msrv/foyer)
![GitHub License](https://img.shields.io/github/license/foyer-rs/foyer)
-
+![Crates.io MSRV](https://img.shields.io/crates/msrv/foyer)
[![CI](https://github.com/foyer-rs/foyer/actions/workflows/ci.yml/badge.svg)](https://github.com/foyer-rs/foyer/actions/workflows/ci.yml)
[![License Checker](https://github.com/foyer-rs/foyer/actions/workflows/license_check.yml/badge.svg)](https://github.com/foyer-rs/foyer/actions/workflows/license_check.yml)
[![codecov](https://codecov.io/github/foyer-rs/foyer/branch/main/graph/badge.svg?token=YO33YQCB70)](https://codecov.io/github/foyer-rs/foyer)
@@ -18,9 +24,11 @@ foyer draws inspiration from [Facebook/CacheLib](https://github.com/facebook/cac
However, *foyer* is more than just a *rewrite in Rust* effort; it introduces a variety of new and optimized features.
+For more details, please visit foyer's website: https://foyer.rs 🥰
+
## Features
-- **Hybrid Cache**: Seamlessly integrates both in-memory and disk-based caching for optimal performance and flexibility.
+- **Hybrid Cache**: Seamlessly integrates both in-memory and disk cache for optimal performance and flexibility.
- **Plug-and-Play Algorithms**: Empowers users with easily replaceable caching algorithms, ensuring adaptability to diverse use cases.
- **Fearless Concurrency**: Built to handle high concurrency with robust thread-safe mechanisms, guaranteeing reliable performance under heavy loads.
- **Zero-Copy In-Memory Cache Abstraction**: Leveraging Rust's robust type system, the in-memory cache in foyer achieves a better performance with zero-copy abstraction.
@@ -34,7 +42,13 @@ Feel free to open a PR and add your projects here:
- [RisingWave](https://github.com/risingwavelabs/risingwave): SQL stream processing, analytics, and management.
- [Chroma](https://github.com/chroma-core/chroma): Embedding database for LLM apps.
-## Usage
+## Document
+
+Tutorial & Document: https://foyer.rs
+
+API References: https://docs.rs/foyer
+
+## Quick Start
To use *foyer* in your project, add this line to the `dependencies` section of `Cargo.toml`.
diff --git a/foyer/src/lib.rs b/foyer/src/lib.rs
index dc0710cd..27a1f61f 100644
--- a/foyer/src/lib.rs
+++ b/foyer/src/lib.rs
@@ -17,6 +17,10 @@
#![warn(clippy::allow_attributes)]
//! A hybrid cache library that supports plug-and-play cache algorithms, in-memory cache and disk cache.
+//!
+//! ![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555)
+//! ![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555)
+//! ![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&style=for-the-badge&logo=rust&labelColor=555555)
use foyer_common as common;
use foyer_memory as memory;
From 474fd2fe7da36e77b859bd59cc5ea60ef1598cef Mon Sep 17 00:00:00 2001
From: Croxx
Date: Thu, 19 Sep 2024 17:33:51 +0800
Subject: [PATCH 05/53] chore: update badge with link (#721)
* chore: update badge with link
Signed-off-by: MrCroxx
* chore: center the badges
Signed-off-by: MrCroxx
* chore: add website center
Signed-off-by: MrCroxx
* chore: fix link
Signed-off-by: MrCroxx
* chore: add more guides
Signed-off-by: MrCroxx
* chore: add links in rust doc
Signed-off-by: MrCroxx
* chore: update
Signed-off-by: MrCroxx
---------
Signed-off-by: MrCroxx
---
README.md | 34 ++++++++++++++++++++++------------
foyer/src/lib.rs | 11 ++++++++---
2 files changed, 30 insertions(+), 15 deletions(-)
diff --git a/README.md b/README.md
index a878d205..eb639ae5 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,22 @@
-
-
-![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&style=for-the-badge&logo=rust&labelColor=555555)
-![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555)
-![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555)
+
+
+
+
+
+
+
+
+
+
+
-
+
+ Tutorial & Document:
+ https://foyer.rs
+
# foyer
@@ -26,6 +35,11 @@ However, *foyer* is more than just a *rewrite in Rust* effort; it introduces a v
For more details, please visit foyer's website: https://foyer.rs 🥰
+[Website](https://foyer.rs) |
+[Tutorial](https://foyer.rs/docs/overview) |
+[API Docs](https://docs.rs/foyer) |
+[Crate](https://crates.io/crates/foyer)
+
## Features
- **Hybrid Cache**: Seamlessly integrates both in-memory and disk cache for optimal performance and flexibility.
@@ -42,14 +56,10 @@ Feel free to open a PR and add your projects here:
- [RisingWave](https://github.com/risingwavelabs/risingwave): SQL stream processing, analytics, and management.
- [Chroma](https://github.com/chroma-core/chroma): Embedding database for LLM apps.
-## Document
-
-Tutorial & Document: https://foyer.rs
-
-API References: https://docs.rs/foyer
-
## Quick Start
+**This section only shows briefs. Please visit https://foyer.rs for more details.**
+
To use *foyer* in your project, add this line to the `dependencies` section of `Cargo.toml`.
```toml
diff --git a/foyer/src/lib.rs b/foyer/src/lib.rs
index 27a1f61f..2a636cd5 100644
--- a/foyer/src/lib.rs
+++ b/foyer/src/lib.rs
@@ -18,9 +18,14 @@
//! A hybrid cache library that supports plug-and-play cache algorithms, in-memory cache and disk cache.
//!
-//! ![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555)
-//! ![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555)
-//! ![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&style=for-the-badge&logo=rust&labelColor=555555)
+//! ![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&down_message=website&style=for-the-badge&logo=htmx&link=https%3A%2F%2Ffoyer.rs)
+//! ![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=crates.io&labelColor=555555&link=https%3A%2F%2Fcrates.io%2Fcrates%2Ffoyer)
+//! ![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=rust&label=docs.rs&labelColor=555555&link=https%3A%2F%2Fdocs.rs%2Ffoyer)
+//!
+//! [Website](https://foyer.rs) |
+//! [Tutorial](https://foyer.rs/docs/overview) |
+//! [API Docs](https://docs.rs/foyer) |
+//! [Crate](https://crates.io/crates/foyer)
use foyer_common as common;
use foyer_memory as memory;
From 7ebc971d2c1542382e7ea2c2008c5083b3fede41 Mon Sep 17 00:00:00 2001
From: Croxx
Date: Fri, 20 Sep 2024 12:26:09 +0800
Subject: [PATCH 06/53] fix: fix io buffer pool alignment (#724)
Signed-off-by: MrCroxx
---
foyer-storage/src/io_buffer_pool.rs | 5 ++++-
foyer-storage/src/large/batch.rs | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/foyer-storage/src/io_buffer_pool.rs b/foyer-storage/src/io_buffer_pool.rs
index 4a136fdf..83e42503 100644
--- a/foyer-storage/src/io_buffer_pool.rs
+++ b/foyer-storage/src/io_buffer_pool.rs
@@ -14,7 +14,9 @@
use std::collections::VecDeque;
-use crate::{IoBuffer, IoBytes};
+use foyer_common::bits;
+
+use crate::{device::ALIGN, IoBuffer, IoBytes};
pub enum Buffer {
IoBuffer(IoBuffer),
@@ -41,6 +43,7 @@ pub struct IoBufferPool {
impl IoBufferPool {
pub fn new(buffer_size: usize, capacity: usize) -> Self {
+ bits::assert_aligned(ALIGN, buffer_size);
Self {
capacity,
buffer_size,
diff --git a/foyer-storage/src/large/batch.rs b/foyer-storage/src/large/batch.rs
index ed7e771d..a4e46f87 100644
--- a/foyer-storage/src/large/batch.rs
+++ b/foyer-storage/src/large/batch.rs
@@ -117,6 +117,7 @@ where
S: HashBuilder + Debug,
{
pub fn new(capacity: usize, region_manager: RegionManager, device: MonitoredDevice, indexer: Indexer) -> Self {
+ let capacity = bits::align_up(device.align(), capacity);
let mut batch = Self {
buffer: IoBuffer::new(capacity),
len: 0,
From a52da3a523dcaccbad30d7e513aa69d2ab3fc7d8 Mon Sep 17 00:00:00 2001
From: Croxx
Date: Fri, 20 Sep 2024 13:07:40 +0800
Subject: [PATCH 07/53] chore: relase foyer 0.11.3 (#725)
Signed-off-by: MrCroxx
---
CHANGELOG.md | 18 +++++++++++++++++-
foyer-bench/Cargo.toml | 4 ++--
foyer-common/Cargo.toml | 2 +-
foyer-intrusive/Cargo.toml | 4 ++--
foyer-memory/Cargo.toml | 6 +++---
foyer-storage/Cargo.toml | 6 +++---
foyer/Cargo.toml | 8 ++++----
7 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 47a2dd24..a989f5f9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,6 @@
title: Changelog
description: Changelog for foyer.
authors: mrcroxx
-tags: [changelog]
date: 2023-05-12T11:02:09+08:00
---
@@ -10,6 +9,23 @@ date: 2023-05-12T11:02:09+08:00
+## 2024-09-20
+
+### Releases
+
+| crate | version |
+| - | - |
+| foyer | 0.11.3 |
+| foyer-common | 0.9.3 |
+| foyer-intrusive | 0.9.3 |
+| foyer-memory | 0.7.3 |
+| foyer-storage | 0.10.3 |
+| foyer-bench | 0.3.3 |
+
+### Changes
+
+- Fix panicked by io buffer pool alignment issue.
+
## 2024-09-12
### Releases
diff --git a/foyer-bench/Cargo.toml b/foyer-bench/Cargo.toml
index c6bd15bc..9ca1c6bb 100644
--- a/foyer-bench/Cargo.toml
+++ b/foyer-bench/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "foyer-bench"
-version = "0.3.2"
+version = "0.3.3"
edition = "2021"
authors = ["MrCroxx "]
description = "bench tool for foyer - the hybrid cache for Rust"
@@ -17,7 +17,7 @@ clap = { workspace = true }
console-subscriber = { version = "0.4", optional = true }
fastrace = { workspace = true, optional = true }
fastrace-jaeger = { workspace = true, optional = true }
-foyer = { version = "0.11.2", path = "../foyer" }
+foyer = { version = "0.11.3", path = "../foyer" }
futures = "0.3"
hdrhistogram = "7"
itertools = { workspace = true }
diff --git a/foyer-common/Cargo.toml b/foyer-common/Cargo.toml
index bd9d5f37..16ef110d 100644
--- a/foyer-common/Cargo.toml
+++ b/foyer-common/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "foyer-common"
-version = "0.9.2"
+version = "0.9.3"
edition = "2021"
authors = ["MrCroxx "]
description = "common components for foyer - the hybrid cache for Rust"
diff --git a/foyer-intrusive/Cargo.toml b/foyer-intrusive/Cargo.toml
index 598e35c5..abdf950d 100644
--- a/foyer-intrusive/Cargo.toml
+++ b/foyer-intrusive/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "foyer-intrusive"
-version = "0.9.2"
+version = "0.9.3"
edition = "2021"
authors = ["MrCroxx "]
description = "intrusive data structures for foyer - the hybrid cache for Rust"
@@ -11,7 +11,7 @@ readme = "../README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-foyer-common = { version = "0.9.2", path = "../foyer-common" }
+foyer-common = { version = "0.9.3", path = "../foyer-common" }
itertools = { workspace = true }
[features]
diff --git a/foyer-memory/Cargo.toml b/foyer-memory/Cargo.toml
index ba2ee1c0..f971ad0e 100644
--- a/foyer-memory/Cargo.toml
+++ b/foyer-memory/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "foyer-memory"
-version = "0.7.2"
+version = "0.7.3"
edition = "2021"
authors = ["MrCroxx "]
description = "memory cache for foyer - the hybrid cache for Rust"
@@ -15,8 +15,8 @@ ahash = "0.8"
bitflags = "2"
cmsketch = "0.2.1"
fastrace = { workspace = true }
-foyer-common = { version = "0.9.2", path = "../foyer-common" }
-foyer-intrusive = { version = "0.9.2", path = "../foyer-intrusive" }
+foyer-common = { version = "0.9.3", path = "../foyer-common" }
+foyer-intrusive = { version = "0.9.3", path = "../foyer-intrusive" }
futures = "0.3"
hashbrown = "0.14"
itertools = { workspace = true }
diff --git a/foyer-storage/Cargo.toml b/foyer-storage/Cargo.toml
index 1a2c365c..3812d80b 100644
--- a/foyer-storage/Cargo.toml
+++ b/foyer-storage/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "foyer-storage"
-version = "0.10.2"
+version = "0.10.3"
edition = "2021"
authors = ["MrCroxx "]
description = "storage engine for foyer - the hybrid cache for Rust"
@@ -24,8 +24,8 @@ bytes = "1"
clap = { workspace = true }
either = "1"
fastrace = { workspace = true }
-foyer-common = { version = "0.9.2", path = "../foyer-common" }
-foyer-memory = { version = "0.7.2", path = "../foyer-memory" }
+foyer-common = { version = "0.9.3", path = "../foyer-common" }
+foyer-memory = { version = "0.7.3", path = "../foyer-memory" }
fs4 = "0.9.1"
futures = "0.3"
itertools = { workspace = true }
diff --git a/foyer/Cargo.toml b/foyer/Cargo.toml
index 6c925596..25a4e837 100644
--- a/foyer/Cargo.toml
+++ b/foyer/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "foyer"
-version = "0.11.2"
+version = "0.11.3"
edition = "2021"
authors = ["MrCroxx "]
description = "Hybrid cache for Rust"
@@ -15,9 +15,9 @@ rust-version = "1.81.0"
ahash = "0.8"
anyhow = "1"
fastrace = { workspace = true }
-foyer-common = { version = "0.9.2", path = "../foyer-common" }
-foyer-memory = { version = "0.7.2", path = "../foyer-memory" }
-foyer-storage = { version = "0.10.2", path = "../foyer-storage" }
+foyer-common = { version = "0.9.3", path = "../foyer-common" }
+foyer-memory = { version = "0.7.3", path = "../foyer-memory" }
+foyer-storage = { version = "0.10.3", path = "../foyer-storage" }
futures = "0.3"
pin-project = "1"
tokio = { workspace = true }
From fd68f1b33903f30f3f93d5e20708ebea70d24272 Mon Sep 17 00:00:00 2001
From: Croxx
Date: Fri, 20 Sep 2024 13:48:29 +0800
Subject: [PATCH 08/53] doc: fix a tiny broken link (#728)
Signed-off-by: MrCroxx
---
foyer-storage/src/device/direct_file.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/foyer-storage/src/device/direct_file.rs b/foyer-storage/src/device/direct_file.rs
index b56cbd59..6b66c020 100644
--- a/foyer-storage/src/device/direct_file.rs
+++ b/foyer-storage/src/device/direct_file.rs
@@ -251,7 +251,7 @@ impl Dev for DirectFileDevice {
}
}
-/// [`DirectFiDeviceOptionsBuilder`] is used to build the options for the direct fs device.
+/// [`DirectFileDeviceOptionsBuilder`] is used to build the options for the direct fs device.
///
/// The direct fs device uses a directory in a file system to store the data of disk cache.
///
From f1490da1078c54359ee7896a607a245cf08bb9ff Mon Sep 17 00:00:00 2001
From: Croxx
Date: Fri, 20 Sep 2024 15:18:11 +0800
Subject: [PATCH 09/53] refactor: rename with_buffer_threshold to
with_buffer_pool_size (#729)
Signed-off-by: MrCroxx
---
examples/hybrid_full.rs | 2 +-
foyer-storage/src/store.rs | 28 ++++++++++++++++++++++------
foyer/src/hybrid/builder.rs | 24 +++++++++++++++++++++++-
3 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/examples/hybrid_full.rs b/examples/hybrid_full.rs
index 14ca0ff1..97f98500 100644
--- a/examples/hybrid_full.rs
+++ b/examples/hybrid_full.rs
@@ -48,7 +48,7 @@ async fn main() -> Result<()> {
.with_recover_concurrency(8)
.with_flushers(2)
.with_reclaimers(2)
- .with_buffer_threshold(256 * 1024 * 1024)
+ .with_buffer_pool_size(256 * 1024 * 1024)
.with_clean_region_threshold(4)
.with_eviction_pickers(vec![Box::::default()])
.with_admission_picker(Arc::new(RateLimitPicker::new(100 * 1024 * 1024)))
diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs
index 5ed47948..663f9870 100644
--- a/foyer-storage/src/store.rs
+++ b/foyer-storage/src/store.rs
@@ -357,8 +357,7 @@ where
recover_concurrency: usize,
flushers: usize,
reclaimers: usize,
- // FIXME(MrCroxx): rename the field and builder fn.
- buffer_threshold: usize,
+ buffer_pool_size: usize,
clean_region_threshold: Option,
eviction_pickers: Vec>,
admission_picker: Arc>,
@@ -387,7 +386,7 @@ where
recover_concurrency: 8,
flushers: 1,
reclaimers: 1,
- buffer_threshold: 16 * 1024 * 1024, // 16 MiB
+ buffer_pool_size: 16 * 1024 * 1024, // 16 MiB
clean_region_threshold: None,
eviction_pickers: vec![Box::new(InvalidRatioPicker::new(0.8)), Box::::default()],
admission_picker: Arc::>::default(),
@@ -469,6 +468,7 @@ where
self
}
+ // FIXME(MrCroxx): remove it after 0.12
/// Set the total flush buffer threshold.
///
/// Each flusher shares a volume at `threshold / flushers`.
@@ -476,8 +476,24 @@ where
/// If the buffer of the flush queue exceeds the threshold, the further entries will be ignored.
///
/// Default: 16 MiB.
+ #[deprecated(
+ since = "0.11.4",
+ note = "The function will be renamed to \"with_buffer_pool_size()\", use it instead."
+ )]
pub fn with_buffer_threshold(mut self, threshold: usize) -> Self {
- self.buffer_threshold = threshold;
+ self.buffer_pool_size = threshold;
+ self
+ }
+
+ /// Set the total flush buffer pool size.
+ ///
+ /// Each flusher shares a volume at `threshold / flushers`.
+ ///
+ /// If the buffer of the flush queue exceeds the threshold, the further entries will be ignored.
+ ///
+ /// Default: 16 MiB.
+ pub fn with_buffer_pool_size(mut self, buffer_pool_size: usize) -> Self {
+ self.buffer_pool_size = buffer_pool_size;
self
}
@@ -659,7 +675,7 @@ where
eviction_pickers: self.eviction_pickers,
reinsertion_picker: self.reinsertion_picker,
tombstone_log_config: self.tombstone_log_config,
- buffer_threshold: self.buffer_threshold,
+ buffer_threshold: self.buffer_pool_size,
statistics: statistics.clone(),
write_runtime_handle,
read_runtime_handle,
@@ -702,7 +718,7 @@ where
eviction_pickers: self.eviction_pickers,
reinsertion_picker: self.reinsertion_picker,
tombstone_log_config: self.tombstone_log_config,
- buffer_threshold: self.buffer_threshold,
+ buffer_threshold: self.buffer_pool_size,
statistics: statistics.clone(),
write_runtime_handle,
read_runtime_handle,
diff --git a/foyer/src/hybrid/builder.rs b/foyer/src/hybrid/builder.rs
index 3ee2a450..34eb69be 100644
--- a/foyer/src/hybrid/builder.rs
+++ b/foyer/src/hybrid/builder.rs
@@ -299,6 +299,7 @@ where
}
}
+ // FIXME(MrCroxx): remove it after 0.12
/// Set the total flush buffer threshold.
///
/// Each flusher shares a volume at `threshold / flushers`.
@@ -306,8 +307,29 @@ where
/// If the buffer of the flush queue exceeds the threshold, the further entries will be ignored.
///
/// Default: 16 MiB.
+ #[deprecated(
+ since = "0.11.4",
+ note = "The function will be renamed to \"with_buffer_pool_size()\", use it instead."
+ )]
pub fn with_buffer_threshold(self, threshold: usize) -> Self {
- let builder = self.builder.with_buffer_threshold(threshold);
+ let builder = self.builder.with_buffer_pool_size(threshold);
+ Self {
+ name: self.name,
+ tracing_config: self.tracing_config,
+ memory: self.memory,
+ builder,
+ }
+ }
+
+ /// Set the total flush buffer pool size.
+ ///
+ /// Each flusher shares a volume at `threshold / flushers`.
+ ///
+ /// If the buffer of the flush queue exceeds the threshold, the further entries will be ignored.
+ ///
+ /// Default: 16 MiB.
+ pub fn with_buffer_pool_size(self, buffer_pool_size: usize) -> Self {
+ let builder = self.builder.with_buffer_pool_size(buffer_pool_size);
Self {
name: self.name,
tracing_config: self.tracing_config,
From 553a9cbdd8a392d1aa071eeb9c00b49555f60162 Mon Sep 17 00:00:00 2001
From: Croxx
Date: Fri, 20 Sep 2024 15:59:28 +0800
Subject: [PATCH 10/53] chore: warn if DirectFileDevice is used in a fs (#730)
Signed-off-by: MrCroxx
---
foyer-storage/src/device/direct_file.rs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/foyer-storage/src/device/direct_file.rs b/foyer-storage/src/device/direct_file.rs
index 6b66c020..6b8170f3 100644
--- a/foyer-storage/src/device/direct_file.rs
+++ b/foyer-storage/src/device/direct_file.rs
@@ -199,6 +199,12 @@ impl Dev for DirectFileDevice {
let file = opts.open(&options.path)?;
if file.metadata().unwrap().is_file() {
+ tracing::warn!(
+ "{}\n{}\n{}",
+ "It seems a `DirectFileDevice` is used within a normal file system, which is inefficient.",
+ "Please use `DirectFileDevice` directly on a raw block device.",
+ "Or use `DirectFsDevice` within a normal file system.",
+ );
file.set_len(options.capacity as _)?;
}
From 60839ee7e399f3ee32b57fe548a03881ab540531 Mon Sep 17 00:00:00 2001
From: Croxx
Date: Tue, 24 Sep 2024 14:21:15 +0800
Subject: [PATCH 11/53] refactor: revert the pre-serialization and parallel
buffer (#717)
* refactor: use entry uncompressed serialized size for selection
Signed-off-by: MrCroxx
* refactor: refactor entry serde
Signed-off-by: MrCroxx
* refactor: revert the parallelism batching design
Signed-off-by: MrCroxx
* refactor: remove spawn on write
Signed-off-by: MrCroxx
* chore: pass ffmt test
Signed-off-by: MrCroxx
* fix: fix build on nightly with nightly feature
Signed-off-by: MrCroxx
* chore: fix
Signed-off-by: MrCroxx
---------
Signed-off-by: MrCroxx
---
examples/Cargo.toml | 8 +-
foyer-bench/Cargo.toml | 2 +-
foyer-storage/Cargo.toml | 1 +
foyer-storage/src/engine.rs | 21 +--
foyer-storage/src/large/batch.rs | 154 +++++++++++-----------
foyer-storage/src/large/flusher.rs | 190 ++++++++++++++--------------
foyer-storage/src/large/generic.rs | 29 ++---
foyer-storage/src/lib.rs | 1 +
foyer-storage/src/serde.rs | 105 +++++++++------
foyer-storage/src/small/generic.rs | 4 +-
foyer-storage/src/storage/either.rs | 13 +-
foyer-storage/src/storage/mod.rs | 4 +-
foyer-storage/src/storage/noop.rs | 13 +-
foyer-storage/src/store.rs | 29 +----
14 files changed, 286 insertions(+), 288 deletions(-)
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
index 74b49b7f..2584ca5f 100644
--- a/examples/Cargo.toml
+++ b/examples/Cargo.toml
@@ -19,10 +19,10 @@ fastrace = { workspace = true }
fastrace-jaeger = { workspace = true, optional = true }
fastrace-opentelemetry = { workspace = true, optional = true }
foyer = { version = "*", path = "../foyer" }
-opentelemetry = { version = "0.24", optional = true }
-opentelemetry-otlp = { version = "0.17", optional = true }
-opentelemetry-semantic-conventions = { version = "0.16", optional = true }
-opentelemetry_sdk = { version = "0.24", features = [
+opentelemetry = { version = "0.25", optional = true }
+opentelemetry-otlp = { version = "0.25", optional = true }
+opentelemetry-semantic-conventions = { version = "0.25", optional = true }
+opentelemetry_sdk = { version = "0.25", features = [
"rt-tokio",
"trace",
], optional = true }
diff --git a/foyer-bench/Cargo.toml b/foyer-bench/Cargo.toml
index 9ca1c6bb..8afb448f 100644
--- a/foyer-bench/Cargo.toml
+++ b/foyer-bench/Cargo.toml
@@ -29,7 +29,7 @@ serde = { workspace = true }
serde_bytes = "0.11.15"
tokio = { workspace = true }
tracing = "0.1"
-tracing-opentelemetry = { version = "0.25", optional = true }
+tracing-opentelemetry = { version = "0.26", optional = true }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
zipf = "7"
diff --git a/foyer-storage/Cargo.toml b/foyer-storage/Cargo.toml
index 3812d80b..e14de4a2 100644
--- a/foyer-storage/Cargo.toml
+++ b/foyer-storage/Cargo.toml
@@ -24,6 +24,7 @@ bytes = "1"
clap = { workspace = true }
either = "1"
fastrace = { workspace = true }
+flume = "0.11"
foyer-common = { version = "0.9.3", path = "../foyer-common" }
foyer-memory = { version = "0.7.3", path = "../foyer-memory" }
fs4 = "0.9.1"
diff --git a/foyer-storage/src/engine.rs b/foyer-storage/src/engine.rs
index 51357acd..33629b3e 100644
--- a/foyer-storage/src/engine.rs
+++ b/foyer-storage/src/engine.rs
@@ -28,13 +28,12 @@ use futures::Future;
use crate::{
error::Result,
large::generic::{GenericLargeStorage, GenericLargeStorageConfig},
- serde::KvInfo,
small::generic::{GenericSmallStorage, GenericSmallStorageConfig},
storage::{
either::{Either, EitherConfig, Selection, Selector},
noop::Noop,
},
- DeviceStats, IoBytes, Storage,
+ DeviceStats, Storage,
};
pub struct SizeSelector
@@ -84,8 +83,12 @@ where
type Value = V;
type BuildHasher = S;
- fn select(&self, _entry: &CacheEntry, buffer: &IoBytes) -> Selection {
- if buffer.len() < self.threshold {
+ fn select(
+ &self,
+ _entry: &CacheEntry,
+ estimated_size: usize,
+ ) -> Selection {
+ if estimated_size < self.threshold {
Selection::Left
} else {
Selection::Right
@@ -239,12 +242,12 @@ where
}
}
- fn enqueue(&self, entry: CacheEntry, buffer: IoBytes, info: KvInfo) {
+ fn enqueue(&self, entry: CacheEntry, estimated_size: usize) {
match self {
- Engine::Noop(storage) => storage.enqueue(entry, buffer, info),
- Engine::Large(storage) => storage.enqueue(entry, buffer, info),
- Engine::Small(storage) => storage.enqueue(entry, buffer, info),
- Engine::Combined(storage) => storage.enqueue(entry, buffer, info),
+ Engine::Noop(storage) => storage.enqueue(entry, estimated_size),
+ Engine::Large(storage) => storage.enqueue(entry, estimated_size),
+ Engine::Small(storage) => storage.enqueue(entry, estimated_size),
+ Engine::Combined(storage) => storage.enqueue(entry, estimated_size),
}
}
diff --git a/foyer-storage/src/large/batch.rs b/foyer-storage/src/large/batch.rs
index a4e46f87..ba5a8b04 100644
--- a/foyer-storage/src/large/batch.rs
+++ b/foyer-storage/src/large/batch.rs
@@ -12,19 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-use std::{
- fmt::Debug,
- mem::ManuallyDrop,
- ops::{Deref, DerefMut, Range},
- time::Instant,
-};
+use std::{fmt::Debug, ops::Range, sync::Arc, time::Instant};
use foyer_common::{
bits,
code::{HashBuilder, StorageKey, StorageValue},
+ metrics::Metrics,
range::RangeBoundsExt,
strict_assert_eq,
- wait_group::{WaitGroup, WaitGroupFuture, WaitGroupGuard},
};
use foyer_memory::CacheEntry;
use itertools::Itertools;
@@ -39,38 +34,12 @@ use super::{
use crate::{
device::{bytes::IoBytes, MonitoredDevice, RegionId},
io_buffer_pool::IoBufferPool,
- large::indexer::HashedEntryAddress,
+ large::{indexer::HashedEntryAddress, serde::EntryHeader},
region::{GetCleanRegionHandle, RegionManager},
- Dev, DevExt, IoBuffer,
+ serde::{Checksummer, EntrySerializer},
+ Compression, Dev, DevExt, IoBuffer,
};
-pub struct Allocation {
- _guard: WaitGroupGuard,
- slice: ManuallyDrop>,
-}
-
-impl Deref for Allocation {
- type Target = [u8];
-
- fn deref(&self) -> &Self::Target {
- self.slice.as_ref()
- }
-}
-
-impl DerefMut for Allocation {
- fn deref_mut(&mut self) -> &mut Self::Target {
- self.slice.as_mut()
- }
-}
-
-impl Allocation {
- unsafe fn new(buffer: &mut [u8], guard: WaitGroupGuard) -> Self {
- let fake = Vec::from_raw_parts(buffer.as_mut_ptr(), buffer.len(), buffer.len());
- let slice = ManuallyDrop::new(fake.into_boxed_slice());
- Self { _guard: guard, slice }
- }
-}
-
pub struct BatchMut
where
K: StorageKey,
@@ -83,7 +52,6 @@ where
tombstones: Vec,
waiters: Vec>,
init: Option,
- wait: WaitGroup,
/// Cache write buffer between rotation to reduce page fault.
buffer_pool: IoBufferPool,
@@ -91,6 +59,7 @@ where
region_manager: RegionManager,
device: MonitoredDevice,
indexer: Indexer,
+ metrics: Arc,
}
impl Debug for BatchMut
@@ -116,7 +85,13 @@ where
V: StorageValue,
S: HashBuilder + Debug,
{
- pub fn new(capacity: usize, region_manager: RegionManager, device: MonitoredDevice, indexer: Indexer) -> Self {
+ pub fn new(
+ capacity: usize,
+ region_manager: RegionManager,
+ device: MonitoredDevice,
+ indexer: Indexer,
+ metrics: Arc,
+ ) -> Self {
let capacity = bits::align_up(device.align(), capacity);
let mut batch = Self {
buffer: IoBuffer::new(capacity),
@@ -125,26 +100,56 @@ where
tombstones: vec![],
waiters: vec![],
init: None,
- wait: WaitGroup::default(),
buffer_pool: IoBufferPool::new(capacity, 1),
region_manager,
device,
indexer,
+ metrics,
};
batch.append_group();
batch
}
- pub fn entry(&mut self, size: usize, entry: CacheEntry, sequence: Sequence) -> Option {
+ pub fn entry(&mut self, entry: CacheEntry, compression: &Compression, sequence: Sequence) -> bool {
tracing::trace!("[batch]: append entry with sequence: {sequence}");
- let aligned = bits::align_up(self.device.align(), size);
+ self.may_init();
- if entry.is_outdated() || self.len + aligned > self.buffer.len() {
- return None;
+ if entry.is_outdated() {
+ return false;
}
- let allocation = self.allocate(aligned);
+ let pos = self.len;
+
+ let info = match EntrySerializer::serialize(
+ entry.key(),
+ entry.value(),
+ compression,
+ &mut self.buffer[pos + EntryHeader::serialized_len()..],
+ &self.metrics,
+ ) {
+ Ok(info) => info,
+ Err(e) => {
+ tracing::warn!("[batch]: serialize entry error: {e}");
+ return false;
+ }
+ };
+
+ let header = EntryHeader {
+ key_len: info.key_len as _,
+ value_len: info.value_len as _,
+ hash: entry.hash(),
+ sequence,
+ checksum: Checksummer::checksum(
+ &self.buffer[pos + EntryHeader::serialized_len()
+ ..pos + EntryHeader::serialized_len() + info.key_len + info.value_len],
+ ),
+ compression: *compression,
+ };
+ header.write(&mut self.buffer[pos..pos + EntryHeader::serialized_len()]);
+
+ let aligned = bits::align_up(self.device.align(), header.entry_len());
+ self.advance(aligned);
let group = self.groups.last_mut().unwrap();
group.indices.push(HashedEntryAddress {
@@ -152,7 +157,7 @@ where
address: EntryAddress {
region: RegionId::MAX,
offset: group.region.offset as u32 + group.region.len as u32,
- len: size as _,
+ len: header.entry_len() as _,
sequence,
},
});
@@ -160,27 +165,35 @@ where
group.region.len += aligned;
group.range.end += aligned;
- Some(allocation)
+ true
}
pub fn tombstone(&mut self, tombstone: Tombstone, stats: Option) {
tracing::trace!("[batch]: append tombstone");
+
self.may_init();
+
self.tombstones.push(TombstoneInfo { tombstone, stats });
}
- pub fn reinsertion(&mut self, reinsertion: &Reinsertion) -> Option {
+ pub fn reinsertion(&mut self, reinsertion: &Reinsertion) -> bool {
tracing::trace!("[batch]: submit reinsertion");
+ self.may_init();
+
let aligned = bits::align_up(self.device.align(), reinsertion.buffer.len());
// Skip if the entry is no longer in the indexer.
// Skip if the batch buffer size exceeds the threshold.
if self.indexer.get(reinsertion.hash).is_none() || self.len + aligned > self.buffer.len() {
- return None;
+ return false;
}
- let allocation = self.allocate(aligned);
+ let pos = self.len;
+
+ self.buffer[pos..pos + reinsertion.buffer.len()].copy_from_slice(&reinsertion.buffer);
+
+ self.advance(aligned);
let group = self.groups.last_mut().unwrap();
// Reserve buffer space for entry.
@@ -196,22 +209,17 @@ where
group.region.len += aligned;
group.range.end += aligned;
- Some(allocation)
+ true
}
/// Register a waiter to be notified after the batch is finished.
- pub fn wait(&mut self) -> oneshot::Receiver<()> {
+ pub fn wait(&mut self, tx: oneshot::Sender<()>) {
tracing::trace!("[batch]: register waiter");
self.may_init();
- let (tx, rx) = oneshot::channel();
self.waiters.push(tx);
- rx
}
- // Note: Make sure `rotate` is called after all buffer from the last batch are dropped.
- //
- // Otherwise, the page fault caused by the buffer pool will hurt the performance.
- pub fn rotate(&mut self) -> Option<(Batch, WaitGroupFuture)> {
+ pub fn rotate(&mut self) -> Option> {
if self.is_empty() {
return None;
}
@@ -222,8 +230,6 @@ where
let buffer = IoBytes::from(buffer);
self.buffer_pool.release(buffer.clone());
- let wait = std::mem::take(&mut self.wait);
-
let init = self.init.take();
let tombstones = std::mem::take(&mut self.tombstones);
@@ -269,20 +275,16 @@ where
None => self.append_group(),
}
- Some((
- Batch {
- groups,
- tombstones,
- waiters,
- init,
- },
- wait.wait(),
- ))
+ Some(Batch {
+ groups,
+ tombstones,
+ waiters,
+ init,
+ })
}
- fn allocate(&mut self, len: usize) -> Allocation {
+ fn advance(&mut self, len: usize) {
assert!(bits::is_aligned(self.device.align(), len));
- self.may_init();
assert!(bits::is_aligned(self.device.align(), self.len));
// Rotate group if the current one is full.
@@ -292,24 +294,22 @@ where
self.append_group();
}
- // Reserve buffer space for entry.
- let start = self.len;
- let end = start + len;
- self.len = end;
-
- unsafe { Allocation::new(&mut self.buffer[start..end], self.wait.acquire()) }
+ self.len += len;
}
- fn is_empty(&self) -> bool {
+ #[inline]
+ pub fn is_empty(&self) -> bool {
self.tombstones.is_empty() && self.groups.iter().all(|group| group.range.is_empty()) && self.waiters.is_empty()
}
+ #[inline]
fn may_init(&mut self) {
if self.init.is_none() {
self.init = Some(Instant::now());
}
}
+ #[inline]
fn append_group(&mut self) {
self.groups.push(GroupMut {
region: RegionHandle {
diff --git a/foyer-storage/src/large/flusher.rs b/foyer-storage/src/large/flusher.rs
index 4572bc14..5bff8c7f 100644
--- a/foyer-storage/src/large/flusher.rs
+++ b/foyer-storage/src/large/flusher.rs
@@ -21,12 +21,13 @@ use std::{
use foyer_common::{
code::{HashBuilder, StorageKey, StorageValue},
metrics::Metrics,
- strict_assert,
};
use foyer_memory::CacheEntry;
use futures::future::{try_join, try_join_all};
-use parking_lot::Mutex;
-use tokio::{runtime::Handle, sync::Notify};
+use tokio::{
+ runtime::Handle,
+ sync::{oneshot, OwnedSemaphorePermit, Semaphore},
+};
use super::{
batch::{Batch, BatchMut, InvalidStats, TombstoneInfo},
@@ -39,13 +40,10 @@ use super::{
use crate::{
device::MonitoredDevice,
error::{Error, Result},
- large::serde::EntryHeader,
region::RegionManager,
- serde::{Checksummer, KvInfo},
- Compression, IoBytes, Statistics,
+ Compression, Statistics,
};
-#[derive(Debug)]
pub enum Submission
where
K: StorageKey,
@@ -54,8 +52,7 @@ where
{
CacheEntry {
entry: CacheEntry,
- buffer: IoBytes,
- info: KvInfo,
+ estimated_size: usize,
sequence: Sequence,
},
Tombstone {
@@ -65,6 +62,39 @@ where
Reinsertion {
reinsertion: Reinsertion,
},
+ Wait {
+ tx: oneshot::Sender<()>,
+ },
+}
+
+impl Debug for Submission
+where
+ K: StorageKey,
+ V: StorageValue,
+ S: HashBuilder + Debug,
+{
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::CacheEntry {
+ entry: _,
+ estimated_size,
+ sequence,
+ } => f
+ .debug_struct("CacheEntry")
+ .field("estimated_size", estimated_size)
+ .field("sequence", sequence)
+ .finish(),
+ Self::Tombstone { tombstone, stats } => f
+ .debug_struct("Tombstone")
+ .field("tombstone", tombstone)
+ .field("stats", stats)
+ .finish(),
+ Self::Reinsertion { reinsertion } => {
+ f.debug_struct("Reinsertion").field("reinsertion", reinsertion).finish()
+ }
+ Self::Wait { .. } => f.debug_struct("Wait").finish(),
+ }
+ }
}
#[derive(Debug)]
@@ -74,11 +104,8 @@ where
V: StorageValue,
S: HashBuilder + Debug,
{
- batch: Arc>>,
+ tx: flume::Sender>,
- notify: Arc,
-
- compression: Compression,
metrics: Arc,
}
@@ -90,9 +117,7 @@ where
{
fn clone(&self) -> Self {
Self {
- batch: self.batch.clone(),
- notify: self.notify.clone(),
- compression: self.compression,
+ tx: self.tx.clone(),
metrics: self.metrics.clone(),
}
}
@@ -115,22 +140,25 @@ where
metrics: Arc,
runtime: Handle,
) -> Result {
- let notify = Arc::new(Notify::new());
+ let (tx, rx) = flume::unbounded();
let buffer_size = config.buffer_threshold / config.flushers;
- let batch = Arc::new(Mutex::new(BatchMut::new(
+ let batch = BatchMut::new(
buffer_size,
region_manager.clone(),
device.clone(),
indexer.clone(),
- )));
+ metrics.clone(),
+ );
let runner = Runner {
- batch: batch.clone(),
- notify: notify.clone(),
+ rx,
+ batch,
+ flight: Arc::new(Semaphore::new(1)),
region_manager,
indexer,
tombstone_log,
+ compression: config.compression,
flush: config.flush,
stats,
metrics: metrics.clone(),
@@ -142,74 +170,23 @@ where
}
});
- Ok(Self {
- batch,
- notify,
- compression: config.compression,
- metrics,
- })
+ Ok(Self { tx, metrics })
}
pub fn submit(&self, submission: Submission) {
- match submission {
- Submission::CacheEntry {
- entry,
- buffer,
- info,
- sequence,
- } => self.entry(entry, buffer, info, sequence),
- Submission::Tombstone { tombstone, stats } => self.tombstone(tombstone, stats),
- Submission::Reinsertion { reinsertion } => self.reinsertion(reinsertion),
+ tracing::trace!("[lodc flusher]: submit task: {submission:?}");
+ if let Err(e) = self.tx.send(submission) {
+ tracing::error!("[lodc flusher]: error raised when submitting task, error: {e}");
}
- self.notify.notify_one();
}
pub fn wait(&self) -> impl Future