Skip to content

Commit fadb17a

Browse files
committed
doesnt work by value
1 parent aea2c58 commit fadb17a

File tree

2 files changed

+50
-39
lines changed

2 files changed

+50
-39
lines changed

src/libstd/collections/hash/map.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ impl<K, V, S, H> HashMap<K, V, S>
867867
pub fn iter(&self) -> Iter<K, V> {
868868
Iter {
869869
elems_left: self.table.size(),
870-
inner: self.table.raw_full_buckets(),
870+
inner: Bucket::raw_full_buckets(&self.table),
871871
}
872872
}
873873

@@ -898,7 +898,7 @@ impl<K, V, S, H> HashMap<K, V, S>
898898
pub fn iter_mut(&mut self) -> IterMut<K, V> {
899899
IterMut {
900900
elems_left: self.table.size(),
901-
inner: self.table.raw_full_buckets_mut(),
901+
inner: Bucket::raw_full_buckets(&mut self.table),
902902
}
903903
}
904904

src/libstd/collections/hash/table.rs

+48-37
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ use cmp;
1717
use hash::{Hash, Hasher};
1818
use iter::{Iterator, IteratorExt, ExactSizeIterator, count};
1919
use marker::{Copy, Sized};
20-
use mem::{min_align_of, size_of};
21-
use mem;
20+
use mem::{self, min_align_of, size_of};
2221
use num::{Int, UnsignedInt};
2322
use ops::{Deref, DerefMut, Drop};
24-
use option::Option;
25-
use option::Option::{Some, None};
23+
use option::Option::{self, Some, None};
2624
use ptr::{self, Unique, PtrExt, copy_memory, copy_nonoverlapping_memory, zero_memory};
25+
use result::Result::{self, Ok, Err};
2726
use rt::heap::{allocate, deallocate, reallocate_inplace};
2827
use collections::hash_state::HashState;
2928
use core::nonzero::NonZero;
@@ -95,6 +94,7 @@ impl<K,V,M:Copy,S> Copy for Bucket<K,V,M,S> {}
9594
mod bucket {
9695
pub enum Empty {}
9796
pub enum Full {}
97+
pub enum TableIsEmpty {}
9898
}
9999

100100
pub type EmptyBucket<K, V, M> = Bucket<K, V, M, bucket::Empty>;
@@ -151,6 +151,14 @@ fn can_alias_safehash_as_option() {
151151
assert_eq!(size_of::<SafeHash>(), size_of::<Option<SafeHash>>())
152152
}
153153

