addressable_pairing_heap/
lib.rs

1#![cfg_attr(all(feature = "bench", test), feature(test))]
2
3#![deny(unused_imports)]
4#![deny(missing_docs)]
5
6//! An addressable pairing heap implementation for Rust.
7//! 
8//! Addressable heaps return handles to stored elements that make it possible
9//! to query and edit them. For example this allows for the `decrease_key(h: Handle)` method
10//! that decreases the key (priority) of the element that is associated with the
11//! given handle.
12//! 
13//! This implementation stores elements within a `Stash` that allocates elements
14//! densely within an array.
15//!
16//! It is possible to use custom types as the underlying `Key` type by implementing
17//! the `Key` trait.
18
19#[cfg(all(feature = "bench", test))]
20extern crate test;
21extern crate rand;
22
23extern crate stash;
24extern crate unreachable;
25
26/// A handle to access stored elements within an addressable pairing heap.
27#[derive(Debug, Copy, Clone, PartialEq, Eq)]
28pub struct Handle(usize);
29
30impl Handle {
31	#[inline]
32	fn undef() -> Self {
33		Handle(usize::max_value())
34	}
35
36	#[inline]
37	fn is_undef(self) -> bool {
38		self == Handle::undef()
39	}
40
41	#[inline]
42	fn to_usize(self) -> usize { self.0 }
43}
44
45/// Represents a trait for keys within an addressable pairing heap.
46/// 
47/// A user can use custom type for the key type by implementing this trait.
48/// 
49/// This trait is implicitely implemented already for all types that 
50/// are `Copy`, `PartialOrd` and `Ord`.
51pub trait Key: Copy + PartialOrd + Ord {}
52impl<T> Key for T where T: Copy + PartialOrd + Ord {}
53
54/// An entry within an addressable pairing heap.
55#[derive(Debug, Clone, PartialEq, Eq)]
56struct Entry<T, K> where K: Key {
57	key : K,
58	elem: T
59}
60
61impl<T, K> Entry<T, K>
62	where K: Key
63{
64	#[inline]
65	fn new(key: K, elem: T) -> Self {
66		Entry{
67			key : key,
68			elem: elem
69		}
70	}
71}
72
73#[derive(Debug, Copy, Clone, PartialEq, Eq)]
74enum Position{
75	/// root node at index
76	Root(usize),
77
78	/// child of parent with index
79	Child(Handle, usize)
80}
81
82impl Position {
83	#[inline]
84	fn child(parent: Handle, index: usize) -> Self {
85		Position::Child(parent, index)
86	}
87
88	#[inline]
89	fn root(index: usize) -> Self {
90		Position::Root(index)
91	}
92
93	#[inline]
94	fn is_root(self) -> bool {
95		match self {
96			Position::Root(_) => true,
97			_                 => false
98		}
99	}
100
101	#[inline]
102	fn is_child(self) -> bool {
103		match self {
104			Position::Child(..) => true,
105			_                   => false
106		}
107	}
108}
109
110#[derive(Debug, Clone, PartialEq, Eq)]
111struct Node<T, K>
112	where K: Key
113{
114	pos     : Position,
115	entry   : Entry<T, K>,
116	children: Vec<Handle>
117}
118
119impl<T, K> Node<T, K>
120	where K: Key
121{
122	#[inline]
123	fn new_root(at: usize, entry: Entry<T, K>) -> Self {
124		Node{
125			entry   : entry,
126			pos     : Position::root(at),
127			children: Vec::new()
128		}
129	}
130}
131
132/// Errors that can be caused while using `PairingHeap`.
133#[derive(Debug, Copy, Clone, PartialEq, Eq)]
134pub enum Error {
135	/// Caused when using `decrease_key` method with a `new_key` that is greater than the old one.
136	DecreaseKeyOutOfOrder
137}
138
139/// Generic `Result` type for `PairingHeap` methods.
140pub type Result<T> = ::std::result::Result<T, Error>;
141
142use stash::*;
143
144/// Type alias for `PairingHeap` that has `i64` as default `Key` type.
145pub type DefaultPairingHeap<T> = PairingHeap<T, i64>;
146
147/// An addressable pairing heap implementation.
148/// 
149/// Stores elements with an associated key.
150/// The key can be thought of as the priority of the element that is associated to it.
151/// 
152/// Supports usages like `take_min` that takes the element with the minimum key out of this storage.
153/// 
154/// Inserting elements into this data structure provides the caller with handles
155/// that makes accessing the elements possible - this is called "addressable".
156/// Handles are always local to the associated pairing heap instance and thus should not be
157/// exchanged throughout various instances of pairing heaps.
158/// 
159/// An special feature of addressable pairing heaps is the possibility to explicitely
160/// decrease the key of an already stored element with the `decrease_key` operation which
161/// simply increases the priority of the associated element.
162/// 
163/// It is possible to use different implementations for `Key` as the key type.
164#[derive(Debug, Clone)]
165pub struct PairingHeap<T, K>
166	where K: Key
167{
168	/// Handle to the element with the minimum key within the pairing heap.
169	min: Handle,
170	/// The roots of the ```PairingHeap``` where
171	/// the first root within this ```Vec``` always represents the one with the minimum ```key```.
172	roots: Vec<Handle>,
173
174	/// In the ```data``` vector all elements are stored.
175	/// This indirection to the real data allows for efficient addressable elements via handles.
176	data: Stash<Node<T, K>>
177}
178
179impl<T, K> PairingHeap<T, K>
180	where K: Key
181{
182	/// Creates a new instance of a `PairingHeap`.
183	#[inline]
184	pub fn new() -> Self {
185		PairingHeap{
186			min  : Handle::undef(),
187			roots: Vec::new(),
188			data : Stash::new()
189		}
190	}
191
192	/// Returns the number of elements stored in this `PairingHeap`.
193	#[inline]
194	pub fn len(&self) -> usize {
195		self.data.len()
196	}
197
198	/// Returns true if this `PairingHeap` is empty.
199	#[inline]
200	pub fn is_empty(&self) -> bool {
201		self.len() == 0
202	}
203
204	/// Returns a reference to the `Node` that is associated with the given handle.
205	/// Note that this won't fail on usage for a correct implementation of `PairingHeap`.
206	#[inline]
207	fn node(&self, handle: Handle) -> &Node<T, K> {
208		unsafe{ self.data.get_unchecked(handle.to_usize()) }
209	}
210
211	/// Returns a mutable reference to the `Node` that is associated with the given handle.
212	/// Note that this won't fail on usage for a correct implementation of `PairingHeap`.
213	#[inline]
214	fn node_mut(&mut self, handle: Handle) -> &mut Node<T, K> {
215		unsafe{ self.data.get_unchecked_mut(handle.to_usize()) }
216	}
217
218	/// Links the given `lower` tree under the given `upper` tree thus making `lower`
219	/// a children of `upper`.
220	fn link(&mut self, upper: Handle, lower: Handle) {
221
222		debug_assert!(upper != lower, "cannot link to self!");
223		debug_assert!(self.node(lower).pos.is_root(), "lower cannot have multiple parents!");
224
225		let idx = self.node(upper).children.len();
226		self.node_mut(upper).children.push(lower);
227		self.node_mut(lower).pos = Position::child(upper, idx);
228		self.insert_root(upper);
229	}
230
231	/// Links the element with the lower key over the element with the higher key.
232	/// Thus making one the child of the other.
233	fn union(&mut self, fst: Handle, snd: Handle) {
234		debug_assert!(fst != snd, "cannot union self with itself");
235
236		if self.node(fst).entry.key < self.node(snd).entry.key {
237			self.link(fst, snd)
238		}
239		else {
240			self.link(snd, fst)
241		}
242	}
243
244	/// Pairwise unifies roots in the `PairingHeap` which
245	/// effectively decreases the number of roots to half.
246	fn pairwise_union(&mut self) {
247		let mut roots =
248			::std::mem::replace(&mut self.roots, Vec::new())
249			.into_iter();
250		loop {
251			match (roots.next(), roots.next()) {
252				(Some(fst), Some(snd)) => self.union(fst, snd),
253				(Some(fst), None     ) => self.insert_root(fst),
254				_                      => return
255			}
256		}
257	}
258
259	/// Updates the internal pointer to the current minimum element by hinting
260	/// to a new possible min element within the heap.
261	#[inline]
262	fn update_min(&mut self, handle: Handle) {
263		if self.min.is_undef() || self.node(handle).entry.key < self.node(self.min).entry.key {
264			self.min = handle;
265		}
266	}
267
268	/// Creates a new root node.
269	#[inline]
270	fn mk_root_node(&mut self, elem: T, key: K) -> Handle {
271		let idx = self.len();
272		Handle(
273			self.data.put(
274				Node::new_root(idx, Entry::new(key, elem))))
275	}
276
277	/// Inserts a new root into the `PairingHeap` and checks whether it is the new minimum element.
278	fn insert_root(&mut self, new_root: Handle) {
279		let idx = self.roots.len();
280		self.roots.push(new_root);
281		self.node_mut(new_root).pos = Position::root(idx);
282		self.update_min(new_root);
283	}
284
285	/// Inserts the given element into the `PairingHeap` with its associated key
286	/// and returns a `Handle` to it that allows to directly address it.
287	/// 
288	/// The handle is for example required in order to use methods like `decrease_key`.
289	#[inline]
290	pub fn push(&mut self, elem: T, key: K) -> Handle {
291		let handle = self.mk_root_node(elem, key);
292		self.insert_root(handle);
293		handle
294
295	}
296
297	/// Cuts the given `child` from its parent and inserts it as a root into the `PairingHeap`.
298	/// Will panic if the given `child` is not a child and thus a root node already.
299	fn cut(&mut self, child: Handle) {
300		debug_assert!(self.node(child).pos.is_child());
301
302		match self.node(child).pos {
303			Position::Root(_) => unsafe{ ::unreachable::unreachable() },
304			Position::Child(parent, idx) => {
305				self.node_mut(parent).children.swap_remove(idx);
306				self.node_mut(child).pos = Position::root(self.len());
307				self.insert_root(child);
308			}
309		}
310	}
311
312	/// Decreases the key of the element with the associated given `handle`.
313	/// Will panic if the given new key is not lower than the previous key.
314	pub fn decrease_key(&mut self, handle: Handle, new_key: K) -> Result<()> {
315		if new_key >= self.node(handle).entry.key {
316			return Err(Error::DecreaseKeyOutOfOrder)
317		}
318
319		self.node_mut(handle).entry.key = new_key;
320		match self.node(handle).pos {
321			Position::Root(_) => {
322				self.update_min(handle);
323			},
324			Position::Child(..) => {
325				self.cut(handle)
326			}
327		}
328		Ok(())
329	}
330
331	/// Returns a reference to the element associated with the given handle.
332	#[inline]
333	pub fn get(&self, handle: Handle) -> Option<&T> {
334		self.data
335			.get(handle.to_usize())
336			.and_then(|node| Some(&node.entry.elem))
337	}
338
339	/// Returns a mutable reference to the element associated with the given handle.
340	#[inline]
341	pub fn get_mut(&mut self, handle: Handle) -> Option<&mut T> {
342		self.data
343			.get_mut(handle.to_usize())
344			.and_then(|node| Some(&mut node.entry.elem))
345	}
346
347	/// Returns a reference to the element associated with the given handle.
348	/// 
349	/// Does not perform bounds checking so use it carefully!
350	#[inline]
351	pub unsafe fn get_unchecked(&self, handle: Handle) -> &T {
352		&self.node(handle).entry.elem
353	}
354
355	/// Returns a mutable reference to the element associated with the given handle.
356	/// 
357	/// Does not perform bounds checking so use it carefully!
358	#[inline]
359	pub unsafe fn get_unchecked_mut(&mut self, handle: Handle) -> &mut T {
360		&mut self.node_mut(handle).entry.elem
361	}
362
363	/// Returns a reference to the current minimum element if not empty.
364	#[inline]
365	pub fn peek(&self) -> Option<&T> {
366		self.get(self.min)
367	}
368
369	/// Returns a reference to the current minimum element.
370	/// 
371	/// Does not perform bounds checking so use it carefully!
372	#[inline]
373	pub unsafe fn peek_unchecked(&self) -> &T {
374		self.get_unchecked(self.min)
375	}
376
377	/// Returns a mutable reference to the current minimum element if not empty.
378	#[inline]
379	pub fn peek_mut(&mut self) -> Option<&mut T> {
380		let min = self.min;
381		self.get_mut(min)
382	}
383
384	/// Returns a reference to the current minimum element without bounds checking.
385	/// So use it very carefully!
386	#[inline]
387	pub unsafe fn peek_unchecked_mut(&mut self) -> &mut T {
388		let min = self.min;
389		self.get_unchecked_mut(min)
390	}
391
392	/// Removes the element associated with the minimum key within this `PairingHeap` and returns it.
393	#[inline]
394	pub fn pop(&mut self) -> Option<T> {
395		match self.is_empty() {
396			true => None,
397			_    => unsafe{ Some(self.pop_unchecked()) }
398		}
399	}
400
401	/// Removes the element associated with the minimum key within this `PairingHeap` without
402	/// checking for emptiness and returns it.
403	/// 
404	/// So use this method carefully!
405	pub unsafe fn pop_unchecked(&mut self) -> T {
406		let min = self.min;
407		match self.node(min).pos {
408			Position::Child(..) => ::unreachable::unreachable(),
409			Position::Root(idx) => {
410				self.roots.swap_remove(idx);
411				self.min = Handle::undef();
412				for child in ::std::mem::replace(&mut self.node_mut(min).children, Vec::new()).into_iter() {
413					self.insert_root(child);
414				}
415				self.pairwise_union();
416				self.data.take_unchecked(min.to_usize()).entry.elem
417			}
418		}
419	}
420
421	/// Iterate over the values in this `PairingHeap` by reference in unspecified order.
422	#[inline]
423	pub fn values<'a>(&'a self) -> Values<'a, T, K> {
424		Values{iter: self.data.values()}
425	}
426
427	/// Iterate over the values in this `PairingHeap` by mutable reference unspecified order.
428	#[inline]
429	pub fn values_mut<'a>(&'a mut self) -> ValuesMut<'a, T, K> {
430		ValuesMut{iter: self.data.values_mut()}
431	}
432
433	/// Iterate over values stored within a `PairingHeap` in a sorted-by-min order. Drains the heap.
434	#[inline]
435	pub fn drain_min(self) -> DrainMin<T, K> {
436		DrainMin{heap: self}
437	}
438}
439
440use std::ops::{Index, IndexMut};
441
442impl<T, K> Index<Handle> for PairingHeap<T, K>
443	where K: Key
444{
445	type Output = T;
446
447	fn index(&self, handle: Handle) -> &Self::Output {
448		&self.data
449			.get(handle.to_usize())
450			.expect("no node found for given handle")
451			.entry.elem
452	}
453}
454
455impl<T, K> IndexMut<Handle> for PairingHeap<T, K>
456	where K: Key
457{
458	fn index_mut(&mut self, handle: Handle) -> &mut Self::Output {
459		&mut self.data
460			.get_mut(handle.to_usize())
461			.expect("no node found for given handle")
462			.entry.elem
463	}
464}
465
466/// Iterator over references to values stored within a `PairingHeap`.
467pub struct Values<'a, T: 'a, K: 'a + Key> {
468	iter: ::stash::stash::Values<'a, Node<T, K>>
469}
470
471/// Iterator over mutable references to values stored within a `PairingHeap`.
472pub struct ValuesMut<'a, T: 'a, K: 'a + Key> {
473	iter: ::stash::stash::ValuesMut<'a, Node<T, K>>
474}
475
476impl<'a, T, K: Key> Iterator for Values<'a, T, K> {
477	type Item = &'a T;
478
479	#[inline]
480	fn next(&mut self) -> Option<Self::Item> {
481		self.iter.next().map(|node| &node.entry.elem)
482	}
483}
484
485impl<'a, T, K: Key> Iterator for ValuesMut<'a, T, K> {
486	type Item = &'a mut T;
487
488	#[inline]
489	fn next(&mut self) -> Option<Self::Item> {
490		self.iter.next().map(|node| &mut node.entry.elem)
491	}
492}
493
494/// Iterator over values stored within a `PairingHeap` in a sorted-by-min order. Drains the heap.
495pub struct DrainMin<T, K: Key> {
496	heap: PairingHeap<T, K>
497}
498
499impl<T, K: Key> Iterator for DrainMin<T, K> {
500	type Item = T;
501
502	#[inline]
503	fn next(&mut self) -> Option<Self::Item> {
504		self.heap.pop()
505	}
506}
507
508#[cfg(test)]
509mod tests {
510	use super::*;
511
512	#[test]
513	fn take_min() {
514		let mut ph = PairingHeap::new();
515		ph.push(0,   6);
516		ph.push(1,  10);
517		ph.push(2, -42);
518		ph.push(3,1337);
519		ph.push(4,  -1);
520		ph.push(5,   1);
521		ph.push(6,   2);
522		ph.push(7,   3);
523		ph.push(8,   4);
524		ph.push(9,   5);
525		assert_eq!(Some(2), ph.pop());
526		assert_eq!(Some(4), ph.pop());
527		assert_eq!(Some(5), ph.pop());
528		assert_eq!(Some(6), ph.pop());
529		assert_eq!(Some(7), ph.pop());
530		assert_eq!(Some(8), ph.pop());
531		assert_eq!(Some(9), ph.pop());
532		assert_eq!(Some(0), ph.pop());
533		assert_eq!(Some(1), ph.pop());
534		assert_eq!(Some(3), ph.pop());
535		assert_eq!(None   , ph.pop());
536	}
537
538	#[test]
539	fn decrease_key() {
540		let mut ph = PairingHeap::new();
541		let a = ph.push(0,   0);
542		let b = ph.push(1,  50);
543		let c = ph.push(2, 100);
544		let d = ph.push(3, 150);
545		let e = ph.push(4, 200);
546		let f = ph.push(5, 250);
547		assert_eq!(Some(&0), ph.peek());
548		assert_eq!(Ok(()), ph.decrease_key(f, -50));
549		assert_eq!(Some(&5), ph.peek());
550		assert_eq!(Ok(()), ph.decrease_key(e, -100));
551		assert_eq!(Some(&4), ph.peek());
552		assert_eq!(Ok(()), ph.decrease_key(d, -99));
553		assert_eq!(Some(&4), ph.peek());
554		assert_eq!(Err(Error::DecreaseKeyOutOfOrder), ph.decrease_key(c, 1000));
555		assert_eq!(Some(&4), ph.peek());
556		assert_eq!(Ok(()), ph.decrease_key(b, -1000));
557		assert_eq!(Some(&1), ph.peek());
558		assert_eq!(Err(Error::DecreaseKeyOutOfOrder), ph.decrease_key(a, 100));
559		assert_eq!(Some(&1), ph.peek());
560	}
561
562	#[test]
563	fn empty_take() {
564		let mut ph = PairingHeap::<usize, usize>::new();
565		assert_eq!(None, ph.pop());
566	}
567
568	fn setup() -> PairingHeap<char, i64> {
569		let mut ph = PairingHeap::new();
570		ph.push('a', 100);
571		ph.push('b',  50);
572		ph.push('c', 150);
573		ph.push('d', -25);
574		ph.push('e', 999);
575		ph.push('f',  42);
576		ph.push('g',  43);
577		ph.push('i',  41);
578		ph.push('j',-100);
579		ph.push('k', -77);
580		ph.push('l', 123);
581		ph.push('m',-123);
582		ph.push('n',   0);
583		ph.push('o',  -1);
584		ph.push('p',   2);
585		ph.push('q',  -3);
586		ph.push('r',   4);
587		ph.push('s',  -5);
588		ph
589	}
590
591	// fn setup_vec() -> Vec<(char, i64)> {
592	// 	vec![
593	// 		('a',  0), ('A', 26), ('.', 52),
594	// 		('b',  1), ('B', 27), (',', 53),
595	// 		('c',  2), ('C', 28), (';', 54),
596	// 		('d',  3), ('D', 29), ('!', 55),
597	// 		('e',  4), ('E', 30), ('&', 56),
598	// 		('f',  5), ('F', 31), ('|', 57),
599	// 		('g',  6), ('G', 32), ('(', 58),
600	// 		('h',  7), ('H', 33), (')', 59),
601	// 		('i',  8), ('I', 34), ('[', 60),
602	// 		('j',  9), ('J', 35), (']', 61),
603	// 		('k', 10), ('K', 36), ('{', 62),
604	// 		('l', 11), ('L', 37), ('}', 63),
605	// 		('m', 12), ('M', 38), ('=', 64),
606	// 		('n', 13), ('N', 39), ('?', 65),
607	// 		('o', 14), ('O', 40), ('+', 66),
608	// 		('p', 15), ('P', 41), ('-', 67),
609	// 		('q', 16), ('Q', 42), ('*', 68),
610	// 		('r', 17), ('R', 43), ('/', 69),
611	// 		('s', 18), ('S', 44), ('<', 70),
612	// 		('t', 19), ('T', 45), ('>', 71),
613	// 		('u', 20), ('U', 46), ('=', 72),
614	// 		('v', 21), ('V', 47), ('#', 73),
615	// 		('w', 22), ('W', 48), ('~', 74),
616	// 		('x', 23), ('X', 49), ('?', 75),
617	// 		('y', 24), ('Y', 50), (':', 76),
618	// 		('z', 25), ('Z', 51), ('^', 77)
619	// 	]
620	// }
621
622	#[test]
623	fn drain_min() {
624		let ph = setup();
625		let mut drain = ph.drain_min();
626
627		assert_eq!(drain.next(), Some('m'));
628		assert_eq!(drain.next(), Some('j'));
629		assert_eq!(drain.next(), Some('k'));
630		assert_eq!(drain.next(), Some('d'));
631		assert_eq!(drain.next(), Some('s'));
632		assert_eq!(drain.next(), Some('q'));
633		assert_eq!(drain.next(), Some('o'));
634		assert_eq!(drain.next(), Some('n'));
635
636		assert_eq!(drain.next(), Some('p'));
637		assert_eq!(drain.next(), Some('r'));
638		assert_eq!(drain.next(), Some('i'));
639		assert_eq!(drain.next(), Some('f'));
640		assert_eq!(drain.next(), Some('g'));
641		assert_eq!(drain.next(), Some('b'));
642		assert_eq!(drain.next(), Some('a'));
643		assert_eq!(drain.next(), Some('l'));
644		assert_eq!(drain.next(), Some('c'));
645		assert_eq!(drain.next(), Some('e'));
646
647		assert_eq!(drain.next(), None);
648	}
649
650	#[test]
651	fn values() {
652		let ph = setup();
653		let values = ph.values();
654
655		// cannot test order of values since it is unspecified!
656		assert_eq!(values.count(), 18);
657	}
658}
659
660#[cfg(all(feature = "bench", test))]
661mod bench {
662	use super::*;
663    use test::{Bencher, black_box};
664    use ::std::collections::BinaryHeap;
665
666	fn setup_sample() -> Vec<i64> {
667		use rand::{thread_rng, sample};
668		let n       = 100_000;
669		let mut rng = thread_rng();
670		sample(&mut rng, 1..n, n as usize)
671	}
672
673	fn setup_sample_bigpod() -> Vec<BigPod> {
674		use rand::{thread_rng, sample};
675		let n       = 100_000;
676		let mut rng = thread_rng();
677		sample(&mut rng, 1..n, n as usize)
678			.into_iter()
679			.map(|val| val.into())
680			.collect::<Vec<BigPod>>()
681	}
682
683    #[derive(Debug, Clone, PartialEq, Eq, Ord)]
684    struct BigPod {
685    	elems: [i64; 32]
686    }
687
688    impl From<i64> for BigPod {
689    	fn from(val: i64) -> BigPod {
690    		let mut bp = BigPod{
691    			elems: [0; 32]
692    		};
693    		bp.elems[0] = val;
694    		bp
695    	}
696    }
697
698    impl PartialOrd for BigPod {
699    	fn partial_cmp(&self, other: &BigPod) -> Option<std::cmp::Ordering> {
700    		self.elems[0].partial_cmp(&other.elems[0])
701    	}
702    }
703
704	#[bench]
705	fn pairing_heap_push(bencher: &mut Bencher) {
706		let sample = setup_sample();
707		bencher.iter(|| {
708			let mut ph = PairingHeap::new();
709			for &key in sample.iter() {
710				black_box(ph.push((), key));
711			}
712		});
713	}
714
715	#[bench]
716	fn pairing_heap_push_bigpod(bencher: &mut Bencher) {
717		let sample = setup_sample_bigpod();
718		bencher.iter(|| {
719			let mut ph = PairingHeap::new();
720			for bigpod in sample.iter() {
721				black_box(ph.push(bigpod.clone(), bigpod.elems[0]));
722			}
723		});
724	}
725
726	#[bench]
727	fn binary_heap_push(bencher: &mut Bencher) {
728		let sample = setup_sample();
729		bencher.iter(|| {
730			let mut bh = BinaryHeap::new();
731			for &key in sample.iter() {
732				black_box(bh.push(key));
733			}
734		});
735	}
736
737	#[bench]
738	fn binary_heap_push_bigpod(bencher: &mut Bencher) {
739		let sample = setup_sample_bigpod();
740		bencher.iter(|| {
741			let mut bh = BinaryHeap::new();
742			for bigpod in sample.iter() {
743				black_box(bh.push(bigpod.clone()));
744			}
745		});
746	}
747
748	#[bench]
749	fn pairing_heap_pop(bencher: &mut Bencher) {
750		let mut ph = PairingHeap::new();
751		for key in setup_sample().into_iter() {
752			ph.push((), key);
753		}
754		bencher.iter(|| {
755			let mut ph = ph.clone();
756			while let Some(_) = black_box(ph.pop()) {}
757		});
758	}
759
760	#[bench]
761	fn pairing_heap_pop_bigpod(bencher: &mut Bencher) {
762		let mut ph = PairingHeap::new();
763		for bigpod in setup_sample_bigpod().into_iter() {
764			let head = bigpod.elems[0];
765			ph.push(bigpod, head);
766		}
767		bencher.iter(|| {
768			let mut ph = ph.clone();
769			while let Some(_) = black_box(ph.pop()) {}
770		});
771	}
772
773	#[bench]
774	fn binary_heap_pop(bencher: &mut Bencher) {
775		let mut bh = BinaryHeap::new();
776		for key in setup_sample().into_iter() {
777			bh.push(key);
778		}
779		bencher.iter(|| {
780			let mut bh = bh.clone();
781			while let Some(_) = black_box(bh.pop()) {}
782		});
783	}
784
785	#[bench]
786	fn binary_heap_pop_bigpod(bencher: &mut Bencher) {
787		let mut bh = BinaryHeap::new();
788		for bigpod in setup_sample_bigpod().into_iter() {
789			bh.push(bigpod);
790		}
791		bencher.iter(|| {
792			let mut bh = bh.clone();
793			while let Some(_) = black_box(bh.pop()) {}
794		});
795	}
796
797	#[bench]
798	fn pairing_heap_clone(bencher: &mut Bencher) {
799		let mut ph = PairingHeap::new();
800		for key in setup_sample().into_iter() {
801			ph.push((), key);
802		}
803		bencher.iter(|| {
804			black_box(&ph.clone());
805		});
806	}
807
808	#[bench]
809	fn binary_heap_clone(bencher: &mut Bencher) {
810		let mut bh = BinaryHeap::new();
811		for key in setup_sample().into_iter() {
812			bh.push(key);
813		}
814		bencher.iter(|| {
815			black_box(&bh.clone());
816		});
817	}
818}