Skip to main content

surrealdb_collections/
vec_map.rs

1//! Ordered map backed by a sorted `Vec` of `(K, V)` entries.
2
3use std::borrow::Borrow;
4use std::cmp::Ordering;
5use std::collections::BTreeMap;
6use std::hash::{Hash, Hasher};
7use std::io::Write;
8use std::iter::FromIterator;
9use std::ops::Index;
10
11use storekey::{BorrowDecode, BorrowReader, DecodeError, Encode, EncodeError, Writer};
12
13use crate::search::search_sorted_by;
14
15/// Map with unique keys in ascending `Ord` order, stored in a `Vec`.
16#[derive(Clone, Debug)]
17#[repr(transparent)]
18pub struct VecMap<K, V> {
19	entries: Vec<(K, V)>,
20}
21
22impl<K, V> Default for VecMap<K, V> {
23	fn default() -> Self {
24		Self {
25			entries: Vec::new(),
26		}
27	}
28}
29
30impl<K: PartialEq, V: PartialEq> PartialEq for VecMap<K, V> {
31	fn eq(&self, other: &Self) -> bool {
32		self.entries == other.entries
33	}
34}
35
36impl<K: Eq, V: Eq> Eq for VecMap<K, V> {}
37
38impl<K: Hash, V: Hash> Hash for VecMap<K, V> {
39	fn hash<H: Hasher>(&self, state: &mut H) {
40		self.entries.hash(state);
41	}
42}
43
44impl<K: Ord, V: Ord> PartialOrd for VecMap<K, V> {
45	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
46		Some(self.cmp(other))
47	}
48}
49
50impl<K: Ord, V: Ord> Ord for VecMap<K, V> {
51	fn cmp(&self, other: &Self) -> Ordering {
52		self.entries.cmp(&other.entries)
53	}
54}
55
56impl<K, V> VecMap<K, V> {
57	#[must_use]
58	pub fn new() -> Self {
59		Self::default()
60	}
61
62	/// Creates a new `VecMap` with space preallocated for `capacity` entries.
63	#[must_use]
64	pub fn with_capacity(capacity: usize) -> Self {
65		Self {
66			entries: Vec::with_capacity(capacity),
67		}
68	}
69
70	/// Build a `VecMap` from a `Vec` whose entries are already sorted by key
71	/// and contain no duplicate keys.
72	///
73	/// The invariant is checked with a `debug_assert!` and is **not** enforced
74	/// in release builds; callers must guarantee it. Use this when converting
75	/// from an already-ordered source (e.g. `BTreeMap`, revision-decoded
76	/// payloads, `PublicObject`) to avoid re-sorting.
77	#[must_use]
78	pub fn from_sorted_vec_unchecked(entries: Vec<(K, V)>) -> Self
79	where
80		K: Ord,
81	{
82		debug_assert!(
83			entries.windows(2).all(|w| w[0].0 < w[1].0),
84			"VecMap::from_sorted_vec_unchecked: entries not strictly sorted by key"
85		);
86		Self {
87			entries,
88		}
89	}
90
91	#[must_use]
92	pub fn len(&self) -> usize {
93		self.entries.len()
94	}
95
96	#[must_use]
97	pub fn is_empty(&self) -> bool {
98		self.entries.is_empty()
99	}
100
101	pub fn clear(&mut self) {
102		self.entries.clear();
103	}
104
105	#[must_use]
106	pub fn get<Q: ?Sized + Ord>(&self, key: &Q) -> Option<&V>
107	where
108		K: Borrow<Q>,
109	{
110		let i = search_sorted_by(&self.entries, |(k, _)| k.borrow().cmp(key)).ok()?;
111		Some(&self.entries[i].1)
112	}
113
114	#[must_use]
115	pub fn get_mut<Q: ?Sized + Ord>(&mut self, key: &Q) -> Option<&mut V>
116	where
117		K: Borrow<Q>,
118	{
119		let i = search_sorted_by(&self.entries, |(k, _)| k.borrow().cmp(key)).ok()?;
120		Some(&mut self.entries[i].1)
121	}
122
123	#[must_use]
124	pub fn contains_key<Q: ?Sized + Ord>(&self, key: &Q) -> bool
125	where
126		K: Borrow<Q>,
127	{
128		self.get(key).is_some()
129	}
130
131	pub fn insert(&mut self, key: K, value: V) -> Option<V>
132	where
133		K: Ord,
134	{
135		match search_sorted_by(&self.entries, |(k, _)| k.cmp(&key)) {
136			Ok(i) => Some(std::mem::replace(&mut self.entries[i].1, value)),
137			Err(i) => {
138				self.entries.insert(i, (key, value));
139				None
140			}
141		}
142	}
143
144	pub fn remove<Q: ?Sized + Ord>(&mut self, key: &Q) -> Option<V>
145	where
146		K: Borrow<Q>,
147	{
148		let i = search_sorted_by(&self.entries, |(k, _)| k.borrow().cmp(key)).ok()?;
149		Some(self.entries.remove(i).1)
150	}
151
152	pub fn retain<F>(&mut self, mut f: F)
153	where
154		F: FnMut(&K, &mut V) -> bool,
155	{
156		self.entries.retain_mut(|(k, v)| f(k, v));
157	}
158
159	/// Moves all elements from `other` into `self`, leaving `other` empty.
160	///
161	/// This matches [`BTreeMap::append`]: both maps must already be sorted by key with no
162	/// duplicates within each map. If the same key appears in both, the value from `other`
163	/// replaces the value in `self` (the key slot from `self` is dropped, as with
164	/// [`BTreeMap::insert`]).
165	pub fn append(&mut self, other: &mut Self)
166	where
167		K: Ord,
168	{
169		if other.is_empty() {
170			return;
171		}
172		if self.is_empty() {
173			std::mem::swap(self, other);
174			return;
175		}
176		let can_concat =
177			self.entries.last().zip(other.entries.first()).is_some_and(|(a, b)| a.0 < b.0);
178		if can_concat {
179			self.entries.append(&mut other.entries);
180			return;
181		}
182		*self = Self::merge_sorted_prefer_rhs(
183			Self {
184				entries: std::mem::take(&mut self.entries),
185			},
186			Self {
187				entries: std::mem::take(&mut other.entries),
188			},
189		);
190	}
191
192	/// Linear merge of two maps whose keys are sorted ascending in each.
193	///
194	/// If the same key appears in both maps, the value from `rhs` is kept (same as
195	/// repeatedly inserting each entry from `rhs` into a copy of `lhs`).
196	#[must_use]
197	pub fn merge_sorted_prefer_rhs(lhs: Self, rhs: Self) -> Self
198	where
199		K: Ord,
200	{
201		let reserve = lhs.entries.len() + rhs.entries.len();
202		let mut a = lhs.entries.into_iter().peekable();
203		let mut b = rhs.entries.into_iter().peekable();
204		let mut out = Vec::with_capacity(reserve);
205		loop {
206			match (a.peek(), b.peek()) {
207				(None, None) => break,
208				(Some(_), None) => {
209					out.extend(a);
210					break;
211				}
212				(None, Some(_)) => {
213					out.extend(b);
214					break;
215				}
216				(Some((ka, _)), Some((kb, _))) => match ka.cmp(kb) {
217					Ordering::Less => {
218						out.push(
219							a.next().expect("merge_sorted_prefer_rhs: iterator lagged behind peek"),
220						);
221					}
222					Ordering::Greater => {
223						out.push(
224							b.next().expect("merge_sorted_prefer_rhs: iterator lagged behind peek"),
225						);
226					}
227					Ordering::Equal => {
228						a.next()
229							.expect("merge_sorted_prefer_rhs: iterator lagged behind peek (lhs)");
230						out.push(
231							b.next().expect(
232								"merge_sorted_prefer_rhs: iterator lagged behind peek (rhs)",
233							),
234						);
235					}
236				},
237			}
238		}
239		Self::from_sorted_vec_unchecked(out)
240	}
241
242	/// Appends `(key, value)` in **O(1)** amortized time without searching.
243	///
244	/// # Ordering
245	///
246	/// `key` must be **strictly greater** than every existing key (or the map
247	/// must be empty). Violating this breaks sorted-map invariants; it is checked
248	/// with [`debug_assert!`] only (see [`append`](Self::append)).
249	pub fn push(&mut self, key: K, value: V)
250	where
251		K: Ord,
252	{
253		debug_assert!(
254			self.entries.last().map(|(k, _)| k < &key).unwrap_or(true),
255			"VecMap::push: key must be strictly greater than the current maximum key"
256		);
257		self.entries.push((key, value));
258	}
259
260	pub fn iter(&self) -> Iter<'_, K, V> {
261		Iter {
262			inner: self.entries.iter(),
263		}
264	}
265
266	pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
267		IterMut {
268			inner: self.entries.iter_mut(),
269		}
270	}
271
272	pub fn keys(&self) -> impl Iterator<Item = &K> + '_ {
273		self.entries.iter().map(|(k, _)| k)
274	}
275
276	pub fn values(&self) -> impl Iterator<Item = &V> + '_ {
277		self.entries.iter().map(|(_, v)| v)
278	}
279
280	pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> + '_ {
281		self.entries.iter_mut().map(|(_, v)| v)
282	}
283
284	#[must_use]
285	pub fn first_key_value(&self) -> Option<(&K, &V)> {
286		self.entries.first().map(|(k, v)| (k, v))
287	}
288
289	#[must_use]
290	pub fn last_key_value(&self) -> Option<(&K, &V)> {
291		self.entries.last().map(|(k, v)| (k, v))
292	}
293
294	pub fn entry(&mut self, key: K) -> Entry<'_, K, V>
295	where
296		K: Ord,
297	{
298		match search_sorted_by(&self.entries, |(k, _)| k.cmp(&key)) {
299			Ok(i) => Entry::Occupied(OccupiedEntry {
300				entries: &mut self.entries,
301				index: i,
302			}),
303			Err(i) => Entry::Vacant(VacantEntry {
304				entries: &mut self.entries,
305				key,
306				index: i,
307			}),
308		}
309	}
310}
311
312impl<K: Ord, V> Index<&K> for VecMap<K, V> {
313	type Output = V;
314
315	fn index(&self, key: &K) -> &Self::Output {
316		self.get(key).expect("VecMap: index out of bounds")
317	}
318}
319
320impl<'a, K, V> IntoIterator for &'a VecMap<K, V> {
321	type Item = (&'a K, &'a V);
322	type IntoIter = Iter<'a, K, V>;
323
324	fn into_iter(self) -> Self::IntoIter {
325		self.iter()
326	}
327}
328
329pub struct Iter<'a, K, V> {
330	inner: std::slice::Iter<'a, (K, V)>,
331}
332
333impl<'a, K, V> Iterator for Iter<'a, K, V> {
334	type Item = (&'a K, &'a V);
335
336	fn next(&mut self) -> Option<Self::Item> {
337		self.inner.next().map(|(k, v)| (k, v))
338	}
339
340	fn size_hint(&self) -> (usize, Option<usize>) {
341		self.inner.size_hint()
342	}
343}
344
345impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
346	fn len(&self) -> usize {
347		self.inner.len()
348	}
349}
350
351impl<'a, K, V> Clone for Iter<'a, K, V> {
352	fn clone(&self) -> Self {
353		Self {
354			inner: self.inner.clone(),
355		}
356	}
357}
358
359pub struct IterMut<'a, K, V> {
360	inner: std::slice::IterMut<'a, (K, V)>,
361}
362
363impl<'a, K, V> Iterator for IterMut<'a, K, V> {
364	type Item = (&'a K, &'a mut V);
365
366	fn next(&mut self) -> Option<Self::Item> {
367		self.inner.next().map(|(k, v)| (&*k, v))
368	}
369
370	fn size_hint(&self) -> (usize, Option<usize>) {
371		self.inner.size_hint()
372	}
373}
374
375pub struct IntoIter<K, V> {
376	inner: std::vec::IntoIter<(K, V)>,
377}
378
379impl<K, V> Iterator for IntoIter<K, V> {
380	type Item = (K, V);
381
382	fn next(&mut self) -> Option<Self::Item> {
383		self.inner.next()
384	}
385
386	fn size_hint(&self) -> (usize, Option<usize>) {
387		self.inner.size_hint()
388	}
389}
390
391impl<K, V> ExactSizeIterator for IntoIter<K, V> {
392	fn len(&self) -> usize {
393		self.inner.len()
394	}
395}
396
397impl<K, V> VecMap<K, V> {
398	/// Consumes the map and returns an iterator over the values in key order.
399	pub fn into_values(self) -> impl Iterator<Item = V> {
400		self.entries.into_iter().map(|(_, v)| v)
401	}
402}
403
404impl<K, V> IntoIterator for VecMap<K, V> {
405	type Item = (K, V);
406	type IntoIter = IntoIter<K, V>;
407
408	fn into_iter(self) -> Self::IntoIter {
409		IntoIter {
410			inner: self.entries.into_iter(),
411		}
412	}
413}
414
415impl<K: Ord, V> FromIterator<(K, V)> for VecMap<K, V> {
416	fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
417		let mut v: Vec<(K, V)> = iter.into_iter().collect();
418		if v.is_empty() {
419			return Self::default();
420		}
421		v.sort_by(|a, b| a.0.cmp(&b.0));
422		// Stable sort preserves iterator order among equal keys. Reverse so the last
423		// occurrence per key is first, dedup keeps the first of consecutive equals, then
424		// reverse back to ascending order — matching repeated `insert` (last wins).
425		v.reverse();
426		v.dedup_by(|a, b| a.0 == b.0);
427		v.reverse();
428		Self::from_sorted_vec_unchecked(v)
429	}
430}
431
432impl<K: Ord, V> Extend<(K, V)> for VecMap<K, V> {
433	fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
434		if self.is_empty() {
435			*self = iter.into_iter().collect();
436			return;
437		}
438		for (k, v) in iter {
439			self.insert(k, v);
440		}
441	}
442}
443
444impl<K: Ord, V> From<BTreeMap<K, V>> for VecMap<K, V> {
445	fn from(map: BTreeMap<K, V>) -> Self {
446		let mut entries = Vec::with_capacity(map.len());
447		entries.extend(map);
448		Self::from_sorted_vec_unchecked(entries)
449	}
450}
451
452pub enum Entry<'a, K, V> {
453	Occupied(OccupiedEntry<'a, K, V>),
454	Vacant(VacantEntry<'a, K, V>),
455}
456
457impl<'a, K: Ord, V> Entry<'a, K, V> {
458	pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
459		match self {
460			Entry::Occupied(o) => o.into_mut(),
461			Entry::Vacant(v) => v.insert(default()),
462		}
463	}
464}
465
466pub struct OccupiedEntry<'a, K, V> {
467	entries: &'a mut Vec<(K, V)>,
468	index: usize,
469}
470
471impl<'a, K, V> OccupiedEntry<'a, K, V> {
472	pub fn into_mut(self) -> &'a mut V {
473		&mut self.entries[self.index].1
474	}
475}
476
477pub struct VacantEntry<'a, K, V> {
478	entries: &'a mut Vec<(K, V)>,
479	key: K,
480	index: usize,
481}
482
483impl<'a, K, V> VacantEntry<'a, K, V> {
484	pub fn insert(self, value: V) -> &'a mut V {
485		self.entries.insert(self.index, (self.key, value));
486		&mut self.entries[self.index].1
487	}
488}
489
490impl<F, K: Encode<F>, V: Encode<F>> Encode<F> for VecMap<K, V> {
491	fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError> {
492		for (k, v) in self.iter() {
493			w.mark_terminator();
494			k.encode(w)?;
495			v.encode(w)?;
496		}
497		w.write_terminator()
498	}
499}
500
501impl<'de, F, K: BorrowDecode<'de, F> + Ord, V: BorrowDecode<'de, F>> BorrowDecode<'de, F>
502	for VecMap<K, V>
503{
504	/// Deserialises a storekey map as a sequence of key-value pairs, appending each with
505	/// [`push`](VecMap::push).
506	///
507	/// **Wire contract:** Keys must appear in **strictly ascending** order (matching
508	/// [`Encode`] for `VecMap` / `BTreeMap`). If a decoded key is less than or equal to the
509	/// previous key, decoding fails with [`DecodeError::InvalidFormat`] in all builds.
510	fn borrow_decode(r: &mut BorrowReader<'de>) -> Result<Self, DecodeError> {
511		let mut map = VecMap::new();
512		while !r.read_terminal()? {
513			let k = K::borrow_decode(r)?;
514			if let Some((prev_k, _)) = map.last_key_value()
515				&& k <= *prev_k
516			{
517				return Err(DecodeError::InvalidFormat);
518			}
519			let v = V::borrow_decode(r)?;
520			map.push(k, v);
521		}
522		Ok(map)
523	}
524}
525
526#[cfg(test)]
527mod tests {
528	use std::cmp::Ordering;
529	use std::collections::BTreeMap;
530	use std::collections::hash_map::DefaultHasher;
531	use std::hash::{Hash, Hasher};
532
533	use super::*;
534
535	/// Asserts that `m`'s keys are in strictly ascending order.
536	fn assert_sorted<K: Ord + std::fmt::Debug, V>(m: &VecMap<K, V>) {
537		for (a, b) in m.keys().zip(m.keys().skip(1)) {
538			assert!(a < b, "VecMap keys not strictly sorted: {a:?} >= {b:?}");
539		}
540	}
541
542	fn hash_of<T: Hash>(t: &T) -> u64 {
543		let mut h = DefaultHasher::new();
544		t.hash(&mut h);
545		h.finish()
546	}
547
548	#[test]
549	fn new_and_default_are_empty() {
550		let m: VecMap<i32, i32> = VecMap::new();
551		assert!(m.is_empty());
552		assert_eq!(m.len(), 0);
553		let d: VecMap<i32, i32> = VecMap::default();
554		assert_eq!(m, d);
555	}
556
557	#[test]
558	fn with_capacity_starts_empty_and_works() {
559		let mut m: VecMap<i32, i32> = VecMap::with_capacity(8);
560		assert!(m.is_empty());
561		for i in 0..8 {
562			m.insert(i, i);
563		}
564		assert_eq!(m.len(), 8);
565		assert_sorted(&m);
566	}
567
568	#[test]
569	fn from_sorted_vec_unchecked_builds_correct_map() {
570		let m: VecMap<i32, &str> =
571			VecMap::from_sorted_vec_unchecked(vec![(1, "a"), (2, "b"), (3, "c")]);
572		assert_eq!(m.len(), 3);
573		assert_eq!(m.get(&2), Some(&"b"));
574	}
575
576	#[test]
577	fn from_sorted_vec_unchecked_empty_is_ok() {
578		let m: VecMap<i32, i32> = VecMap::from_sorted_vec_unchecked(vec![]);
579		assert!(m.is_empty());
580	}
581
582	#[test]
583	#[cfg(debug_assertions)]
584	#[should_panic(expected = "VecMap::from_sorted_vec_unchecked")]
585	fn from_sorted_vec_unchecked_unsorted_panics_in_debug() {
586		let _: VecMap<i32, i32> = VecMap::from_sorted_vec_unchecked(vec![(2, 0), (1, 0)]);
587	}
588
589	#[test]
590	#[cfg(debug_assertions)]
591	#[should_panic(expected = "VecMap::from_sorted_vec_unchecked")]
592	fn from_sorted_vec_unchecked_duplicate_keys_panics_in_debug() {
593		let _: VecMap<i32, i32> = VecMap::from_sorted_vec_unchecked(vec![(1, 0), (1, 0)]);
594	}
595
596	#[test]
597	fn clear_resets_to_empty() {
598		let mut m: VecMap<i32, i32> = [(1, 10), (2, 20)].into_iter().collect();
599		m.clear();
600		assert!(m.is_empty());
601		assert_eq!(m.len(), 0);
602	}
603
604	#[test]
605	fn insert_returns_none_for_new_and_old_for_replace() {
606		let mut m = VecMap::new();
607		assert_eq!(m.insert("a", 1), None);
608		assert_eq!(m.insert("b", 2), None);
609		assert_eq!(m.insert("a", 10), Some(1));
610		assert_eq!(m.get("a"), Some(&10));
611		assert_eq!(m.len(), 2);
612	}
613
614	#[test]
615	fn insert_keeps_entries_sorted_for_arbitrary_order() {
616		let mut m = VecMap::new();
617		for &k in &[5, 1, 4, 2, 3] {
618			m.insert(k, k * 10);
619		}
620		assert_sorted(&m);
621		let keys: Vec<_> = m.keys().copied().collect();
622		assert_eq!(keys, vec![1, 2, 3, 4, 5]);
623	}
624
625	/// Cross the `LINEAR_SEARCH_THRESHOLD` (64) boundary so that
626	/// `search_sorted_by` exercises the `binary_search_by` fallback during
627	/// inserts in the middle and end of the map.
628	#[test]
629	fn insert_above_linear_threshold_keeps_sorted_and_replaces() {
630		let mut m = VecMap::new();
631		for i in 0..128u32 {
632			m.insert(i * 2, i * 2);
633		}
634		for i in 0..128u32 {
635			m.insert(i * 2 + 1, i * 2 + 1);
636		}
637		assert_eq!(m.len(), 256);
638		assert_sorted(&m);
639		for i in 0..256u32 {
640			assert_eq!(m.get(&i), Some(&i));
641		}
642		assert_eq!(m.insert(150, 9_999), Some(150));
643		assert_eq!(m.get(&150), Some(&9_999));
644	}
645
646	#[test]
647	fn get_and_contains_key_with_borrow() {
648		let m: VecMap<String, i32> =
649			[("apple".to_string(), 1), ("banana".to_string(), 2)].into_iter().collect();
650		assert_eq!(m.get("apple"), Some(&1));
651		assert_eq!(m.get("missing"), None);
652		assert!(m.contains_key("banana"));
653		assert!(!m.contains_key("cherry"));
654	}
655
656	#[test]
657	fn get_mut_allows_mutation_and_returns_none_for_missing() {
658		let mut m: VecMap<i32, String> = [(1, "a".into()), (2, "b".into())].into_iter().collect();
659		if let Some(v) = m.get_mut(&1) {
660			v.push('!');
661		}
662		assert_eq!(m.get(&1), Some(&"a!".to_string()));
663		assert!(m.get_mut(&99).is_none());
664	}
665
666	#[test]
667	fn remove_returns_value_then_none_and_keeps_order() {
668		let mut m: VecMap<i32, i32> = (0..10).map(|i| (i, i * 100)).collect();
669		assert_eq!(m.remove(&3), Some(300));
670		assert_eq!(m.remove(&3), None);
671		assert_sorted(&m);
672		let keys: Vec<_> = m.keys().copied().collect();
673		assert_eq!(keys, vec![0, 1, 2, 4, 5, 6, 7, 8, 9]);
674	}
675
676	#[test]
677	fn remove_with_borrow() {
678		let mut m: VecMap<String, i32> =
679			[("a".to_string(), 1), ("b".to_string(), 2)].into_iter().collect();
680		assert_eq!(m.remove("a"), Some(1));
681		assert_eq!(m.remove("missing"), None);
682		assert_eq!(m.len(), 1);
683	}
684
685	#[test]
686	fn retain_keeps_subset_in_order() {
687		let mut m: VecMap<i32, i32> = (0..6).map(|i| (i, i * 10)).collect();
688		m.retain(|&k, _| k % 2 == 0);
689		assert_sorted(&m);
690		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
691		assert_eq!(pairs, vec![(0, 0), (2, 20), (4, 40)]);
692	}
693
694	#[test]
695	fn retain_can_mutate_values_in_place() {
696		let mut m: VecMap<i32, i32> = (0..3).map(|i| (i, i)).collect();
697		m.retain(|_, v| {
698			*v += 100;
699			true
700		});
701		let vs: Vec<_> = m.values().copied().collect();
702		assert_eq!(vs, vec![100, 101, 102]);
703	}
704
705	#[test]
706	fn retain_remove_all_or_keep_all() {
707		let mut m: VecMap<i32, i32> = (0..5).map(|i| (i, i)).collect();
708		let mut copy = m.clone();
709		m.retain(|_, _| false);
710		assert!(m.is_empty());
711		copy.retain(|_, _| true);
712		assert_eq!(copy.len(), 5);
713	}
714
715	#[test]
716	fn append_moves_entries_and_empties_other() {
717		let mut a: VecMap<i32, i32> = (0..3).map(|i| (i, i)).collect();
718		let mut b: VecMap<i32, i32> = (3..6).map(|i| (i, i)).collect();
719		a.append(&mut b);
720		assert!(b.is_empty());
721		assert_eq!(a.len(), 6);
722		assert_sorted(&a);
723	}
724
725	#[test]
726	fn append_with_one_or_both_empty() {
727		let mut a: VecMap<i32, i32> = (0..3).map(|i| (i, i)).collect();
728		let mut empty: VecMap<i32, i32> = VecMap::new();
729		a.append(&mut empty);
730		assert_eq!(a.len(), 3);
731		assert!(empty.is_empty());
732
733		let mut a: VecMap<i32, i32> = VecMap::new();
734		let mut b: VecMap<i32, i32> = (0..3).map(|i| (i, i)).collect();
735		a.append(&mut b);
736		assert_eq!(a.len(), 3);
737		assert!(b.is_empty());
738
739		let mut a: VecMap<i32, i32> = VecMap::new();
740		let mut b: VecMap<i32, i32> = VecMap::new();
741		a.append(&mut b);
742		assert!(a.is_empty());
743		assert!(b.is_empty());
744	}
745
746	#[test]
747	fn append_merges_when_other_is_entirely_before_self() {
748		let mut a: VecMap<i32, i32> = (5..8).map(|i| (i, i)).collect();
749		let mut b: VecMap<i32, i32> = (0..3).map(|i| (i, i)).collect();
750		a.append(&mut b);
751		assert!(b.is_empty());
752		assert_eq!(a.len(), 6);
753		assert_sorted(&a);
754		let pairs: Vec<_> = a.iter().map(|(k, v)| (*k, *v)).collect();
755		assert_eq!(pairs, vec![(0, 0), (1, 1), (2, 2), (5, 5), (6, 6), (7, 7)]);
756	}
757
758	#[test]
759	fn append_overlapping_prefers_values_from_other_like_btreemap() {
760		let mut a: VecMap<i32, i32> = [(1, 1), (2, 2), (3, 3)].into_iter().collect();
761		let mut b: VecMap<i32, i32> = [(3, 30), (4, 4), (5, 5)].into_iter().collect();
762		a.append(&mut b);
763		assert!(b.is_empty());
764		let pairs: Vec<_> = a.iter().map(|(k, v)| (*k, *v)).collect();
765		assert_eq!(pairs, vec![(1, 1), (2, 2), (3, 30), (4, 4), (5, 5)]);
766	}
767
768	#[test]
769	fn append_interleaved_keys_merges_sorted() {
770		let mut a: VecMap<i32, i32> = [(1, 10), (3, 30), (5, 50)].into_iter().collect();
771		let mut b: VecMap<i32, i32> = [(2, 20), (4, 40), (6, 60)].into_iter().collect();
772		a.append(&mut b);
773		assert!(b.is_empty());
774		let pairs: Vec<_> = a.iter().map(|(k, v)| (*k, *v)).collect();
775		assert_eq!(pairs, vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]);
776	}
777
778	#[test]
779	fn append_full_overlap_all_keys_match() {
780		let mut a: VecMap<i32, i32> = [(1, 1), (2, 2), (3, 3)].into_iter().collect();
781		let mut b: VecMap<i32, i32> = [(1, 100), (2, 200), (3, 300)].into_iter().collect();
782		a.append(&mut b);
783		assert!(b.is_empty());
784		let pairs: Vec<_> = a.iter().map(|(k, v)| (*k, *v)).collect();
785		assert_eq!(pairs, vec![(1, 100), (2, 200), (3, 300)]);
786	}
787
788	#[test]
789	fn append_other_is_subset_of_self() {
790		let mut a: VecMap<i32, i32> =
791			[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)].into_iter().collect();
792		let mut b: VecMap<i32, i32> = [(2, 200), (4, 400)].into_iter().collect();
793		a.append(&mut b);
794		assert!(b.is_empty());
795		let pairs: Vec<_> = a.iter().map(|(k, v)| (*k, *v)).collect();
796		assert_eq!(pairs, vec![(1, 1), (2, 200), (3, 3), (4, 400), (5, 5)]);
797	}
798
799	#[test]
800	fn append_self_is_subset_of_other() {
801		let mut a: VecMap<i32, i32> = [(2, 2), (4, 4)].into_iter().collect();
802		let mut b: VecMap<i32, i32> =
803			[(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)].into_iter().collect();
804		a.append(&mut b);
805		assert!(b.is_empty());
806		let pairs: Vec<_> = a.iter().map(|(k, v)| (*k, *v)).collect();
807		assert_eq!(pairs, vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)]);
808	}
809
810	/// Differential test against `BTreeMap::append`: across a battery of
811	/// disjoint, overlapping, and subset scenarios — including inputs large
812	/// enough to cross the linear/binary-search threshold — `VecMap::append`
813	/// must produce the same key/value pairs in the same order as
814	/// `BTreeMap::append`, and leave `other` empty in both cases.
815	#[test]
816	fn append_matches_btreemap_append_for_sample_inputs() {
817		type Scenario = (Vec<(i32, i32)>, Vec<(i32, i32)>);
818		let scenarios: Vec<Scenario> = vec![
819			// disjoint, self < other (concat path)
820			(vec![(1, 1), (2, 2)], vec![(3, 3), (4, 4)]),
821			// disjoint, self > other (merge path)
822			(vec![(5, 5), (6, 6)], vec![(1, 1), (2, 2)]),
823			// interleaved disjoint
824			(vec![(1, 10), (3, 30), (5, 50)], vec![(2, 20), (4, 40), (6, 60)]),
825			// single-key overlap
826			(vec![(1, 1), (2, 2), (3, 3)], vec![(3, 30), (4, 4), (5, 5)]),
827			// fully overlapping
828			(vec![(1, 1), (2, 2), (3, 3)], vec![(1, 100), (2, 200), (3, 300)]),
829			// other is subset of self
830			(vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)], vec![(2, 200), (4, 400)]),
831			// self is subset of other
832			(vec![(2, 2), (4, 4)], vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)]),
833			// empty cases
834			(vec![], vec![(1, 1), (2, 2)]),
835			(vec![(1, 1), (2, 2)], vec![]),
836			(vec![], vec![]),
837			// large inputs that exceed LINEAR_SEARCH_THRESHOLD (64) on both sides;
838			// every other key in `b` overlaps `a`, every alternate key extends past
839			(
840				(0..100i32).map(|i| (i * 2, i)).collect(),
841				(0..100i32).map(|i| (i * 2 + 1, i + 10_000)).collect(),
842			),
843			(
844				(0..100i32).map(|i| (i, i)).collect(),
845				(50..150i32).map(|i| (i, i + 1_000_000)).collect(),
846			),
847		];
848
849		for (i, (a_pairs, b_pairs)) in scenarios.into_iter().enumerate() {
850			let mut vm_a: VecMap<i32, i32> = a_pairs.iter().copied().collect();
851			let mut vm_b: VecMap<i32, i32> = b_pairs.iter().copied().collect();
852			let mut bt_a: BTreeMap<i32, i32> = a_pairs.iter().copied().collect();
853			let mut bt_b: BTreeMap<i32, i32> = b_pairs.iter().copied().collect();
854
855			vm_a.append(&mut vm_b);
856			bt_a.append(&mut bt_b);
857
858			assert!(vm_b.is_empty(), "scenario {i}: VecMap other not emptied");
859			assert!(bt_b.is_empty(), "scenario {i}: BTreeMap other not emptied");
860
861			let vm_pairs: Vec<_> = vm_a.iter().map(|(k, v)| (*k, *v)).collect();
862			let bt_pairs: Vec<_> = bt_a.iter().map(|(k, v)| (*k, *v)).collect();
863			assert_eq!(vm_pairs, bt_pairs, "scenario {i}: VecMap diverges from BTreeMap");
864			assert_sorted(&vm_a);
865		}
866	}
867
868	#[test]
869	fn merge_sorted_prefer_rhs_with_empty_inputs() {
870		let empty: VecMap<i32, i32> = VecMap::new();
871		assert!(VecMap::merge_sorted_prefer_rhs(empty.clone(), empty.clone()).is_empty());
872
873		let m: VecMap<i32, i32> = (0..3).map(|i| (i, i)).collect();
874		assert_eq!(VecMap::merge_sorted_prefer_rhs(m.clone(), empty.clone()), m);
875		assert_eq!(VecMap::merge_sorted_prefer_rhs(empty, m.clone()), m);
876	}
877
878	#[test]
879	fn merge_sorted_prefer_rhs_overlapping_uses_rhs_value() {
880		let a: VecMap<&str, i32> =
881			VecMap::from_sorted_vec_unchecked(vec![("a", 1), ("b", 2), ("c", 3)]);
882		let b: VecMap<&str, i32> =
883			VecMap::from_sorted_vec_unchecked(vec![("b", 22), ("c", 33), ("d", 4)]);
884		let m = VecMap::merge_sorted_prefer_rhs(a, b);
885		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
886		assert_eq!(pairs, vec![("a", 1), ("b", 22), ("c", 33), ("d", 4)]);
887	}
888
889	/// Drains the longer side into `out` once the shorter side is exhausted.
890	#[test]
891	fn merge_sorted_prefer_rhs_lhs_longer_then_rhs_longer() {
892		let a: VecMap<&str, i32> =
893			VecMap::from_sorted_vec_unchecked(vec![("a", 1), ("b", 2), ("c", 3)]);
894		let b: VecMap<&str, i32> = VecMap::from_sorted_vec_unchecked(vec![("a", 11)]);
895		let m = VecMap::merge_sorted_prefer_rhs(a, b);
896		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
897		assert_eq!(pairs, vec![("a", 11), ("b", 2), ("c", 3)]);
898
899		let a: VecMap<&str, i32> = VecMap::from_sorted_vec_unchecked(vec![("a", 1)]);
900		let b: VecMap<&str, i32> =
901			VecMap::from_sorted_vec_unchecked(vec![("b", 2), ("c", 3), ("d", 4)]);
902		let m = VecMap::merge_sorted_prefer_rhs(a, b);
903		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
904		assert_eq!(pairs, vec![("a", 1), ("b", 2), ("c", 3), ("d", 4)]);
905	}
906
907	#[test]
908	fn push_appends_in_order() {
909		let mut m = VecMap::new();
910		m.push(1, "a");
911		m.push(2, "b");
912		m.push(3, "c");
913		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
914		assert_eq!(pairs, vec![(1, "a"), (2, "b"), (3, "c")]);
915	}
916
917	#[test]
918	#[cfg(debug_assertions)]
919	#[should_panic(expected = "VecMap::push")]
920	fn push_out_of_order_panics_in_debug() {
921		let mut m = VecMap::new();
922		m.push(2, ());
923		m.push(1, ());
924	}
925
926	#[test]
927	#[cfg(debug_assertions)]
928	#[should_panic(expected = "VecMap::push")]
929	fn push_equal_key_panics_in_debug() {
930		let mut m = VecMap::new();
931		m.push(1, ());
932		m.push(1, ());
933	}
934
935	#[test]
936	fn iter_yields_keys_in_order() {
937		let m: VecMap<i32, i32> = [(2, 20), (1, 10), (3, 30)].into_iter().collect();
938		let keys: Vec<_> = m.iter().map(|(k, _)| *k).collect();
939		assert_eq!(keys, vec![1, 2, 3]);
940	}
941
942	#[test]
943	fn iter_size_hint_and_len() {
944		let m: VecMap<i32, i32> = (0..5).map(|i| (i, i)).collect();
945		let mut it = m.iter();
946		assert_eq!(it.size_hint(), (5, Some(5)));
947		assert_eq!(it.len(), 5);
948		it.next();
949		assert_eq!(it.size_hint(), (4, Some(4)));
950		assert_eq!(it.len(), 4);
951	}
952
953	#[test]
954	fn iter_clone_is_independent() {
955		let m: VecMap<i32, i32> = (0..3).map(|i| (i, i)).collect();
956		let mut a = m.iter();
957		let mut b = a.clone();
958		assert_eq!(a.next().map(|(k, _)| *k), Some(0));
959		assert_eq!(b.next().map(|(k, _)| *k), Some(0));
960		assert_eq!(a.next().map(|(k, _)| *k), Some(1));
961		assert_eq!(b.next().map(|(k, _)| *k), Some(1));
962	}
963
964	#[test]
965	fn iter_mut_allows_value_mutation_and_reports_size() {
966		let mut m: VecMap<i32, i32> = (0..3).map(|i| (i, i)).collect();
967		{
968			let it = m.iter_mut();
969			assert_eq!(it.size_hint(), (3, Some(3)));
970		}
971		for (_, v) in m.iter_mut() {
972			*v += 100;
973		}
974		let vs: Vec<_> = m.values().copied().collect();
975		assert_eq!(vs, vec![100, 101, 102]);
976	}
977
978	#[test]
979	fn keys_values_values_mut_in_order() {
980		let mut m: VecMap<&str, i32> = [("a", 1), ("b", 2)].into_iter().collect();
981		assert_eq!(m.keys().copied().collect::<Vec<_>>(), vec!["a", "b"]);
982		assert_eq!(m.values().copied().collect::<Vec<_>>(), vec![1, 2]);
983		for v in m.values_mut() {
984			*v *= 10;
985		}
986		assert_eq!(m.values().copied().collect::<Vec<_>>(), vec![10, 20]);
987	}
988
989	#[test]
990	fn first_and_last_key_value() {
991		let m: VecMap<i32, &str> = VecMap::new();
992		assert_eq!(m.first_key_value(), None);
993		assert_eq!(m.last_key_value(), None);
994
995		let m: VecMap<i32, &str> =
996			VecMap::from_sorted_vec_unchecked(vec![(1, "a"), (2, "b"), (3, "c")]);
997		assert_eq!(m.first_key_value(), Some((&1, &"a")));
998		assert_eq!(m.last_key_value(), Some((&3, &"c")));
999	}
1000
1001	#[test]
1002	fn entry_or_insert_with_for_vacant_then_occupied() {
1003		let mut m: VecMap<&str, i32> = VecMap::new();
1004		*m.entry("a").or_insert_with(|| 1) += 10;
1005		*m.entry("a").or_insert_with(|| 999) += 1;
1006		assert_eq!(m.get("a"), Some(&12));
1007		m.entry("c").or_insert_with(|| 3);
1008		m.entry("b").or_insert_with(|| 2);
1009		assert_sorted(&m);
1010		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
1011		assert_eq!(pairs, vec![("a", 12), ("b", 2), ("c", 3)]);
1012	}
1013
1014	#[test]
1015	fn index_returns_value_for_present_key() {
1016		let m: VecMap<i32, &str> = VecMap::from_sorted_vec_unchecked(vec![(1, "a"), (2, "b")]);
1017		assert_eq!(m[&1], "a");
1018		assert_eq!(m[&2], "b");
1019	}
1020
1021	#[test]
1022	#[should_panic(expected = "VecMap: index out of bounds")]
1023	fn index_missing_key_panics() {
1024		let m: VecMap<i32, i32> = VecMap::new();
1025		let _ = m[&1];
1026	}
1027
1028	#[test]
1029	fn into_iter_owned_yields_in_order() {
1030		let m: VecMap<i32, i32> = (0..3).map(|i| (i, i * 10)).collect();
1031		let pairs: Vec<_> = m.into_iter().collect();
1032		assert_eq!(pairs, vec![(0, 0), (1, 10), (2, 20)]);
1033	}
1034
1035	#[test]
1036	fn into_iter_owned_size_hint_and_len() {
1037		let m: VecMap<i32, i32> = (0..4).map(|i| (i, i)).collect();
1038		let mut it = m.into_iter();
1039		assert_eq!(it.size_hint(), (4, Some(4)));
1040		assert_eq!(it.len(), 4);
1041		it.next();
1042		assert_eq!(it.len(), 3);
1043	}
1044
1045	#[test]
1046	fn into_iter_borrowed_yields_in_order() {
1047		let m: VecMap<i32, i32> = (0..3).map(|i| (i, i * 10)).collect();
1048		let pairs: Vec<_> = (&m).into_iter().map(|(k, v)| (*k, *v)).collect();
1049		assert_eq!(pairs, vec![(0, 0), (1, 10), (2, 20)]);
1050	}
1051
1052	#[test]
1053	fn into_values_yields_in_key_order() {
1054		let m: VecMap<i32, &str> =
1055			VecMap::from_sorted_vec_unchecked(vec![(1, "a"), (2, "b"), (3, "c")]);
1056		let values: Vec<_> = m.into_values().collect();
1057		assert_eq!(values, vec!["a", "b", "c"]);
1058	}
1059
1060	#[test]
1061	fn from_iter_dedups_unsorted_input_keeping_last() {
1062		let m: VecMap<i32, &str> =
1063			vec![(2, "x"), (1, "a"), (2, "b"), (3, "c"), (2, "z")].into_iter().collect();
1064		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
1065		assert_eq!(pairs, vec![(1, "a"), (2, "z"), (3, "c")]);
1066	}
1067
1068	#[test]
1069	fn from_iter_empty_returns_default() {
1070		let m: VecMap<i32, i32> = std::iter::empty().collect();
1071		assert!(m.is_empty());
1072	}
1073
1074	/// `extend` into an empty map goes through the `FromIterator` fast path.
1075	#[test]
1076	fn extend_into_empty_uses_from_iter_path_and_dedups() {
1077		let mut m: VecMap<i32, i32> = VecMap::new();
1078		m.extend([(2, 20), (1, 10), (2, 200)]);
1079		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
1080		assert_eq!(pairs, vec![(1, 10), (2, 200)]);
1081	}
1082
1083	/// `extend` into a non-empty map uses repeated `insert`.
1084	#[test]
1085	fn extend_into_non_empty_uses_insert_path() {
1086		let mut m: VecMap<i32, i32> = [(1, 1)].into_iter().collect();
1087		m.extend([(0, 0), (1, 99), (2, 2)]);
1088		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
1089		assert_eq!(pairs, vec![(0, 0), (1, 99), (2, 2)]);
1090		assert_sorted(&m);
1091	}
1092
1093	#[test]
1094	fn from_btreemap_preserves_order() {
1095		let mut bt = BTreeMap::new();
1096		bt.insert(1, "a");
1097		bt.insert(3, "c");
1098		bt.insert(2, "b");
1099		let m: VecMap<i32, &str> = VecMap::from(bt);
1100		let pairs: Vec<_> = m.iter().map(|(k, v)| (*k, *v)).collect();
1101		assert_eq!(pairs, vec![(1, "a"), (2, "b"), (3, "c")]);
1102	}
1103
1104	#[test]
1105	fn equality_and_ord_are_lexicographic() {
1106		let a: VecMap<i32, i32> = [(1, 1), (2, 2)].into_iter().collect();
1107		let b: VecMap<i32, i32> = [(1, 1), (2, 3)].into_iter().collect();
1108		let c: VecMap<i32, i32> = [(1, 1), (2, 2)].into_iter().collect();
1109		assert_eq!(a, c);
1110		assert!(a < b);
1111		assert_eq!(a.cmp(&c), Ordering::Equal);
1112		assert_eq!(a.partial_cmp(&b), Some(Ordering::Less));
1113	}
1114
1115	#[test]
1116	fn hash_matches_for_equal_maps_built_in_different_order() {
1117		let a: VecMap<i32, i32> = [(1, 1), (2, 2), (3, 3)].into_iter().collect();
1118		let b: VecMap<i32, i32> = [(3, 3), (1, 1), (2, 2)].into_iter().collect();
1119		assert_eq!(a, b);
1120		assert_eq!(hash_of(&a), hash_of(&b));
1121	}
1122}