Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 28 additions & 21 deletions cachebox/_core.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -384,16 +384,17 @@ class Cache(BaseCacheImpl[KT, VT]):
"""
Get `key`s value, or automatically create and insert one via `factory`.
If `key` exists, its current value is returned and `factory` is not called.
Otherwise `factory` is called exactly once under an internal lock, its
Otherwise `factory` is called with the internal lock released, its
result is inserted and returned.

Args:
key: The key to look up or insert.
factory: The factory to call and get default value from if ``key`` is not in the cache.

Warning:
`factory` must not call back into this cache (deadlock risk) or block
for long. If `factory` raises, nothing is inserted and the exception
if two threads miss the same key at once, `factory` can run
more than once; the value inserted first wins and is returned to
both. If `factory` raises, nothing is inserted and the exception
propagates.
"""
...
Expand Down Expand Up @@ -565,16 +566,17 @@ class FIFOCache(BaseCacheImpl[KT, VT]):
"""
Get `key`s value, or automatically create and insert one via `factory`.
If `key` exists, its current value is returned and `factory` is not called.
Otherwise `factory` is called exactly once under an internal lock, its
Otherwise `factory` is called with the internal lock released, its
result is inserted and returned.

Args:
key: The key to look up or insert.
factory: The factory to call and get default value from if ``key`` is not in the cache.

Warning:
`factory` must not call back into this cache (deadlock risk) or block
for long. If `factory` raises, nothing is inserted and the exception
if two threads miss the same key at once, `factory` can run
more than once; the value inserted first wins and is returned to
both. If `factory` raises, nothing is inserted and the exception
propagates.
"""
...
Expand Down Expand Up @@ -779,16 +781,17 @@ class RRCache(BaseCacheImpl[KT, VT]):
"""
Get `key`s value, or automatically create and insert one via `factory`.
If `key` exists, its current value is returned and `factory` is not called.
Otherwise `factory` is called exactly once under an internal lock, its
Otherwise `factory` is called with the internal lock released, its
result is inserted and returned.

Args:
key: The key to look up or insert.
factory: The factory to call and get default value from if ``key`` is not in the cache.

Warning:
`factory` must not call back into this cache (deadlock risk) or block
for long. If `factory` raises, nothing is inserted and the exception
if two threads miss the same key at once, `factory` can run
more than once; the value inserted first wins and is returned to
both. If `factory` raises, nothing is inserted and the exception
propagates.
"""
...
Expand Down Expand Up @@ -986,16 +989,17 @@ class LRUCache(BaseCacheImpl[KT, VT]):
"""
Get `key`s value, or automatically create and insert one via `factory`.
If `key` exists, its current value is returned and `factory` is not called.
Otherwise `factory` is called exactly once under an internal lock, its
Otherwise `factory` is called with the internal lock released, its
result is inserted and returned.

Args:
key: The key to look up or insert.
factory: The factory to call and get default value from if ``key`` is not in the cache.

Warning:
`factory` must not call back into this cache (deadlock risk) or block
for long. If `factory` raises, nothing is inserted and the exception
if two threads miss the same key at once, `factory` can run
more than once; the value inserted first wins and is returned to
both. If `factory` raises, nothing is inserted and the exception
propagates.
"""
...
Expand Down Expand Up @@ -1234,16 +1238,17 @@ class LFUCache(BaseCacheImpl[KT, VT]):
"""
Get `key`s value, or automatically create and insert one via `factory`.
If `key` exists, its current value is returned and `factory` is not called.
Otherwise `factory` is called exactly once under an internal lock, its
Otherwise `factory` is called with the internal lock released, its
result is inserted and returned.

Args:
key: The key to look up or insert.
factory: The factory to call and get default value from if ``key`` is not in the cache.

Warning:
`factory` must not call back into this cache (deadlock risk) or block
for long. If `factory` raises, nothing is inserted and the exception
if two threads miss the same key at once, `factory` can run
more than once; the value inserted first wins and is returned to
both. If `factory` raises, nothing is inserted and the exception
propagates.
"""
...
Expand Down Expand Up @@ -1441,16 +1446,17 @@ class TTLCache(BaseCacheImpl[KT, VT]):
"""
Get `key`s value, or automatically create and insert one via `factory`.
If `key` exists, its current value is returned and `factory` is not called.
Otherwise `factory` is called exactly once under an internal lock, its
Otherwise `factory` is called with the internal lock released, its
result is inserted and returned.

Args:
key: The key to look up or insert.
factory: The factory to call and get default value from if ``key`` is not in the cache.

Warning:
`factory` must not call back into this cache (deadlock risk) or block
for long. If `factory` raises, nothing is inserted and the exception
if two threads miss the same key at once, `factory` can run
more than once; the value inserted first wins and is returned to
both. If `factory` raises, nothing is inserted and the exception
propagates.
"""
...
Expand Down Expand Up @@ -1708,7 +1714,7 @@ class VTTLCache(BaseCacheImpl[KT, VT]):
"""
Get `key`s value, or automatically create and insert one via `factory`.
If `key` exists, its current value is returned and `factory` is not called.
Otherwise `factory` is called exactly once under an internal lock, its
Otherwise `factory` is called with the internal lock released, its
result is inserted and returned.

Args:
Expand All @@ -1717,8 +1723,9 @@ class VTTLCache(BaseCacheImpl[KT, VT]):
ttl: An optional time-to-live duration for item.

Warning:
`factory` must not call back into this cache (deadlock risk) or block
for long. If `factory` raises, nothing is inserted and the exception
if two threads miss the same key at once, `factory` can run
more than once; the value inserted first wins and is returned to
both. If `factory` raises, nothing is inserted and the exception
propagates.
"""
...
Expand Down
21 changes: 16 additions & 5 deletions src/pyclasses/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,12 @@ impl PyCache {
/// Get `key`s value, or automatically create and insert one via `factory`.
///
/// If `key` exists, its current value is returned and `factory` is not called.
/// Otherwise `factory` is called exactly once under an internal lock, its
/// Otherwise `factory` is called with the internal lock released, its
/// result is inserted and returned.
///
/// Warning: `factory` must not call back into this cache (deadlock risk) or block
/// for long. If `factory` raises, nothing is inserted and the exception
/// Warning: if two threads miss the same key at once, `factory` can run
/// more than once; the value inserted first wins and is returned to
/// both. If `factory` raises, nothing is inserted and the exception
/// propagates.
fn setdefault_with(
&self,
Expand All @@ -378,14 +379,24 @@ impl PyCache {

let inner = self.0.get();
let shared = inner.shared();

{
let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}
}

// `factory` is Python code: a GC pass inside it would deadlock on `__traverse__`
let default_object = factory.call0(py)?;

let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}

let default_object = factory.call0(py)?;

let handle = nopolicy::Handle::with_precomputed_hash_key(
py,
shared.getsizeof(),
Expand Down
21 changes: 16 additions & 5 deletions src/pyclasses/fifocache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,12 @@ impl PyFIFOCache {
/// Get `key`s value, or automatically create and insert one via `factory`.
///
/// If `key` exists, its current value is returned and `factory` is not called.
/// Otherwise `factory` is called exactly once under an internal lock, its
/// Otherwise `factory` is called with the internal lock released, its
/// result is inserted and returned.
///
/// Warning: `factory` must not call back into this cache (deadlock risk) or block
/// for long. If `factory` raises, nothing is inserted and the exception
/// Warning: if two threads miss the same key at once, `factory` can run
/// more than once; the value inserted first wins and is returned to
/// both. If `factory` raises, nothing is inserted and the exception
/// propagates.
fn setdefault_with(
&self,
Expand All @@ -384,14 +385,24 @@ impl PyFIFOCache {

let inner = self.0.get();
let shared = inner.shared();

{
let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}
}

// `factory` is Python code: a GC pass inside it would deadlock on `__traverse__`
let default_object = factory.call0(py)?;

let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}

let default_object = factory.call0(py)?;

let handle = fifopolicy::Handle::with_precomputed_hash_key(
py,
shared.getsizeof(),
Expand Down
21 changes: 16 additions & 5 deletions src/pyclasses/lfucache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,11 +384,12 @@ impl PyLFUCache {
/// Get `key`s value, or automatically create and insert one via `factory`.
///
/// If `key` exists, its current value is returned and `factory` is not called.
/// Otherwise, `factory` is called exactly once under an internal lock, its
/// Otherwise, `factory` is called with the internal lock released, its
/// result is inserted and returned.
///
/// Warning: `factory` must not call back into this cache (deadlock risk) or block
/// for long. If `factory` raises, nothing is inserted and the exception
/// Warning: if two threads miss the same key at once, `factory` can run
/// more than once; the value inserted first wins and is returned to
/// both. If `factory` raises, nothing is inserted and the exception
/// propagates.
fn setdefault_with(
&self,
Expand All @@ -403,14 +404,24 @@ impl PyLFUCache {

let inner = self.0.get();
let shared = inner.shared();

{
let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}
}

// `factory` is Python code: a GC pass inside it would deadlock on `__traverse__`
let default_object = factory.call0(py)?;

let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}

let default_object = factory.call0(py)?;

let handle = lfupolicy::FrequencyHandle::with_precomputed_hash_key(
py,
shared.getsizeof(),
Expand Down
21 changes: 16 additions & 5 deletions src/pyclasses/lrucache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,12 @@ impl PyLRUCache {
/// Get `key`s value, or automatically create and insert one via `factory`.
///
/// If `key` exists, its current value is returned and `factory` is not called.
/// Otherwise `factory` is called exactly once under an internal lock, its
/// Otherwise `factory` is called with the internal lock released, its
/// result is inserted and returned.
///
/// Warning: `factory` must not call back into this cache (deadlock risk) or block
/// for long. If `factory` raises, nothing is inserted and the exception
/// Warning: if two threads miss the same key at once, `factory` can run
/// more than once; the value inserted first wins and is returned to
/// both. If `factory` raises, nothing is inserted and the exception
/// propagates.
fn setdefault_with(
&self,
Expand All @@ -411,14 +412,24 @@ impl PyLRUCache {

let inner = self.0.get();
let shared = inner.shared();

{
let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}
}

// `factory` is Python code: a GC pass inside it would deadlock on `__traverse__`
let default_object = factory.call0(py)?;

let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}

let default_object = factory.call0(py)?;

let handle = lrupolicy::Handle::with_precomputed_hash_key(
py,
shared.getsizeof(),
Expand Down
21 changes: 16 additions & 5 deletions src/pyclasses/rrcache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,11 +363,12 @@ impl PyRRCache {
/// Get `key`s value, or automatically create and insert one via `factory`.
///
/// If `key` exists, its current value is returned and `factory` is not called.
/// Otherwise `factory` is called exactly once under an internal lock, its
/// Otherwise `factory` is called with the internal lock released, its
/// result is inserted and returned.
///
/// Warning: `factory` must not call back into this cache (deadlock risk) or block
/// for long. If `factory` raises, nothing is inserted and the exception
/// Warning: if two threads miss the same key at once, `factory` can run
/// more than once; the value inserted first wins and is returned to
/// both. If `factory` raises, nothing is inserted and the exception
/// propagates.
fn setdefault_with(
&self,
Expand All @@ -382,14 +383,24 @@ impl PyRRCache {

let inner = self.0.get();
let shared = inner.shared();

{
let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}
}

// `factory` is Python code: a GC pass inside it would deadlock on `__traverse__`
let default_object = factory.call0(py)?;

let mut policy = inner.policy();

if let Some(x) = policy.get(py, &key)? {
return Ok(x.value().clone_ref(py));
}

let default_object = factory.call0(py)?;

let handle = rrpolicy::Handle::with_precomputed_hash_key(
py,
shared.getsizeof(),
Expand Down
Loading