Giter VIP home page Giter VIP logo

lru-cache's Introduction

Rust CI crates.io

WARNING: THIS PROJECT IS IN MAINTENANCE MODE, DUE TO INSUFFICIENT MAINTAINER RESOURCES

It works fine, but will generally no longer be improved.

We are currently only accepting changes which:

  • keep this compiling with the latest versions of Rust or its dependencies.
  • have minimal review requirements, such as documentation changes (so not totally new APIs).

A cache that holds a limited number of key-value pairs.

lru-cache's People

Contributors

apasel422 avatar debris avatar flashcat avatar gankra avatar ignatenkobrain avatar jmagnuson avatar jstnlef avatar reem avatar sfackler avatar xrl avatar zonyitoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

lru-cache's Issues

Limit the cache based on arbitrary measures

Motivation:
My use-case for lru-cache involves inspecting items' heap size. Rather than hack it in, I think it would be beneficial to make the cache adaptable to whatever limit needs to be imposed.

You might have a set of heterogeneous items, each using a different amount of allocation on the heap. Maybe a more general Meter trait might help:

trait Meter<T> {
    fn measure(&self, item: &T) -> usize;
}

The default Meter could be a Count:

struct Count;

impl<T> Meter<T> for Count { 
    fn measure(&self, _: &T) -> usize { 1 }
}

Here's an implementation that would use the HeapSizeOf trait (I'd recommend this one for inclusion under a feature gate as it's generally useful.)

struct HeapSize;

impl<T: HeapSizeOf> Meter<T> for HeapSize {
    fn measure(&self, item: &T) -> usize { item.heap_size_of_children() + ::std::mem::size_of::<T>() }
}

When you add or remove an item, you add or subtract meter.measure(&item) from the maximum respectively. If the metered total exceeds the maximum while adding an item, other items must be removed in a loop until the total falls below the limit.

Caveats:

  • get_mut or interior mutability could allow items to be altered such that their measure at insertion time differs from their measure at removal. We could add a UniformMeter<T> which takes no reference to individual items when measuring -- indicating that the measurement is unrelated to item size. get_mut might only be implemented when the meter is uniform, while fn get(&mut self, key: &Q) -> Option<&T> would serve as an alternative implemented for all caches. This doesn't solve the interior mutability issue, but that can be addressed the same way as in HashMap: documentation specifying that it's a logic error to modify the value such that its measure would be altered.
  • insert can remove multiple items -- how do we return each of them to the caller efficiently? (maybe an iterator?)

Alternatively:

  • check the measure before and after get_mut and adjust the total correspondingly. The issue here is that it would need to be done through a CacheHandle<'a, T: 'a> which contains that logic in its destructor. This would break backwards compatibility, and would need to handle returning displaced items if the size grows.
  • re-measure every item in the cache whenever necessary. this seems prohibitively expensive

Looking forward to your comments and naming suggestions below.

Make `remove_lru()` public?

This is more of a feature request. But would it be possible to make remove_lru() public?
I've been missing this when implementing an adaptative replacement cache.

Thanks!

Capacity based on entries size

I made a fork that handle cache capacity using entries size rather than entries number.
I found it useful to keep control of memory usage, when cache entries are collections or strings with different legths.

I don't think it is should be merged back (that's why an issue instead of a PR), but I was wondering if you'd like to take it as a contain-rs project. Let me know!

Is it possible to do a immutable borrow?

Something like:

extern crate lru_cache;       

use lru_cache::LruCache;
use std::sync::RwLock;

fn main() {                   
    let mut cache = LruCache::new(2);
    cache.insert(1, 10);

    let rwlock = RwLock::new(cache);
    let lock = rwlock.read().unwrap();
    let value = lock.get_mut(&1);    
    println!("{:?}", value);
}

I got:

error: cannot borrow immutable borrowed content as mutable
  --> src\main.rs:12:17
   |
12 |     let value = lock.get_mut(&1);
   |                 ^^^^

Version on crates.io 8 months old

Please publish some of the latest changes to crates.io. I've been forced to set the dependency to point to the github repository for the time being in my project in order to use remove_lru.

Please consider fixing the linked-hash-map minimal version to at least 0.5.3

Issue

use lru_cache::LruCache;

fn main() {}

#[test]
fn test_panics() {
    let mut l = LruCache::new(10);
    l.insert(1, false);
}
cargo test

This code panics when the linked-hash-map crate used by lru_cache is under version 0.5.3, because it contains uninitialized memory allocation.
The uninitialized memory problem seems to be fixed for version 0.5.3, but because the dependency is specified in Cargo.toml as

linked-hash-map = "0.5"

It means that cargo is free to choose any version >=0.5.0, and if the 0.5.1 or 0.5.2 versions are present in the local package cache, they might be picked.

Rewriting it instead as

linked-hash-map = "0.5.3"

and releasing it as new minor version 0.1.3 would fix the problem, as cargo would be forced to pick a version >=0.5.3

dependency update: linked-hash-map 0.3.0 available

Thanks to cargo outdated, I noticed:

cargo outdated
Checking for SemVer compatible updates...Done
Checking for the latest updates...Done
The following dependencies have newer versions available:

    Name                        Project Ver  SemVer Compat  Latest Ver
    lru-cache->linked-hash-map     0.2.1          --          0.3.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.