154+
impl<K, V> Deref for RawTable<K, V> {
155+
type Target = RawTable<K, V>;
156+
157+
fn deref(&self) -> &RawTable<K, V> {
158+
self
159+
}
160+
}
161+
154162
impl<K, V, M> RawBucket<K, V, M> {
155163
unsafe fn offset(self, count: int) -> RawBucket<K, V, M> {
156164
RawBucket {
@@ -210,29 +218,47 @@ impl<K, V, M, S> Bucket<K, V, M, S> {
210218
pub fn index(&self) -> uint {
211219
self.0.idx
212220
}
221+
/// Turn the bucket into an iterator over full buckets.
222+
pub fn into_iter(self) -> RawFullBuckets<K, V, M> {
223+
RawFullBuckets {
224+
raw: self.raw,
225+
hashes_end: unsafe {
226+
self.raw.hash.offset(self.0.capacity as int - self.index() as int)
227+
},
228+
table: self.table,
229+
}
230+
}
213231
}
214232

215233
impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
216234
pub fn new(table: M, hash: SafeHash) -> Option<Bucket<K, V, M>> {
217-
Bucket::at_index(table, *hash as usize)
235+
Bucket::at_index(table, *hash as usize).ok()
218236
}
219237

220-
pub fn at_index(table: M, ib_index: uint) -> Option<Bucket<K, V, M>> {
238+
pub fn at_index(table: M, ib_index: uint)
239+
-> Result<Bucket<K, V, M>, Bucket<K, V, M, bucket::TableIsEmpty>>
240+
{
241+
let ib_index = ib_index & (table.capacity() - 1);
242+
let bb = BareBucket {
243+
raw: unsafe {
244+
table.first_bucket_raw().offset(ib_index as int)
245+
},
246+
idx: ib_index,
247+
capacity: table.capacity(),
248+
table: table,
249+
};
250+
221251
if table.capacity() == 0 {
222-
None
252+
Err(Bucket(bb))
223253
} else {
224-
let ib_index = ib_index & (table.capacity() - 1);
225-
Some(Bucket(BareBucket {
226-
raw: unsafe {
227-
table.first_bucket_raw().offset(ib_index as int)
228-
},
229-
idx: ib_index,
230-
capacity: table.capacity(),
231-
table: table
232-
}))
254+
Ok(Bucket(bb))
233255
}
234256
}
235257

258+
pub fn raw_full_buckets(table: M) -> RawFullBuckets<K, V, M> {
259+
Bucket::at_index(table, 0).map(|b| b.into_iter()).unwrap_or_else(|b| b.into_iter())
260+
}
261+
236262
/// Narrows down the range of iteration, which must be a power of 2.
237263
pub fn iter_to(mut self, limit: usize) -> Bucket<K, V, M> {
238264
assert!(limit <= self.capacity);
@@ -461,7 +487,7 @@ impl<K, V> RawTable<K, V> {
461487
}
462488

463489
#[inline]
464-
fn first_bucket_raw<M>(&self) -> RawBucket<K, V, M> {
490+
unsafe fn first_bucket_raw<M>(&self) -> RawBucket<K, V, M> {
465491
if self.capacity() == 0 {
466492
RawBucket {
467493
hash: ptr::null_mut(),
@@ -539,18 +565,10 @@ impl<K, V> RawTable<K, V> {
539565
self.size
540566
}
541567

542-
pub fn raw_full_buckets(&self) -> RawFullBuckets<K, V, &RawTable<K, V>> {
543-
full_buckets(self.first_bucket_raw(), self.capacity, self)
544-
}
545-
546-
pub fn raw_full_buckets_mut(&mut self) -> RawFullBuckets<K, V, &mut RawTable<K, V>> {
547-
full_buckets(self.first_bucket_raw(), self.capacity, self)
548-
}
549-
550568
pub fn into_iter(self) -> IntoIter<K, V> {
551569
// Replace the marker regardless of lifetime bounds on parameters.
552570
IntoIter {
553-
iter: full_buckets(self.first_bucket_raw(), self.capacity, self)
571+
iter: Bucket::raw_full_buckets(self),
554572
}
555573
}
556574
}
@@ -596,14 +614,7 @@ fn align<K, V>() -> usize {
596614
cmp::max(mem::min_align_of::<(K, V)>(), mem::min_align_of::<u64>())
597615
}
598616

599-
pub fn full_buckets<K, V, M>(raw: RawBucket<K, V, M>, cap: usize, t: M) -> RawFullBuckets<K, V, M> {
600-
RawFullBuckets {
601-
raw: raw,
602-
hashes_end: unsafe { raw.hash.offset(cap as int) },
603-
table: t,
604-
}
605-
}
606-
617+
/// A newtyped RawBucket. Not copyable.
607618
pub struct RawFullBucket<K, V, M>(RawBucket<K, V, M>);
608619

609620
impl<K, V, M> Deref for RawFullBucket<K, V, M> {
@@ -670,7 +681,7 @@ impl<K, V> Iterator for IntoIter<K, V> {
670681
self.iter.next().map(|bucket| {
671682
self.iter.table.size -= 1;
672683
unsafe {
673-
let (k, v) = ptr::read(bucket.kval as *const (K, V));
684+
let (k, v) = ptr::read(bucket.kval);
674685
(*(bucket.hash as *mut SafeHash), k, v)
675686
}
676687
})
@@ -742,8 +753,8 @@ impl<K, V> Drop for RawTable<K, V> {
742753
// Avoid double drop of elements that have been already moved out.
743754
unsafe {
744755
if self.size != 0 {
745-
for bucket in self.raw_full_buckets_mut() {
746-
ptr::read(bucket.kval as *const (K, V));
756+
for bucket in Bucket::raw_full_buckets(self) {
757+
ptr::read(bucket.kval);
747758
}
748759
}
749760
}

0 commit comments

Comments
 (0)