Skip to content

LruCache clean ups and optimizations #13618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 22, 2014
Merged

LruCache clean ups and optimizations #13618

merged 3 commits into from
Apr 22, 2014

Conversation

yuriks
Copy link
Contributor

@yuriks yuriks commented Apr 19, 2014

Just a few space saving optimizations that end up making the code less cluttered too. I'd like to someone to review the last commit closely, I don't have much experience with writing unsafe code, I had someone walk me through how to use cast::forget in IRC.

yuriks added 2 commits April 18, 2014 03:39
Instead of allocating both head and tail nodes for the ends of the node
list, a single node can be allocated and linked circularly instead,
making it act as both the head and the tail of the list at the same
time.
key: None,
value: None,
key: unsafe { mem::init() },
value: unsafe { mem::init() },
next: ptr::mut_null(),
prev: ptr::mut_null(),
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this whole function be replaced by a call to mem::uninit? It seems like it should work, as you never inspect the key and value and you immediately overwrite the pointers. I'm not sure if there are any downsides, but it would make this simpler.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i think that works, yes. Is there any particular preference between mem::init and mem::uninit? I had uninit in there before for the fields but shied away from it to reduce any non-determinism. Assuming this has no bugs then it indeed shouldn't make a difference.

Copy link
Contributor

Choose a reason for hiding this comment

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

The init function zeroes the memory. It's easier to find bugs with uninit because valgrind errors will be triggered. Either way is just as unsafe here.

@yuriks
Copy link
Contributor Author

yuriks commented Apr 19, 2014

I've updated the last commit with the changes proposed by @gereeter

@@ -102,41 +93,42 @@ impl<K: Hash + TotalEq, V> LruCache<K, V> {
let cache = LruCache {
map: HashMap::new(),
max_size: capacity,
head: unsafe{ cast::transmute(~LruEntry::<K, V>::new()) },
tail: unsafe{ cast::transmute(~LruEntry::<K, V>::new()) },
head: unsafe{ cast::transmute(~mem::uninit::<LruCache<K, V>>()) },
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be LruEntry instead of LruCache?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch.

LruEntry nodes previously used Option to encapsulate the key and value
fields. This was used merely as a way avoid having values for the sigil
node. Apart from wasting a few bytes for the discriminant, this
cluttered the rest of the code, since these fields always contained
Some on regular nodes as a class invariant.

The Option wrapping was removed, and the values in the sigil field are
initialized using mem::init, so that they don't contain any real data.
bors added a commit that referenced this pull request Apr 22, 2014
Just a few space saving optimizations that end up making the code less cluttered too. I'd like to someone to review the last commit closely, I don't have much experience with writing unsafe code, I had someone walk me through how to use cast::forget in IRC.
@bors bors closed this Apr 22, 2014
@bors bors merged commit 9faef77 into rust-lang:master Apr 22, 2014
@yuriks yuriks deleted the lru-cache branch May 13, 2014 15:19
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.

5 participants