Skip to content

Conversation

@tisonkun
Copy link
Collaborator

@tisonkun tisonkun commented Jan 21, 2026

Some pending issues:

  1. Add tests and reorganize once primitives tests. (DONE)
  2. Whether or not add a feature flag to switch between Mutex<HashMap> and DashMap (and perhaps move the map interface to the internal module). (LATER)
  3. Whether or not support gets/removes keys of Q: ?Sized where K: Borrow<Q> and Q: Hash + Eq like std's HashMap. (DONE)

Signed-off-by: tison <wander4096@gmail.com>
Signed-off-by: tison <wander4096@gmail.com>
Signed-off-by: tison <wander4096@gmail.com>
Signed-off-by: tison <wander4096@gmail.com>
Signed-off-by: tison <wander4096@gmail.com>
Signed-off-by: tison <wander4096@gmail.com>
Signed-off-by: tison <wander4096@gmail.com>
@tisonkun tisonkun merged commit 7ca679d into main Jan 21, 2026
9 checks passed
@tisonkun tisonkun deleted the oncemap branch January 21, 2026 04:47
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements OnceMap, a concurrent hash map that ensures computation happens only once per key and caches results. It also reorganizes tests for the once module primitives and enhances singleflight::Group to support generic key queries.

Changes:

  • Implements OnceMap with thread-safe single-execution-per-key semantics
  • Adds try_work method to singleflight::Group for fallible computations
  • Reorganizes tests by moving them from centralized test modules into their respective implementation submodules
  • Enhances singleflight::Group::forget to accept generic key types via the Borrow trait

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
mea/src/once/once_map/mod.rs New OnceMap implementation with compute/try_compute methods and HashMap-like interface
mea/src/once/once_map/tests.rs Comprehensive tests for OnceMap covering basic operations, concurrency, and error handling
mea/src/once/once/mod.rs Adds test module declaration
mea/src/once/once/tests.rs Extracted Once tests from the centralized test file
mea/src/once/once_cell/mod.rs Adds test module declaration
mea/src/once/once_cell/tests.rs Removed Once tests that were moved to once/tests.rs, updated imports
mea/src/once/mod.rs Adds once_map module and exports OnceMap
mea/src/singleflight/mod.rs Adds try_work method for fallible operations, updates forget signature to support Borrow, removes comment
mea/src/lib.rs Documents OnceMap in module-level documentation
README.md Adds OnceMap to the list of primitives
CHANGELOG.md Documents new features

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +204 to +237
pub async fn try_work<E, F>(&self, key: K, func: F) -> Result<V, E>
where
F: AsyncFnOnce() -> Result<V, E>,
{
// 1. Get or create the OnceCell.
let cell = {
let mut map = self.map.lock();
map.entry(key.clone())
.or_insert_with(|| Arc::new(OnceCell::new()))
.clone()
};

// 2. Try to initialize the cell.
// OnceCell::get_or_try_init guarantees that only one task executes the closure.
let res = cell
.get_or_try_init(async || {
let result = func().await?;

// Cleanup: remove the key from the map.
// We must ensure we remove the entry corresponding to *this* cell.
let mut map = self.map.lock();
if let Some(existing) = map.get(&key) {
// Check if the map still points to our cell.
if Arc::ptr_eq(&cell, existing) {
map.remove(&key);
}
}

Ok(result)
})
.await?;

Ok(res.clone())
}
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new try_work method lacks test coverage. While there is a doc test example, there should be unit tests in the test module to verify the behavior, especially testing scenarios like: concurrent callers when the first fails and the second succeeds, behavior when both fail, and ensuring proper cleanup after failures.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants