Skip to content

Commit

Permalink
Add support for returning displaced entries for re-use.
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron authored and mbrubeck committed Aug 22, 2021
1 parent 9f0ca65 commit a9e01cd
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@ categories = ["data-structures", "no-std"]
readme = "README.md"
include = ["src/**/*", "LICENSE", "README.md"]

[features]
default = []
std = []

[dependencies]
arrayvec = { version = "0.7", default-features = false }
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ Servo's style system.
insertion, and `O(n)` lookup. It does not require an allocator and can be
used in `no_std` crates. It is implemented in 100% safe Rust.

## Cargo Features

By default, this crate won't need the standard library. However, if the `std` cargo feature is enabled, `insert()` will
return a replaced value which allows to reuse memory it may have contained.

* [Documentation](https://docs.rs/uluru)
* [crates.io](https://crates.io/crates/uluru)
* [Release notes](https://github.com/servo/uluru/releases)
29 changes: 28 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![no_std]
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(unsafe_code)]

//! A simple, fast, least-recently-used (LRU) cache.
Expand Down Expand Up @@ -96,6 +96,33 @@ impl<T, const N: usize> LRUCache<T, N> {
///
/// This item becomes the front (most-recently-used) item in the cache. If the cache is full,
/// the back (least-recently-used) item will be removed.
#[cfg(feature = "std")]
pub fn insert(&mut self, val: T) -> Option<T> {
let entry = Entry {
val,
prev: 0,
next: 0,
};

// If the cache is full, replace the oldest entry. Otherwise, add an entry.
let (new_head, previous_entry) = if self.entries.len() == self.entries.capacity() {
let i = self.pop_back();
let previous_entry = std::mem::replace(&mut self.entries[i as usize], entry);
(i, Some(previous_entry.val))
} else {
self.entries.push(entry);
(self.entries.len() as u16 - 1, None)
};

self.push_front(new_head);
previous_entry
}

/// Insert a given key in the cache.
///
/// This item becomes the front (most-recently-used) item in the cache. If the cache is full,
/// the back (least-recently-used) item will be removed.
#[cfg(not(feature = "std"))]
pub fn insert(&mut self, val: T) {
let entry = Entry {
val,
Expand Down

0 comments on commit a9e01cd

Please sign in to comment.