about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-01-27 16:25:36 +0000
committerbors <bors@rust-lang.org>2016-01-27 16:25:36 +0000
commitb2f4c5c596524ceb7b7dcbf6e87105c81a2fa7ac (patch)
treefa8018f86e62c871785a4f25ade295250a55c6ae
parent8256c470a5ec80509071a70dcfba76666c855a1e (diff)
parentd3174ce75112a52082580065b041f8f4330fefa5 (diff)
downloadrust-b2f4c5c596524ceb7b7dcbf6e87105c81a2fa7ac.tar.gz
rust-b2f4c5c596524ceb7b7dcbf6e87105c81a2fa7ac.zip
Auto merge of #31224 - bluss:deque-hashing, r=Gankro
Hash VecDeque in its slice parts

Use .as_slices() for a more efficient code path in VecDeque's Hash impl.

This still hashes the elements in the same order.

Before/after timing of VecDeque hashing 1024 elements of u8 and
u64 shows that the vecdeque now can match the Vec
(test_hashing_vec_of_u64 is the Vec run).

```
before

test test_hashing_u64        ... bench:  14,031 ns/iter (+/- 236) = 583 MB/s
test test_hashing_u8         ... bench:   7,887 ns/iter (+/- 65) = 129 MB/s
test test_hashing_vec_of_u64 ... bench:   6,578 ns/iter (+/- 76) = 1245 MB/s

after

running 5 tests
test test_hashing_u64        ... bench:   6,495 ns/iter (+/- 52) = 1261 MB/s
test test_hashing_u8         ... bench:     851 ns/iter (+/- 16) = 1203 MB/s
test test_hashing_vec_of_u64 ... bench:   6,499 ns/iter (+/- 59) = 1260 MB/s
```
-rw-r--r--src/libcollections/vec_deque.rs6
-rw-r--r--src/libcollectionstest/vec_deque.rs19
2 files changed, 22 insertions, 3 deletions
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 394f7a97598..f434053390e 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -1994,9 +1994,9 @@ impl<A: Ord> Ord for VecDeque<A> {
 impl<A: Hash> Hash for VecDeque<A> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         self.len().hash(state);
-        for elt in self {
-            elt.hash(state);
-        }
+        let (a, b) = self.as_slices();
+        Hash::hash_slice(a, state);
+        Hash::hash_slice(b, state);
     }
 }
 
diff --git a/src/libcollectionstest/vec_deque.rs b/src/libcollectionstest/vec_deque.rs
index 5f587789bd8..a50886bfdf3 100644
--- a/src/libcollectionstest/vec_deque.rs
+++ b/src/libcollectionstest/vec_deque.rs
@@ -606,6 +606,25 @@ fn test_hash() {
 }
 
 #[test]
+fn test_hash_after_rotation() {
+    // test that two deques hash equal even if elements are laid out differently
+    let len = 28;
+    let mut ring: VecDeque<i32> = (0..len as i32).collect();
+    let orig = ring.clone();
+    for _ in 0..ring.capacity() {
+        // shift values 1 step to the right by pop, sub one, push
+        ring.pop_front();
+        for elt in &mut ring {
+            *elt -= 1;
+        }
+        ring.push_back(len - 1);
+        assert_eq!(::hash(&orig), ::hash(&ring));
+        assert_eq!(orig, ring);
+        assert_eq!(ring, orig);
+    }
+}
+
+#[test]
 fn test_ord() {
     let x = VecDeque::new();
     let mut y = VecDeque::new();