Skip to content

Commit c5ba150

Browse files
committed
---
yaml --- r: 150973 b: refs/heads/try2 c: 9faef77 h: refs/heads/master i: 150971: 5bf2c45 v: v3
1 parent 2dba3d0 commit c5ba150

File tree

2 files changed

+22
-43
lines changed

2 files changed

+22
-43
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: ad4062e8af18b9631291e2c50bf0370ad2768e19
8+
refs/heads/try2: 9faef77b237baf8cf9908c799be162ab28a9aa84
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libcollections/lru_cache.rs

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,18 @@ use std::cast;
4141
use std::container::Container;
4242
use std::hash::Hash;
4343
use std::fmt;
44+
use std::mem;
4445
use std::ptr;
4546

4647
use HashMap;
4748

4849
struct KeyRef<K> { k: *K }
4950

5051
struct LruEntry<K, V> {
51-
key: Option<K>,
52-
value: Option<V>,
5352
next: *mut LruEntry<K, V>,
5453
prev: *mut LruEntry<K, V>,
54+
key: K,
55+
value: V,
5556
}
5657

5758
/// An LRU Cache.
@@ -76,19 +77,10 @@ impl<K: Eq> Eq for KeyRef<K> {
7677
impl<K: TotalEq> TotalEq for KeyRef<K> {}
7778

7879
impl<K, V> LruEntry<K, V> {
79-
fn new() -> LruEntry<K, V> {
80+
fn new(k: K, v: V) -> LruEntry<K, V> {
8081
LruEntry {
81-
key: None,
82-
value: None,
83-
next: ptr::mut_null(),
84-
prev: ptr::mut_null(),
85-
}
86-
}
87-
88-
fn with_key_value(k: K, v: V) -> LruEntry<K, V> {
89-
LruEntry {
90-
key: Some(k),
91-
value: Some(v),
82+
key: k,
83+
value: v,
9284
next: ptr::mut_null(),
9385
prev: ptr::mut_null(),
9486
}
@@ -101,7 +93,7 @@ impl<K: Hash + TotalEq, V> LruCache<K, V> {
10193
let cache = LruCache {
10294
map: HashMap::new(),
10395
max_size: capacity,
104-
head: unsafe{ cast::transmute(~LruEntry::<K, V>::new()) },
96+
head: unsafe{ cast::transmute(~mem::uninit::<LruEntry<K, V>>()) },
10597
};
10698
unsafe {
10799
(*cache.head).next = cache.head;
@@ -114,23 +106,24 @@ impl<K: Hash + TotalEq, V> LruCache<K, V> {
114106
pub fn put(&mut self, k: K, v: V) {
115107
let (node_ptr, node_opt) = match self.map.find_mut(&KeyRef{k: &k}) {
116108
Some(node) => {
117-
node.value = Some(v);
109+
node.value = v;
118110
let node_ptr: *mut LruEntry<K, V> = &mut **node;
119111
(node_ptr, None)
120112
}
121113
None => {
122-
let mut node = ~LruEntry::with_key_value(k, v);
114+
let mut node = ~LruEntry::new(k, v);
123115
let node_ptr: *mut LruEntry<K, V> = &mut *node;
124116
(node_ptr, Some(node))
125117
}
126118
};
127119
match node_opt {
128120
None => {
121+
// Existing node, just update LRU position
129122
self.detach(node_ptr);
130123
self.attach(node_ptr);
131124
}
132125
Some(node) => {
133-
let keyref = unsafe { (*node_ptr).key.as_ref().unwrap() };
126+
let keyref = unsafe { &(*node_ptr).key };
134127
self.map.swap(KeyRef{k: keyref}, node);
135128
self.attach(node_ptr);
136129
if self.len() > self.capacity() {
@@ -146,12 +139,7 @@ impl<K: Hash + TotalEq, V> LruCache<K, V> {
146139
None => (None, None),
147140
Some(node) => {
148141
let node_ptr: *mut LruEntry<K, V> = &mut **node;
149-
unsafe {
150-
match (*node_ptr).value {
151-
None => (None, None),
152-
Some(ref value) => (Some(value), Some(node_ptr))
153-
}
154-
}
142+
(Some(unsafe { &(*node_ptr).value }), Some(node_ptr))
155143
}
156144
};
157145
match node_ptr_opt {
@@ -168,7 +156,7 @@ impl<K: Hash + TotalEq, V> LruCache<K, V> {
168156
pub fn pop(&mut self, k: &K) -> Option<V> {
169157
match self.map.pop(&KeyRef{k: k}) {
170158
None => None,
171-
Some(lru_entry) => lru_entry.value
159+
Some(lru_entry) => Some(lru_entry.value)
172160
}
173161
}
174162

@@ -191,12 +179,7 @@ impl<K: Hash + TotalEq, V> LruCache<K, V> {
191179
if self.len() > 0 {
192180
let lru = unsafe { (*self.head).prev };
193181
self.detach(lru);
194-
unsafe {
195-
match (*lru).key {
196-
None => (),
197-
Some(ref k) => { self.map.pop(&KeyRef{k: k}); }
198-
}
199-
}
182+
self.map.pop(&KeyRef{k: unsafe { &(*lru).key }});
200183
}
201184
}
202185

@@ -229,19 +212,11 @@ impl<A: fmt::Show + Hash + TotalEq, B: fmt::Show> fmt::Show for LruCache<A, B> {
229212
if i > 0 { try!(write!(f.buf, ", ")) }
230213
unsafe {
231214
cur = (*cur).next;
232-
match (*cur).key {
233-
// should never print nil
234-
None => try!(write!(f.buf, "nil")),
235-
Some(ref k) => try!(write!(f.buf, "{}", *k)),
236-
}
215+
try!(write!(f.buf, "{}", (*cur).key));
237216
}
238217
try!(write!(f.buf, ": "));
239218
unsafe {
240-
match (*cur).value {
241-
// should never print nil
242-
None => try!(write!(f.buf, "nil")),
243-
Some(ref value) => try!(write!(f.buf, "{}", *value)),
244-
}
219+
try!(write!(f.buf, "{}", (*cur).value));
245220
}
246221
}
247222
write!(f.buf, r"\}")
@@ -266,7 +241,11 @@ impl<K: Hash + TotalEq, V> Mutable for LruCache<K, V> {
266241
impl<K, V> Drop for LruCache<K, V> {
267242
fn drop(&mut self) {
268243
unsafe {
269-
let _: ~LruEntry<K, V> = cast::transmute(self.head);
244+
let node: ~LruEntry<K, V> = cast::transmute(self.head);
245+
// Prevent compiler from trying to drop the un-initialized field in the sigil node.
246+
let ~LruEntry { key: k, value: v, .. } = node;
247+
cast::forget(k);
248+
cast::forget(v);
270249
}
271250
}
272251
}

0 commit comments

Comments
 (0)