{"id":13595365,"url":"https://github.com/marmeladema/clru-rs","last_synced_at":"2025-04-07T17:10:57.541Z","repository":{"id":42982340,"uuid":"307533802","full_name":"marmeladema/clru-rs","owner":"marmeladema","description":"An LRU cache implementation with constant time operations and weighted semantic.","archived":false,"fork":false,"pushed_at":"2024-05-02T21:26:47.000Z","size":72,"stargazers_count":39,"open_issues_count":2,"forks_count":8,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-25T05:08:26.457Z","etag":null,"topics":["cache","hashmap","lru","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marmeladema.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-26T23:41:55.000Z","updated_at":"2024-10-13T11:02:16.000Z","dependencies_parsed_at":"2024-01-16T22:19:04.439Z","dependency_job_id":"fb99b15f-b02b-4ee5-9058-c3b2e2055bfe","html_url":"https://github.com/marmeladema/clru-rs","commit_stats":{"total_commits":63,"total_committers":3,"mean_commits":21.0,"dds":"0.031746031746031744","last_synced_commit":"e91248107963bf1d636402e6678fef893ce1a2da"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marmeladema%2Fclru-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marmeladema%2Fclru-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marmeladema%2Fclru-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marmeladema%2Fclru-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marmeladema","download_url":"https://codeload.github.com/marmeladema/clru-rs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246481005,"owners_count":20784458,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","hashmap","lru","rust"],"created_at":"2024-08-01T16:01:48.653Z","updated_at":"2025-03-31T14:14:24.164Z","avatar_url":"https://github.com/marmeladema.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# CLru\n\n[![Actions](https://github.com/marmeladema/clru-rs/workflows/Rust/badge.svg)](https://github.com/marmeladema/clru-rs/actions)\n[![Crate](https://img.shields.io/crates/v/clru)](https://crates.io/crates/clru)\n[![Docs](https://docs.rs/clru/badge.svg)](https://docs.rs/clru)\n[![License](https://img.shields.io/crates/l/clru)](LICENSE)\n\nAnother [LRU cache](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)) implementation in rust.\nIt has two main characteristics that differentiates it from other implementation:\n\n1. It is backed by a [HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html): it\n   offers a O(1) time complexity (amortized average) for common operations like:\n   * `get` / `get_mut`\n   * `put` / `pop`\n   * `peek` / `peek_mut`\n\n2. It is a weighted cache: each key-value pair has a weight and the capacity serves as both as:\n   * a limit to the number of elements\n   * and as a limit to the total weight of its elements\n\n   using the following formula:\n\n   [`CLruCache::len`](https://docs.rs/clru/latest/clru/struct.CLruCache.html#method.len) + [`CLruCache::weight`](https://docs.rs/clru/latest/clru/struct.CLruCache.html#method.weight) \u003c= [`CLruCache::capacity`](https://docs.rs/clru/latest/clru/struct.CLruCache.html#method.capacity)\n\nEven though most operations don't depend on the number of elements in the cache,\n[`CLruCache::put_with_weight`](https://docs.rs/clru/latest/clru/struct.CLruCache.html#method.put_with_weight) has a special behavior: because it needs to make room\nfor the new element, it will remove enough least recently used elements. In the worst\ncase, that will require to fully empty the cache. Additionally, if the weight of the\nnew element is too big, the insertion can fail.\n\nFor the common case of an LRU cache whose elements don't have a weight, a default\n[`ZeroWeightScale`](https://docs.rs/clru/latest/clru/struct.ZeroWeightScale.html)\nis provided and unlocks some useful APIs like:\n\n* [`CLruCache::put`](https://docs.rs/clru/latest/clru/struct.CLruCache.html#method.put): an infallible insertion that will remove a maximum of 1 element.\n* [`CLruCache::put_or_modify`](https://docs.rs/clru/latest/clru/struct.CLruCache.html#method.put_or_modify): a conditional insertion or modification flow similar to the entry API of [`HashMap`].\n* [`CLruCache::try_put_or_modify`](https://docs.rs/clru/latest/clru/struct.CLruCache.html#method.try_put_or_modify): fallible version of `CLruCache::put_or_modify`.\n* All APIs that allow to retrieve a mutable reference to a value (e.g.: [`CLruCache::get_mut`](https://docs.rs/clru/latest/clru/struct.CLruCache.html#method.get_mut)).\n\n## Disclaimer\n\nMost of the API, documentation, examples and tests have been heavily inspired by the [lru](https://github.com/jeromefroe/lru-rs) crate.\nI want to thank [jeromefroe](https://github.com/jeromefroe/) for his work without which this crate would have probably never has been released.\n\n\n## Differences with [lru](https://github.com/jeromefroe/lru-rs)\n\nThe main differences are:\n* Smaller amount of unsafe code. Unsafe code is not bad in itself as long as it is thoroughly reviewed and understood but can be surprisingly hard to get right. Reducing the amount of unsafe code should hopefully reduce bugs or undefined behaviors.\n* API closer to the standard [HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html) collection which allows to lookup with `Borrow`-ed version of the key.\n\n## Example\n\nBelow are simple examples of how to instantiate and use this LRU cache.\n\n### Using the default [`ZeroWeightScale`](https://docs.rs/clru/latest/clru/struct.ZeroWeightScale.html):\n\n```rust\n\nuse std::num::NonZeroUsize;\nuse clru::CLruCache;\n\nlet mut cache = CLruCache::new(NonZeroUsize::new(2).unwrap());\ncache.put(\"apple\".to_string(), 3);\ncache.put(\"banana\".to_string(), 2);\n\nassert_eq!(cache.get(\"apple\"), Some(\u00263));\nassert_eq!(cache.get(\"banana\"), Some(\u00262));\nassert!(cache.get(\"pear\").is_none());\n\nassert_eq!(cache.put(\"banana\".to_string(), 4), Some(2));\nassert_eq!(cache.put(\"pear\".to_string(), 5), None);\n\nassert_eq!(cache.get(\"pear\"), Some(\u00265));\nassert_eq!(cache.get(\"banana\"), Some(\u00264));\nassert!(cache.get(\"apple\").is_none());\n\n{\n    let v = cache.get_mut(\"banana\").unwrap();\n    *v = 6;\n}\n\nassert_eq!(cache.get(\"banana\"), Some(\u00266));\n```\n\n### Using a custom [`WeightScale`](https://docs.rs/clru/latest/clru/trait.WeightScale.html) implementation:\n\n```rust\n\nuse std::num::NonZeroUsize;\nuse clru::{CLruCache, CLruCacheConfig, WeightScale};\n\nstruct CustomScale;\n\nimpl WeightScale\u003cString, \u0026str\u003e for CustomScale {\n    fn weight(\u0026self, _key: \u0026String, value: \u0026\u0026str) -\u003e usize {\n        value.len()\n    }\n}\n\nlet mut cache = CLruCache::with_config(\n    CLruCacheConfig::new(NonZeroUsize::new(6).unwrap()).with_scale(CustomScale),\n);\n\nassert_eq!(cache.put_with_weight(\"apple\".to_string(), \"red\").unwrap(), None);\nassert_eq!(\n    cache.put_with_weight(\"apple\".to_string(), \"green\").unwrap(),\n    Some(\"red\")\n);\n\nassert_eq!(cache.len(), 1);\nassert_eq!(cache.get(\"apple\"), Some(\u0026\"green\"));\n```\n\n## Tests\n\nEach contribution is tested with regular compiler, miri, and 4 flavors of sanitizer (address, memory, thread and leak).\nThis should help catch bugs sooner than later.\n\n## TODO\n\n* improve documentation and add examples\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarmeladema%2Fclru-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarmeladema%2Fclru-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarmeladema%2Fclru-rs/lists"}