skl/generic/multiple_version.rs
1use core::{
2 ops::{Bound, RangeBounds},
3 sync::atomic::Ordering,
4};
5
6use among::Among;
7use dbutils::{
8 buffer::VacantBuffer,
9 equivalentor::{TypeRefComparator, TypeRefQueryComparator},
10 types::{MaybeStructured, Type},
11};
12use either::Either;
13
14use crate::{
15 allocator::{Allocator, Sealed, WithVersion},
16 error::Error,
17 generic::{Active, MaybeTombstone},
18 ref_counter::RefCounter,
19 Arena, Header, Height, KeyBuilder, ValueBuilder, Version,
20};
21
22use super::{
23 list::{
24 iterator::{Iter, Range},
25 EntryRef,
26 },
27 Ascend,
28};
29
30/// Implementations for single-threaded environments.
31pub mod unsync {
32 use crate::generic::Ascend;
33 pub use crate::unsync::{multiple_version::Allocator, RefCounter};
34
35 #[cfg(any(all(test, not(miri)), all_skl_tests, test_generic_unsync_versioned,))]
36 mod tests {
37 crate::__generic_multiple_version_map_tests!("unsync_multiple_version_map": super::SkipMap<[u8], [u8]>);
38 }
39
40 type SkipList<K, V, C = Ascend> = super::super::list::SkipList<K, V, C, Allocator, RefCounter>;
41
42 /// Iterator over the [`SkipMap`].
43 pub type Iter<'a, K, V, S, C = Ascend> =
44 super::super::iter::Iter<'a, K, V, S, C, Allocator, RefCounter>;
45
46 /// Iterator over a subset of the [`SkipMap`].
47 pub type Range<'a, K, V, S, Q, R, C = Ascend> =
48 super::super::iter::Range<'a, K, V, S, C, Allocator, RefCounter, Q, R>;
49
50 /// The entry reference of the [`SkipMap`].
51 pub type Entry<'a, K, V, S, C = Ascend> =
52 super::super::entry::EntryRef<'a, K, V, S, C, Allocator, RefCounter>;
53
54 /// A fast, ARENA based `SkipMap` that supports multiple versions, forward and backward iteration.
55 ///
56 /// If you want to use in concurrent environment, you can use [`multiple_version::sync::SkipMap`](crate::generic::multiple_version::sync::SkipMap).
57 #[repr(transparent)]
58 pub struct SkipMap<K: ?Sized, V: ?Sized, C = Ascend>(SkipList<K, V, C>);
59
60 impl<K: ?Sized, V: ?Sized, C: Clone> Clone for SkipMap<K, V, C> {
61 #[inline]
62 fn clone(&self) -> Self {
63 Self(self.0.clone())
64 }
65 }
66
67 impl<K: ?Sized, V: ?Sized, C> From<SkipList<K, V, C>> for SkipMap<K, V, C> {
68 #[inline]
69 fn from(list: SkipList<K, V, C>) -> Self {
70 Self(list)
71 }
72 }
73
74 impl<K: ?Sized + 'static, V: ?Sized + 'static, C> crate::traits::List for SkipMap<K, V, C> {
75 type Constructable = SkipList<K, V, C>;
76
77 #[inline]
78 fn as_ref(&self) -> &Self::Constructable {
79 &self.0
80 }
81
82 #[inline]
83 fn as_mut(&mut self) -> &mut Self::Constructable {
84 &mut self.0
85 }
86
87 #[inline]
88 fn meta(
89 &self,
90 ) -> &<<Self::Constructable as crate::traits::Constructable>::Allocator as super::Sealed>::Meta
91 {
92 self.0.meta()
93 }
94 }
95
96 impl<K, V, C> super::Map<K, V, C> for SkipMap<K, V, C>
97 where
98 K: ?Sized + 'static,
99 V: ?Sized + 'static,
100 C: 'static,
101 {
102 type Allocator = Allocator;
103 type RefCounter = RefCounter;
104 }
105}
106
107/// Implementations for concurrent environments.
108pub mod sync {
109 use crate::generic::Ascend;
110 pub use crate::sync::{multiple_version::Allocator, RefCounter};
111
112 #[cfg(any(all(test, not(miri)), all_skl_tests, test_generic_sync_versioned,))]
113 mod tests {
114 crate::__generic_multiple_version_map_tests!("sync_multiple_version_map": super::SkipMap<[u8], [u8]>);
115 }
116
117 #[cfg(any(
118 all(test, not(miri)),
119 all_skl_tests,
120 test_generic_sync_multiple_version_concurrent,
121 ))]
122 mod concurrent_tests {
123 crate::__generic_multiple_version_map_tests!(go "sync_multiple_version_map": super::SkipMap<[u8], [u8]> => crate::tests::generic::TEST_OPTIONS);
124 }
125
126 #[cfg(any(
127 all(test, not(miri)),
128 all_skl_tests,
129 test_generic_sync_multiple_version_concurrent_with_optimistic_freelist,
130 ))]
131 mod concurrent_tests_with_optimistic_freelist {
132 crate::__generic_multiple_version_map_tests!(go "sync_multiple_version_map": super::SkipMap<[u8], [u8]> => crate::tests::generic::TEST_OPTIONS_WITH_OPTIMISTIC_FREELIST);
133 }
134
135 #[cfg(any(
136 all(test, not(miri)),
137 all_skl_tests,
138 test_generic_sync_multiple_version_concurrent_with_pessimistic_freelist,
139 ))]
140 mod concurrent_tests_with_pessimistic_freelist {
141 crate::__generic_multiple_version_map_tests!(go "sync_multiple_version_map": super::SkipMap<[u8], [u8]> => crate::tests::generic::TEST_OPTIONS_WITH_PESSIMISTIC_FREELIST);
142 }
143
144 type SkipList<K, V, C = Ascend> = super::super::list::SkipList<K, V, C, Allocator, RefCounter>;
145
146 /// Iterator over the [`SkipMap`].
147 pub type Iter<'a, K, V, S, C = Ascend> =
148 super::super::iter::Iter<'a, K, V, S, C, Allocator, RefCounter>;
149
150 /// Iterator over a subset of the [`SkipMap`].
151 pub type Range<'a, K, V, S, Q, R, C = Ascend> =
152 super::super::iter::Range<'a, K, V, S, C, Allocator, RefCounter, Q, R>;
153
154 /// The entry reference of the [`SkipMap`].
155 pub type Entry<'a, K, V, S, C = Ascend> =
156 super::super::entry::EntryRef<'a, K, V, S, C, Allocator, RefCounter>;
157
158 /// A fast, lock-free, thread-safe ARENA based `SkipMap` that supports multiple versions, forward and backward iteration.
159 ///
160 /// If you want to use in non-concurrent environment, you can use [`multiple_version::unsync::SkipMap`](crate::generic::multiple_version::unsync::SkipMap).
161 #[repr(transparent)]
162 pub struct SkipMap<K: ?Sized, V: ?Sized, C = Ascend>(SkipList<K, V, C>);
163
164 impl<K: ?Sized, V: ?Sized, C: Clone> Clone for SkipMap<K, V, C> {
165 #[inline]
166 fn clone(&self) -> Self {
167 Self(self.0.clone())
168 }
169 }
170
171 impl<K: ?Sized, V: ?Sized, C> From<SkipList<K, V, C>> for SkipMap<K, V, C> {
172 #[inline]
173 fn from(list: SkipList<K, V, C>) -> Self {
174 Self(list)
175 }
176 }
177
178 impl<K: ?Sized + 'static, V: ?Sized + 'static, C> crate::traits::List for SkipMap<K, V, C> {
179 type Constructable = SkipList<K, V, C>;
180
181 #[inline]
182 fn as_ref(&self) -> &Self::Constructable {
183 &self.0
184 }
185
186 #[inline]
187 fn as_mut(&mut self) -> &mut Self::Constructable {
188 &mut self.0
189 }
190
191 #[inline]
192 fn meta(
193 &self,
194 ) -> &<<Self::Constructable as crate::traits::Constructable>::Allocator as super::Sealed>::Meta
195 {
196 self.0.meta()
197 }
198 }
199
200 impl<K, V, C> super::Map<K, V, C> for SkipMap<K, V, C>
201 where
202 K: ?Sized + 'static,
203 V: ?Sized + 'static,
204 C: 'static,
205 {
206 type Allocator = Allocator;
207 type RefCounter = RefCounter;
208 }
209}
210
211/// A fast, ARENA based `SkipMap` that supports multiple versions, forward and backward iteration.
212///
213/// - For concurrent environment, use [`sync::SkipMap`].
214/// - For non-concurrent environment, use [`unsync::SkipMap`].
215pub trait Map<K, V, C = Ascend>
216where
217 K: ?Sized + 'static,
218 V: ?Sized + 'static,
219 C: 'static,
220 Self: Arena<Constructable = super::list::SkipList<K, V, C, Self::Allocator, Self::RefCounter>>,
221 <Self::Allocator as Sealed>::Node: WithVersion,
222{
223 /// The allocator type used to allocate nodes in the map.
224 type Allocator: Allocator;
225 /// The reference counter type used in the map.
226 type RefCounter: RefCounter;
227
228 /// Try creates from a `SkipMap` from an allocator directly.
229 ///
230 /// This method is not the ideal constructor, it is recommended to use [`Builder`](super::Builder) to create a `SkipMap`,
231 /// if you are not attempting to create multiple `SkipMap`s on the same allocator.
232 ///
233 /// Besides, the only way to reconstruct `SkipMap`s created by this method is to use the [`open_from_allocator(header: Header, arena: Self::Allocator, cmp: Self::Comparator)`](Map::open_from_allocator) method,
234 /// users must save the header to reconstruct the `SkipMap` by their own.
235 /// The header can be obtained by calling [`header`](Map::header) method.
236 #[inline]
237 fn create_from_allocator(arena: Self::Allocator, cmp: C) -> Result<Self, Error> {
238 Self::try_create_from_allocator(arena, cmp)
239 }
240
241 /// Try open a `SkipMap` from an allocator directly.
242 ///
243 /// See documentation for [`create_from_allocator`](Map::create_from_allocator) for more information.
244 ///
245 /// ## Safety
246 /// - The `header` must be the same as the one obtained from `SkipMap` when it was created.
247 /// - The `K` and `V` types must be the same as the types used to create the map.
248 #[inline]
249 unsafe fn open_from_allocator(
250 header: Header,
251 arena: Self::Allocator,
252 cmp: C,
253 ) -> Result<Self, Error> {
254 Self::try_open_from_allocator(arena, cmp, header)
255 }
256
257 /// Returns the header of the `SkipMap`, which can be used to reconstruct the `SkipMap`.
258 ///
259 /// By default, `SkipMap` will allocate meta, head node, and tail node in the ARENA,
260 /// and the data section will be allocated after the tail node.
261 ///
262 /// This method will return the header in the ARENA.
263 #[inline]
264 fn header(&self) -> Option<&Header> {
265 self.as_ref().header()
266 }
267
268 /// Returns the references for the `SkipMap`.
269 #[inline]
270 fn refs(&self) -> usize {
271 self.as_ref().refs()
272 }
273
274 /// Returns the height of the highest tower within any of the nodes that
275 /// have ever been allocated as part of this skiplist.
276 #[inline]
277 fn height(&self) -> u8 {
278 self.as_ref().height()
279 }
280
281 /// Returns the number of entries in the map, this `len` includes all entry versions.
282 ///
283 /// If the map only contains tombstones, this method will not return `0` but the number of tombstones.
284 #[inline]
285 fn len(&self) -> usize {
286 self.as_ref().len()
287 }
288
289 /// Returns `true` if the map is empty, if the map only contains tombstones, this method will also return `false`.
290 #[inline]
291 fn is_empty(&self) -> bool {
292 self.len() == 0
293 }
294
295 /// Returns the maximum version of all entries in the map.
296 #[inline]
297 fn maximum_version(&self) -> Version {
298 self.as_ref().maximum_version()
299 }
300
301 /// Returns the minimum version of all entries in the map.
302 #[inline]
303 fn minimum_version(&self) -> Version {
304 self.as_ref().minimum_version()
305 }
306
307 /// Returns a random generated height.
308 ///
309 /// This method is useful when you want to check if the underlying allocator can allocate a node.
310 ///
311 /// ## Example
312 ///
313 /// ```rust
314 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, Arena};
315 ///
316 /// let map = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
317 /// let height = map.random_height();
318 ///
319 /// let needed = SkipMap::<[u8], [u8]>::estimated_node_size(height, b"k1".len(), b"k2".len());
320 /// ```
321 #[inline]
322 fn random_height(&self) -> Height {
323 self.as_ref().random_height()
324 }
325
326 /// Returns `true` if the map may contains an entry whose version is less than or equal to the given version.
327 #[inline]
328 fn may_contain_version(&self, v: Version) -> bool {
329 self.as_ref().may_contain_version(v)
330 }
331
332 /// Returns `true` if the key exists in the map.
333 ///
334 /// This method will return `false` if the entry is marked as removed. If you want to check if the key exists even if it is marked as removed,
335 /// you can use [`contains_key_with_tombstone`](Map::contains_key_with_tombstone).
336 ///
337 /// ## Example
338 ///
339 /// ```rust
340 /// use skl::generic::{multiple_version::{sync::SkipMap, Map}, Builder};
341 ///
342 /// let map = Builder::new().with_capacity(1024).alloc::<SkipMap<str, str>>().unwrap();
343 ///
344 /// map.insert(0, "hello", "world").unwrap();
345 ///
346 /// map.get_or_remove(1, "hello").unwrap();
347 ///
348 /// assert!(!map.contains_key(1, "hello"));
349 /// assert!(map.contains_key_with_tombstone(1, "hello"));
350 /// ```
351 #[inline]
352 fn contains_key<'a, Q>(&'a self, version: Version, key: &Q) -> bool
353 where
354 K: Type,
355 V: Type,
356 Q: ?Sized,
357 C: TypeRefQueryComparator<'a, K, Q>,
358 {
359 if !self.may_contain_version(version) {
360 return false;
361 }
362
363 self.as_ref().get(version, key).is_some()
364 }
365
366 /// Returns `true` if the key exists in the map, even if it is marked as removed.
367 ///
368 /// ## Example
369 ///
370 /// ```rust
371 /// use skl::generic::{multiple_version::{sync::SkipMap, Map}, Builder};
372 ///
373 /// let map = Builder::new().with_capacity(1024).alloc::<SkipMap<str, str>>().unwrap();
374 ///
375 /// map.insert(0, "hello", "world").unwrap();
376 ///
377 /// map.get_or_remove(1, "hello").unwrap();
378 ///
379 /// assert!(!map.contains_key(1, "hello"));
380 /// assert!(map.contains_key_with_tombstone(1, "hello"));
381 /// ```
382 #[inline]
383 fn contains_key_with_tombstone<'a, Q>(&'a self, version: Version, key: &Q) -> bool
384 where
385 K: Type,
386 V: Type,
387 Q: ?Sized,
388 C: TypeRefQueryComparator<'a, K, Q>,
389 {
390 if !self.may_contain_version(version) {
391 return false;
392 }
393
394 self.as_ref().contains_key_with_tombstone(version, key)
395 }
396
397 /// Returns the first entry in the map.
398 #[inline]
399 fn first<'a>(
400 &'a self,
401 version: Version,
402 ) -> Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>
403 where
404 K: Type,
405 V: Type,
406 C: TypeRefComparator<'a, K>,
407 {
408 if !self.may_contain_version(version) {
409 return None;
410 }
411
412 self.as_ref().first(version)
413 }
414
415 /// Returns the last entry in the map.
416 #[inline]
417 fn last<'a>(
418 &'a self,
419 version: Version,
420 ) -> Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>
421 where
422 K: Type,
423 V: Type,
424 C: TypeRefComparator<'a, K>,
425 {
426 if !self.may_contain_version(version) {
427 return None;
428 }
429
430 self.as_ref().last(version)
431 }
432
433 /// Returns the first entry in the map. The returned entry may not be in valid state. (i.e. the entry is removed)
434 ///
435 /// The difference between [`first`](Map::first) and `first_with_tombstone` is that `first_with_tombstone` will return the value even if
436 /// the entry is removed or not in a valid state.
437 #[inline]
438 fn first_with_tombstone<'a>(
439 &'a self,
440 version: Version,
441 ) -> Option<EntryRef<'a, K, V, MaybeTombstone, C, Self::Allocator, Self::RefCounter>>
442 where
443 K: Type,
444 V: Type,
445 C: TypeRefComparator<'a, K>,
446 {
447 if !self.may_contain_version(version) {
448 return None;
449 }
450
451 self.as_ref().first_with_tombstone(version)
452 }
453
454 /// Returns the last entry in the map. The returned entry may not be in valid state. (i.e. the entry is removed)
455 ///
456 /// The difference between [`last`](Map::last) and `last_with_tombstone` is that `last_with_tombstone` will return the value even if
457 /// the entry is removed or not in a valid state.
458 #[inline]
459 fn last_with_tombstone<'a>(
460 &'a self,
461 version: Version,
462 ) -> Option<EntryRef<'a, K, V, MaybeTombstone, C, Self::Allocator, Self::RefCounter>>
463 where
464 K: Type,
465 V: Type,
466 C: TypeRefComparator<'a, K>,
467 {
468 if !self.may_contain_version(version) {
469 return None;
470 }
471
472 self.as_ref().last_with_tombstone(version)
473 }
474
475 /// Returns the value associated with the given key, if it exists.
476 ///
477 /// This method will return `None` if the entry is marked as removed. If you want to get the entry even if it is marked as removed,
478 /// you can use [`get_with_tombstone`](Map::get_with_tombstone).
479 ///
480 /// ## Example
481 ///
482 /// ```rust
483 /// use skl::generic::{multiple_version::{sync::SkipMap, Map}, Builder};
484 ///
485 /// let map = Builder::new().with_capacity(1024).alloc::<SkipMap<str, str>>().unwrap();
486 ///
487 /// map.insert(0, "hello", "world").unwrap();
488 ///
489 /// let ent = map.get(0, "hello").unwrap();
490 /// assert_eq!(ent.value(), "world");
491 ///
492 /// map.get_or_remove(1, "hello").unwrap();
493 ///
494 /// assert!(map.get(1, "hello").is_none());
495 /// ```
496 #[inline]
497 fn get<'a, Q>(
498 &'a self,
499 version: Version,
500 key: &Q,
501 ) -> Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>
502 where
503 K: Type,
504 V: Type,
505 Q: ?Sized,
506 C: TypeRefQueryComparator<'a, K, Q>,
507 {
508 if !self.may_contain_version(version) {
509 return None;
510 }
511
512 self.as_ref().get(version, key)
513 }
514
515 /// Returns the value associated with the given key, if it exists.
516 ///
517 /// The difference between `get` and `get_with_tombstone` is that `get_with_tombstone` will return the value even if the entry is removed.
518 ///
519 /// ## Example
520 ///
521 /// ```rust
522 /// use skl::generic::{multiple_version::{sync::SkipMap, Map}, Builder};
523 ///
524 /// let map = Builder::new().with_capacity(1024).alloc::<SkipMap<str, str>>().unwrap();
525 ///
526 /// map.insert(0, "hello", "world").unwrap();
527 ///
528 /// map.get_or_remove(1, "hello").unwrap();
529 ///
530 /// assert!(map.get(1, "hello").is_none());
531 ///
532 /// let ent = map.get_with_tombstone(1, "hello").unwrap();
533 /// // value is None because the entry is marked as removed.
534 /// assert!(ent.value().is_none());
535 /// ```
536 #[inline]
537 fn get_with_tombstone<'a, Q>(
538 &'a self,
539 version: Version,
540 key: &Q,
541 ) -> Option<EntryRef<'a, K, V, MaybeTombstone, C, Self::Allocator, Self::RefCounter>>
542 where
543 K: Type,
544 V: Type,
545 Q: ?Sized,
546 C: TypeRefQueryComparator<'a, K, Q>,
547 {
548 if !self.may_contain_version(version) {
549 return None;
550 }
551
552 self.as_ref().get_with_tombstone(version, key)
553 }
554
555 /// Returns an `EntryRef` pointing to the highest element whose key is below the given bound.
556 /// If no such element is found then `None` is returned.
557 #[inline]
558 fn upper_bound<'a, Q>(
559 &'a self,
560 version: Version,
561 upper: Bound<&Q>,
562 ) -> Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>
563 where
564 K: Type,
565 V: Type,
566 Q: ?Sized,
567 C: TypeRefQueryComparator<'a, K, Q>,
568 {
569 if !self.may_contain_version(version) {
570 return None;
571 }
572
573 self.as_ref().upper_bound(version, upper)
574 }
575
576 /// Returns an `EntryRef` pointing to the lowest element whose key is above the given bound.
577 /// If no such element is found then `None` is returned.
578 #[inline]
579 fn lower_bound<'a, Q>(
580 &'a self,
581 version: Version,
582 lower: Bound<&Q>,
583 ) -> Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>
584 where
585 K: Type,
586 V: Type,
587 Q: ?Sized,
588 C: TypeRefQueryComparator<'a, K, Q>,
589 {
590 if !self.may_contain_version(version) {
591 return None;
592 }
593
594 self.as_ref().lower_bound(version, lower)
595 }
596
597 /// Returns an `EntryRef` pointing to the highest element whose key is below the given bound.
598 /// If no such element is found then `None` is returned.
599 ///
600 /// The difference between [`upper_bound`](Map::upper_bound) and `upper_bound_with_tombstone` is that `upper_bound_with_tombstone` will return the value even if the entry is removed.
601 #[inline]
602 fn upper_bound_with_tombstone<'a, Q>(
603 &'a self,
604 version: Version,
605 upper: Bound<&Q>,
606 ) -> Option<EntryRef<'a, K, V, MaybeTombstone, C, Self::Allocator, Self::RefCounter>>
607 where
608 K: Type,
609 V: Type,
610 Q: ?Sized,
611 C: TypeRefQueryComparator<'a, K, Q>,
612 {
613 if !self.may_contain_version(version) {
614 return None;
615 }
616
617 self.as_ref().upper_bound_with_tombstone(version, upper)
618 }
619
620 /// Returns an `EntryRef` pointing to the lowest element whose key is above the given bound.
621 /// If no such element is found then `None` is returned.
622 ///
623 /// The difference between [`lower_bound`](Map::lower_bound) and `lower_bound_with_tombstone` is that `lower_bound_with_tombstone` will return the value even if the entry is removed.
624 #[inline]
625 fn lower_bound_with_tombstone<'a, Q>(
626 &'a self,
627 version: Version,
628 lower: Bound<&Q>,
629 ) -> Option<EntryRef<'a, K, V, MaybeTombstone, C, Self::Allocator, Self::RefCounter>>
630 where
631 K: Type,
632 V: Type,
633 Q: ?Sized,
634 C: TypeRefQueryComparator<'a, K, Q>,
635 {
636 if !self.may_contain_version(version) {
637 return None;
638 }
639
640 self.as_ref().lower_bound_with_tombstone(version, lower)
641 }
642
643 /// Returns a new iterator, this iterator will yield the latest version of all entries in the map less or equal to the given version.
644 #[inline]
645 fn iter(&self, version: Version) -> Iter<'_, K, V, Active, C, Self::Allocator, Self::RefCounter>
646 where
647 K: Type,
648 V: Type,
649 {
650 self.as_ref().iter(version)
651 }
652
653 /// Returns a new iterator, this iterator will yield all versions for all entries in the map less or equal to the given version.
654 #[inline]
655 fn iter_all(
656 &self,
657 version: Version,
658 ) -> Iter<'_, K, V, MaybeTombstone, C, Self::Allocator, Self::RefCounter>
659 where
660 K: Type,
661 V: Type,
662 {
663 self.as_ref().iter_all(version)
664 }
665
666 /// Returns a iterator that within the range, this iterator will yield the latest version of all entries in the range less or equal to the given version.
667 #[inline]
668 fn range<Q, R>(
669 &self,
670 version: Version,
671 range: R,
672 ) -> Range<'_, K, V, Active, C, Self::Allocator, Self::RefCounter, Q, R>
673 where
674 K: Type,
675 V: Type,
676 Q: ?Sized,
677 R: RangeBounds<Q>,
678 {
679 self.as_ref().range(version, range)
680 }
681
682 /// Returns a iterator that within the range, this iterator will yield all versions for all entries in the range less or equal to the given version.
683 #[inline]
684 fn range_all<Q, R>(
685 &self,
686 version: Version,
687 range: R,
688 ) -> Range<'_, K, V, MaybeTombstone, C, Self::Allocator, Self::RefCounter, Q, R>
689 where
690 K: Type,
691 V: Type,
692 Q: ?Sized,
693 R: RangeBounds<Q>,
694 {
695 self.as_ref().range_all(version, range)
696 }
697
698 /// Upserts a new key-value pair if it does not yet exist, if the key with the given version already exists, it will update the value.
699 /// Unlike [`get_or_insert`](Map::get_or_insert), this method will update the value if the key with the given version already exists.
700 ///
701 /// - Returns `Ok(None)` if the key was successfully inserted.
702 /// - Returns `Ok(Some(old))` if the key with the given version already exists and the value is successfully updated.
703 #[inline]
704 fn insert<'a, 'b: 'a>(
705 &'a self,
706 version: Version,
707 key: impl Into<MaybeStructured<'b, K>>,
708 value: impl Into<MaybeStructured<'b, V>>,
709 ) -> Result<
710 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
711 Among<K::Error, V::Error, Error>,
712 >
713 where
714 K: Type + 'b,
715 V: Type + 'b,
716 C: TypeRefComparator<'a, K>,
717 {
718 self.as_ref().insert(version, key, value)
719 }
720
721 /// Upserts a new key-value pair at the given height if it does not yet exist, if the key with the given version already exists, it will update the value.
722 /// Unlike [`get_or_insert_at_height`](Map::get_or_insert_at_height), this method will update the value if the key with the given version already exists.
723 ///
724 /// - Returns `Ok(None)` if the key was successfully inserted.
725 /// - Returns `Ok(Some(old))` if the key with the given version already exists and the value is successfully updated.
726 ///
727 /// ## Example
728 ///
729 /// ```rust
730 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, Arena};
731 ///
732 /// let map = Builder::new().with_capacity(1024).alloc::<SkipMap<str, str>>().unwrap();
733 ///
734 /// let height = map.random_height();
735 /// map.insert_at_height(0, height, "hello", "world").unwrap();
736 /// ```
737 #[inline]
738 fn insert_at_height<'a, 'b: 'a>(
739 &'a self,
740 version: Version,
741 height: Height,
742 key: impl Into<MaybeStructured<'b, K>>,
743 value: impl Into<MaybeStructured<'b, V>>,
744 ) -> Result<
745 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
746 Among<K::Error, V::Error, Error>,
747 >
748 where
749 K: Type + 'b,
750 V: Type + 'b,
751 C: TypeRefComparator<'a, K>,
752 {
753 self.as_ref().insert_at_height(version, height, key, value)
754 }
755
756 /// Upserts a new key if it does not yet exist, if the key with the given version already exists, it will update the value.
757 /// Unlike [`get_or_insert_with_value_builder`](Map::get_or_insert_with_value_builder), this method will update the value if the key with the given version already exists.
758 ///
759 /// This method is useful when you want to insert a key and you know the value size but you do not have the value
760 /// at this moment.
761 ///
762 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
763 /// and you must fill the buffer with bytes later in the closure.
764 ///
765 /// - Returns `Ok(None)` if the key was successfully inserted.
766 /// - Returns `Ok(Some(old))` if the key with the given version already exists and the value is successfully updated.
767 ///
768 /// ## Example
769 ///
770 /// ```rust
771 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, ValueBuilder};
772 ///
773 /// struct Person {
774 /// id: u32,
775 /// name: String,
776 /// }
777 ///
778 /// impl Person {
779 /// fn encoded_size(&self) -> usize {
780 /// 4 + self.name.len()
781 /// }
782 /// }
783 ///
784 ///
785 /// let alice = Person {
786 /// id: 1,
787 /// name: "Alice".to_string(),
788 /// };
789 ///
790 /// let encoded_size = alice.encoded_size();
791 ///
792 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
793 ///
794 /// let vb = ValueBuilder::new(encoded_size, |val: &mut skl::VacantBuffer<'_>| {
795 /// val.put_u32_le(alice.id).unwrap();
796 /// val.put_slice(alice.name.as_bytes()).unwrap();
797 /// Ok(encoded_size)
798 /// });
799 ///
800 /// l.insert_with_value_builder::<core::convert::Infallible>(1, b"alice".as_slice(), vb)
801 /// .unwrap();
802 /// ```
803 #[inline]
804 fn insert_with_value_builder<'a, 'b: 'a, E>(
805 &'a self,
806 version: Version,
807 key: impl Into<MaybeStructured<'b, K>>,
808 value_builder: ValueBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, E>>,
809 ) -> Result<
810 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
811 Among<K::Error, E, Error>,
812 >
813 where
814 K: Type + 'b,
815 V: Type + 'b,
816 C: TypeRefComparator<'a, K>,
817 {
818 self.as_ref().insert_at_height_with_value_builder(
819 version,
820 self.random_height(),
821 key,
822 value_builder,
823 )
824 }
825
826 /// Upserts a new key if it does not yet exist, if the key with the given version already exists, it will update the value.
827 /// Unlike [`get_or_insert_with_value_builder`](Map::get_or_insert_with_value_builder), this method will update the value if the key with the given version already exists.
828 ///
829 /// This method is useful when you want to insert a key and you know the value size but you do not have the value
830 /// at this moment.
831 ///
832 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
833 /// and you must fill the buffer with bytes later in the closure.
834 ///
835 /// - Returns `Ok(None)` if the key was successfully inserted.
836 /// - Returns `Ok(Some(old))` if the key with the given version already exists and the value is successfully updated.
837 ///
838 /// ## Example
839 ///
840 /// ```rust
841 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, ValueBuilder, Arena};
842 ///
843 /// struct Person {
844 /// id: u32,
845 /// name: String,
846 /// }
847 ///
848 /// impl Person {
849 /// fn encoded_size(&self) -> usize {
850 /// 4 + self.name.len()
851 /// }
852 /// }
853 ///
854 ///
855 /// let alice = Person {
856 /// id: 1,
857 /// name: "Alice".to_string(),
858 /// };
859 ///
860 /// let encoded_size = alice.encoded_size();
861 ///
862 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
863 ///
864 /// let vb = ValueBuilder::new(encoded_size, |val: &mut skl::VacantBuffer<'_>| {
865 /// val.put_u32_le(alice.id).unwrap();
866 /// val.put_slice(alice.name.as_bytes()).unwrap();
867 /// Ok(encoded_size)
868 /// });
869 ///
870 /// let height = l.random_height();
871 /// l.insert_at_height_with_value_builder::<core::convert::Infallible>(1, height, b"alice".as_slice(), vb)
872 /// .unwrap();
873 /// ```
874 #[inline]
875 fn insert_at_height_with_value_builder<'a, 'b: 'a, E>(
876 &'a self,
877 version: Version,
878 height: Height,
879 key: impl Into<MaybeStructured<'b, K>>,
880 value_builder: ValueBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, E>>,
881 ) -> Result<
882 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
883 Among<K::Error, E, Error>,
884 >
885 where
886 K: Type + 'b,
887 V: Type + 'b,
888 C: TypeRefComparator<'a, K>,
889 {
890 self
891 .as_ref()
892 .insert_at_height_with_value_builder(version, height, key, value_builder)
893 }
894
895 /// Inserts a new key-value pair if it does not yet exist.
896 ///
897 /// Unlike [`insert`](Map::insert), this method will not update the value if the key with the given version already exists.
898 ///
899 /// - Returns `Ok(None)` if the key was successfully get_or_inserted.
900 /// - Returns `Ok(Some(_))` if the key with the given version already exists.
901 #[inline]
902 fn get_or_insert<'a, 'b: 'a>(
903 &'a self,
904 version: Version,
905 key: impl Into<MaybeStructured<'b, K>>,
906 value: impl Into<MaybeStructured<'b, V>>,
907 ) -> Result<
908 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
909 Among<K::Error, V::Error, Error>,
910 >
911 where
912 K: Type + 'b,
913 V: Type + 'b,
914 C: TypeRefComparator<'a, K>,
915 {
916 self
917 .as_ref()
918 .get_or_insert_at_height(version, self.random_height(), key, value)
919 }
920
921 /// Inserts a new key-value pair at height if it does not yet exist.
922 ///
923 /// Unlike [`insert_at_height`](Map::insert_at_height), this method will not update the value if the key with the given version already exists.
924 ///
925 /// - Returns `Ok(None)` if the key was successfully get_or_inserted.
926 /// - Returns `Ok(Some(_))` if the key with the given version already exists.
927 #[inline]
928 fn get_or_insert_at_height<'a, 'b: 'a>(
929 &'a self,
930 version: Version,
931 height: Height,
932 key: impl Into<MaybeStructured<'b, K>>,
933 value: impl Into<MaybeStructured<'b, V>>,
934 ) -> Result<
935 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
936 Among<K::Error, V::Error, Error>,
937 >
938 where
939 K: Type + 'b,
940 V: Type + 'b,
941 C: TypeRefComparator<'a, K>,
942 {
943 self
944 .as_ref()
945 .get_or_insert_at_height(version, height, key, value)
946 }
947
948 /// Inserts a new key if it does not yet exist.
949 ///
950 /// Unlike [`insert_with_value_builder`](Map::insert_with_value_builder), this method will not update the value if the key with the given version already exists.
951 ///
952 /// This method is useful when you want to get_or_insert a key and you know the value size but you do not have the value
953 /// at this moment.
954 ///
955 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
956 /// and you must fill the buffer with bytes later in the closure.
957 ///
958 /// - Returns `Ok(None)` if the key was successfully get_or_inserted.
959 /// - Returns `Ok(Some(_))` if the key with the given version already exists.
960 ///
961 /// ## Example
962 ///
963 /// ```rust
964 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, ValueBuilder};
965 ///
966 /// struct Person {
967 /// id: u32,
968 /// name: String,
969 /// }
970 ///
971 /// impl Person {
972 /// fn encoded_size(&self) -> usize {
973 /// 4 + self.name.len()
974 /// }
975 /// }
976 ///
977 ///
978 /// let alice = Person {
979 /// id: 1,
980 /// name: "Alice".to_string(),
981 /// };
982 ///
983 /// let encoded_size = alice.encoded_size();
984 ///
985 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
986 ///
987 /// let vb = ValueBuilder::new(encoded_size, |val: &mut skl::VacantBuffer<'_>| {
988 /// val.put_u32_le(alice.id).unwrap();
989 /// val.put_slice(alice.name.as_bytes()).unwrap();
990 /// Ok(encoded_size)
991 /// });
992 /// l.get_or_insert_with_value_builder::<core::convert::Infallible>(1, b"alice".as_slice(), vb)
993 /// .unwrap();
994 /// ```
995 #[inline]
996 fn get_or_insert_with_value_builder<'a, 'b: 'a, E>(
997 &'a self,
998 version: Version,
999 key: impl Into<MaybeStructured<'b, K>>,
1000 value_builder: ValueBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, E>>,
1001 ) -> Result<
1002 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1003 Among<K::Error, E, Error>,
1004 >
1005 where
1006 K: Type + 'b,
1007 V: Type + 'b,
1008 C: TypeRefComparator<'a, K>,
1009 {
1010 self.get_or_insert_at_height_with_value_builder(
1011 version,
1012 self.random_height(),
1013 key,
1014 value_builder,
1015 )
1016 }
1017
1018 /// Inserts a new key if it does not yet exist.
1019 ///
1020 /// Unlike [`insert_at_height_with_value_builder`](Map::insert_at_height_with_value_builder), this method will not update the value if the key with the given version already exists.
1021 ///
1022 /// This method is useful when you want to get_or_insert a key and you know the value size but you do not have the value
1023 /// at this moment.
1024 ///
1025 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
1026 /// and you must fill the buffer with bytes later in the closure.
1027 ///
1028 /// - Returns `Ok(None)` if the key was successfully get_or_inserted.
1029 /// - Returns `Ok(Some(_))` if the key with the given version already exists.
1030 ///
1031 /// ## Example
1032 ///
1033 /// ```rust
1034 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, ValueBuilder, Arena};
1035 ///
1036 /// struct Person {
1037 /// id: u32,
1038 /// name: String,
1039 /// }
1040 ///
1041 /// impl Person {
1042 /// fn encoded_size(&self) -> usize {
1043 /// 4 + self.name.len()
1044 /// }
1045 /// }
1046 ///
1047 ///
1048 /// let alice = Person {
1049 /// id: 1,
1050 /// name: "Alice".to_string(),
1051 /// };
1052 ///
1053 /// let encoded_size = alice.encoded_size();
1054 ///
1055 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
1056 ///
1057 /// let vb = ValueBuilder::new(encoded_size, |val: &mut skl::VacantBuffer<'_>| {
1058 /// val.put_u32_le(alice.id).unwrap();
1059 /// val.put_slice(alice.name.as_bytes()).unwrap();
1060 /// Ok(encoded_size)
1061 /// });
1062 ///
1063 /// let height = l.random_height();
1064 /// l.get_or_insert_at_height_with_value_builder::<core::convert::Infallible>(1, height, b"alice".as_slice(), vb)
1065 /// .unwrap();
1066 /// ```
1067 #[inline]
1068 fn get_or_insert_at_height_with_value_builder<'a, 'b: 'a, E>(
1069 &'a self,
1070 version: Version,
1071 height: Height,
1072 key: impl Into<MaybeStructured<'b, K>>,
1073 value_builder: ValueBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, E>>,
1074 ) -> Result<
1075 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1076 Among<K::Error, E, Error>,
1077 >
1078 where
1079 K: Type + 'b,
1080 V: Type + 'b,
1081 C: TypeRefComparator<'a, K>,
1082 {
1083 self
1084 .as_ref()
1085 .get_or_insert_at_height_with_value_builder(version, height, key, value_builder)
1086 }
1087
1088 /// Upserts a new key if it does not yet exist, if the key with the given version already exists, it will update the value.
1089 /// Unlike [`get_or_insert_with_builders`](Map::get_or_insert_with_builders), this method will update the value if the key with the given version already exists.
1090 ///
1091 /// This method is useful when you want to insert a key and you know the key size and value size but you do not have the key and value
1092 /// at this moment.
1093 ///
1094 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
1095 /// and you must fill the buffer with bytes later in the closure.
1096 ///
1097 /// - Returns `Ok(None)` if the key was successfully inserted.
1098 /// - Returns `Ok(Some(old))` if the key with the given version already exists and the value is successfully updated.
1099 ///
1100 /// ## Example
1101 ///
1102 /// ```rust
1103 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, KeyBuilder, ValueBuilder};
1104 ///
1105 /// struct Person {
1106 /// id: u32,
1107 /// name: String,
1108 /// }
1109 ///
1110 /// impl Person {
1111 /// fn encoded_size(&self) -> usize {
1112 /// 4 + self.name.len()
1113 /// }
1114 /// }
1115 ///
1116 ///
1117 /// let alice = Person {
1118 /// id: 1,
1119 /// name: "Alice".to_string(),
1120 /// };
1121 ///
1122 /// let encoded_size = alice.encoded_size();
1123 ///
1124 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
1125 ///
1126 /// let kb = KeyBuilder::new(5u8.into(), |key: &mut skl::VacantBuffer<'_>| {
1127 /// key.put_slice(b"alice").unwrap();
1128 /// Ok(5)
1129 /// });
1130 ///
1131 /// let vb = ValueBuilder::new(encoded_size, |val: &mut skl::VacantBuffer<'_>| {
1132 /// val.put_u32_le(alice.id).unwrap();
1133 /// val.put_slice(alice.name.as_bytes()).unwrap();
1134 /// Ok(encoded_size)
1135 /// });
1136 ///
1137 /// l.insert_with_builders::<(), ()>(1, kb, vb)
1138 /// .unwrap();
1139 /// ```
1140 #[inline]
1141 fn insert_with_builders<'a, KE, VE>(
1142 &'a self,
1143 version: Version,
1144 key_builder: KeyBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, KE>>,
1145 value_builder: ValueBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, VE>>,
1146 ) -> Result<
1147 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1148 Among<KE, VE, Error>,
1149 >
1150 where
1151 K: Type,
1152 V: Type,
1153 C: TypeRefComparator<'a, K>,
1154 {
1155 self.as_ref().insert_at_height_with_builders(
1156 version,
1157 self.random_height(),
1158 key_builder,
1159 value_builder,
1160 )
1161 }
1162
1163 /// Upserts a new key if it does not yet exist, if the key with the given version already exists, it will update the value.
1164 ///
1165 /// Unlike [`get_or_insert_with_builders`](Map::get_or_insert_with_builders), this method will update the value if the key with the given version already exists.
1166 ///
1167 /// This method is useful when you want to insert a key and you know the key size and value size but you do not have the key and value
1168 /// at this moment.
1169 ///
1170 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
1171 /// and you must fill the buffer with bytes later in the closure.
1172 ///
1173 /// - Returns `Ok(None)` if the key was successfully inserted.
1174 /// - Returns `Ok(Some(old))` if the key with the given version already exists and the value is successfully updated.
1175 ///
1176 /// ## Example
1177 ///
1178 /// ```rust
1179 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, KeyBuilder, ValueBuilder, Arena};
1180 ///
1181 /// struct Person {
1182 /// id: u32,
1183 /// name: String,
1184 /// }
1185 ///
1186 /// impl Person {
1187 /// fn encoded_size(&self) -> usize {
1188 /// 4 + self.name.len()
1189 /// }
1190 /// }
1191 ///
1192 ///
1193 /// let alice = Person {
1194 /// id: 1,
1195 /// name: "Alice".to_string(),
1196 /// };
1197 ///
1198 /// let encoded_size = alice.encoded_size();
1199 ///
1200 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
1201 ///
1202 /// let kb = KeyBuilder::new(5u8.into(), |key: &mut skl::VacantBuffer<'_>| {
1203 /// key.put_slice(b"alice").unwrap();
1204 /// Ok(5)
1205 /// });
1206 ///
1207 /// let vb = ValueBuilder::new(encoded_size, |val: &mut skl::VacantBuffer<'_>| {
1208 /// val.put_u32_le(alice.id).unwrap();
1209 /// val.put_slice(alice.name.as_bytes()).unwrap();
1210 /// Ok(encoded_size)
1211 /// });
1212 ///
1213 /// let height = l.random_height();
1214 /// l.insert_at_height_with_builders::<(), ()>(1, height, kb, vb)
1215 /// .unwrap();
1216 /// ```
1217 #[inline]
1218 fn insert_at_height_with_builders<'a, KE, VE>(
1219 &'a self,
1220 version: Version,
1221 height: Height,
1222 key_builder: KeyBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, KE>>,
1223 value_builder: ValueBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, VE>>,
1224 ) -> Result<
1225 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1226 Among<KE, VE, Error>,
1227 >
1228 where
1229 K: Type,
1230 V: Type,
1231 C: TypeRefComparator<'a, K>,
1232 {
1233 self
1234 .as_ref()
1235 .insert_at_height_with_builders(version, height, key_builder, value_builder)
1236 }
1237
1238 /// Inserts a new key if it does not yet exist.
1239 ///
1240 /// Unlike [`insert_with_builders`](Map::insert_with_builders), this method will not update the value if the key with the given version already exists.
1241 ///
1242 /// This method is useful when you want to get_or_insert a key and you know the value size but you do not have the value
1243 /// at this moment.
1244 ///
1245 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
1246 /// and you must fill the buffer with bytes later in the closure.
1247 ///
1248 /// ## Example
1249 ///
1250 /// ```rust
1251 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, KeyBuilder, ValueBuilder};
1252 ///
1253 /// struct Person {
1254 /// id: u32,
1255 /// name: String,
1256 /// }
1257 ///
1258 /// impl Person {
1259 /// fn encoded_size(&self) -> usize {
1260 /// 4 + self.name.len()
1261 /// }
1262 /// }
1263 ///
1264 ///
1265 /// let alice = Person {
1266 /// id: 1,
1267 /// name: "Alice".to_string(),
1268 /// };
1269 ///
1270 /// let encoded_size = alice.encoded_size();
1271 ///
1272 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
1273 ///
1274 /// let kb = KeyBuilder::new(5u8.into(), |key: &mut skl::VacantBuffer<'_>| {
1275 /// key.put_slice(b"alice").unwrap();
1276 /// Ok(5)
1277 /// });
1278 ///
1279 /// let vb = ValueBuilder::new(encoded_size, |val: &mut skl::VacantBuffer<'_>| {
1280 /// val.put_u32_le(alice.id).unwrap();
1281 /// val.put_slice(alice.name.as_bytes()).unwrap();
1282 /// Ok(encoded_size)
1283 /// });
1284 ///
1285 /// l.get_or_insert_with_builders::<(), ()>(1, kb, vb)
1286 /// .unwrap();
1287 /// ```
1288 #[inline]
1289 fn get_or_insert_with_builders<'a, KE, VE>(
1290 &'a self,
1291 version: Version,
1292 key_builder: KeyBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, KE>>,
1293 value_builder: ValueBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, VE>>,
1294 ) -> Result<
1295 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1296 Among<KE, VE, Error>,
1297 >
1298 where
1299 K: Type,
1300 V: Type,
1301 C: TypeRefComparator<'a, K>,
1302 {
1303 self.as_ref().get_or_insert_at_height_with_builders(
1304 version,
1305 self.random_height(),
1306 key_builder,
1307 value_builder,
1308 )
1309 }
1310
1311 /// Inserts a new key if it does not yet exist.
1312 ///
1313 /// Unlike [`insert_at_height_with_builders`](Map::insert_at_height_with_builders), this method will not update the value if the key with the given version already exists.
1314 ///
1315 /// This method is useful when you want to get_or_insert a key and you know the value size but you do not have the value
1316 /// at this moment.
1317 ///
1318 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
1319 /// and you must fill the buffer with bytes later in the closure.
1320 ///
1321 /// ## Example
1322 ///
1323 /// ```rust
1324 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, KeyBuilder, ValueBuilder, Arena};
1325 ///
1326 /// struct Person {
1327 /// id: u32,
1328 /// name: String,
1329 /// }
1330 ///
1331 /// impl Person {
1332 /// fn encoded_size(&self) -> usize {
1333 /// 4 + self.name.len()
1334 /// }
1335 /// }
1336 ///
1337 ///
1338 /// let alice = Person {
1339 /// id: 1,
1340 /// name: "Alice".to_string(),
1341 /// };
1342 ///
1343 /// let encoded_size = alice.encoded_size();
1344 ///
1345 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
1346 ///
1347 /// let kb = KeyBuilder::new(5u8.into(), |key: &mut skl::VacantBuffer<'_>| {
1348 /// key.put_slice(b"alice").unwrap();
1349 /// Ok(5)
1350 /// });
1351 ///
1352 /// let vb = ValueBuilder::new(encoded_size, |val: &mut skl::VacantBuffer<'_>| {
1353 /// val.put_u32_le(alice.id).unwrap();
1354 /// val.put_slice(alice.name.as_bytes()).unwrap();
1355 /// Ok(encoded_size)
1356 /// });
1357 ///
1358 /// let height = l.random_height();
1359 /// l.get_or_insert_at_height_with_builders::<(), ()>(1, height, kb, vb)
1360 /// .unwrap();
1361 /// ```
1362 #[inline]
1363 fn get_or_insert_at_height_with_builders<'a, KE, VE>(
1364 &'a self,
1365 version: Version,
1366 height: Height,
1367 key_builder: KeyBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, KE>>,
1368 value_builder: ValueBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, VE>>,
1369 ) -> Result<
1370 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1371 Among<KE, VE, Error>,
1372 >
1373 where
1374 K: Type,
1375 V: Type,
1376 C: TypeRefComparator<'a, K>,
1377 {
1378 self
1379 .as_ref()
1380 .get_or_insert_at_height_with_builders(version, height, key_builder, value_builder)
1381 }
1382
1383 /// Removes the key-value pair if it exists. A CAS operation will be used to ensure the operation is atomic.
1384 ///
1385 /// Unlike [`get_or_remove`](Map::get_or_remove), this method will remove the value if the key with the given version already exists.
1386 ///
1387 /// - Returns `Ok(None)`:
1388 /// - if the remove operation is successful or the key is marked in remove status by other threads.
1389 /// - Returns `Ok(Either::Right(current))` if the key with the given version already exists
1390 /// and the entry is not successfully removed because of an update on this entry happens in another thread.
1391 #[inline]
1392 fn compare_remove<'a, 'b: 'a>(
1393 &'a self,
1394 version: Version,
1395 key: impl Into<MaybeStructured<'b, K>>,
1396 success: Ordering,
1397 failure: Ordering,
1398 ) -> Result<
1399 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1400 Either<K::Error, Error>,
1401 >
1402 where
1403 K: Type + 'b,
1404 V: Type,
1405 C: TypeRefComparator<'a, K>,
1406 {
1407 self.compare_remove_at_height(version, self.random_height(), key, success, failure)
1408 }
1409
1410 /// Removes the key-value pair if it exists. A CAS operation will be used to ensure the operation is atomic.
1411 ///
1412 /// Unlike [`get_or_remove_at_height`](Map::get_or_remove_at_height), this method will remove the value if the key with the given version already exists.
1413 ///
1414 /// - Returns `Ok(None)`:
1415 /// - if the remove operation is successful or the key is marked in remove status by other threads.
1416 /// - Returns `Ok(Either::Right(current))` if the key with the given version already exists
1417 /// and the entry is not successfully removed because of an update on this entry happens in another thread.
1418 #[inline]
1419 fn compare_remove_at_height<'a, 'b: 'a>(
1420 &'a self,
1421 version: Version,
1422 height: Height,
1423 key: impl Into<MaybeStructured<'b, K>>,
1424 success: Ordering,
1425 failure: Ordering,
1426 ) -> Result<
1427 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1428 Either<K::Error, Error>,
1429 >
1430 where
1431 K: Type + 'b,
1432 V: Type,
1433 C: TypeRefComparator<'a, K>,
1434 {
1435 self
1436 .as_ref()
1437 .compare_remove_at_height(version, height, key, success, failure)
1438 }
1439
1440 /// Gets or removes the key-value pair if it exists.
1441 ///
1442 /// Unlike [`compare_remove`](Map::compare_remove), this method will not remove the value if the key with the given version already exists.
1443 ///
1444 /// - Returns `Ok(None)` if the key does not exist.
1445 /// - Returns `Ok(Some(old))` if the key with the given version already exists.
1446 #[inline]
1447 fn get_or_remove<'a, 'b: 'a>(
1448 &'a self,
1449 version: Version,
1450 key: impl Into<MaybeStructured<'b, K>>,
1451 ) -> Result<
1452 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1453 Either<K::Error, Error>,
1454 >
1455 where
1456 K: Type + 'b,
1457 V: Type,
1458 C: TypeRefComparator<'a, K>,
1459 {
1460 self.get_or_remove_at_height(version, self.random_height(), key)
1461 }
1462
1463 /// Gets or removes the key-value pair if it exists.
1464 ///
1465 /// Unlike [`compare_remove_at_height`](Map::compare_remove_at_height), this method will not remove the value if the key with the given version already exists.
1466 ///
1467 /// - Returns `Ok(None)` if the key does not exist.
1468 /// - Returns `Ok(Some(old))` if the key with the given version already exists.
1469 ///
1470 /// ## Example
1471 ///
1472 /// ```rust
1473 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, Arena};
1474 ///
1475 /// let map = Builder::new().with_capacity(1024).alloc::<SkipMap<str, str>>().unwrap();
1476 ///
1477 /// map.insert(0, "hello", "world").unwrap();
1478 ///
1479 /// let height = map.random_height();
1480 /// map.get_or_remove_at_height(0, height, "hello").unwrap();
1481 /// ```
1482 #[inline]
1483 fn get_or_remove_at_height<'a, 'b: 'a>(
1484 &'a self,
1485 version: Version,
1486 height: Height,
1487 key: impl Into<MaybeStructured<'b, K>>,
1488 ) -> Result<
1489 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1490 Either<K::Error, Error>,
1491 >
1492 where
1493 K: Type + 'b,
1494 V: Type,
1495 C: TypeRefComparator<'a, K>,
1496 {
1497 self.as_ref().get_or_remove_at_height(version, height, key)
1498 }
1499
1500 /// Gets or removes the key-value pair if it exists.
1501 ///
1502 /// - Returns `Ok(None)` if the key does not exist.
1503 /// - Returns `Ok(Some(old))` if the key with the given version already exists.
1504 ///
1505 /// This method is useful when you want to get_or_remove a key and you know the key size but you do not have the key
1506 /// at this moment.
1507 ///
1508 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
1509 /// and you must fill the buffer with bytes later in the closure.
1510 ///
1511 /// ## Example
1512 ///
1513 /// ```rust
1514 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, KeyBuilder};
1515 ///
1516 /// struct Person {
1517 /// id: u32,
1518 /// name: String,
1519 /// }
1520 ///
1521 /// impl Person {
1522 /// fn encoded_size(&self) -> usize {
1523 /// 4 + self.name.len()
1524 /// }
1525 /// }
1526 ///
1527 ///
1528 /// let alice = Person {
1529 /// id: 1,
1530 /// name: "Alice".to_string(),
1531 /// };
1532 ///
1533 /// let encoded_size = alice.encoded_size();
1534 ///
1535 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
1536 ///
1537 /// let kb = KeyBuilder::new(5u8.into(), |key: &mut skl::VacantBuffer<'_>| {
1538 /// key.put_slice(b"alice").unwrap();
1539 /// Ok(5)
1540 /// });
1541 /// l.get_or_remove_with_builder::<core::convert::Infallible>(1, kb)
1542 /// .unwrap();
1543 /// ```
1544 #[inline]
1545 fn get_or_remove_with_builder<'a, 'b: 'a, E>(
1546 &'a self,
1547 version: Version,
1548 key_builder: KeyBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, E>>,
1549 ) -> Result<
1550 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1551 Either<E, Error>,
1552 >
1553 where
1554 K: Type,
1555 V: Type,
1556 C: TypeRefComparator<'a, K>,
1557 {
1558 self
1559 .as_ref()
1560 .get_or_remove_at_height_with_builder(version, self.random_height(), key_builder)
1561 }
1562
1563 /// Gets or removes the key-value pair if it exists.
1564 ///
1565 /// - Returns `Ok(None)` if the key does not exist.
1566 /// - Returns `Ok(Some(old))` if the key with the given version already exists.
1567 ///
1568 /// This method is useful when you want to get_or_remove a key and you know the key size but you do not have the key
1569 /// at this moment.
1570 ///
1571 /// A placeholder will be inserted first, then you will get an [`VacantBuffer`],
1572 /// and you must fill the buffer with bytes later in the closure.
1573 ///
1574 /// ## Example
1575 ///
1576 /// ```rust
1577 /// use skl::{generic::{multiple_version::{sync::SkipMap, Map}, Builder}, KeyBuilder, Arena};
1578 ///
1579 /// struct Person {
1580 /// id: u32,
1581 /// name: String,
1582 /// }
1583 ///
1584 /// impl Person {
1585 /// fn encoded_size(&self) -> usize {
1586 /// 4 + self.name.len()
1587 /// }
1588 /// }
1589 ///
1590 ///
1591 /// let alice = Person {
1592 /// id: 1,
1593 /// name: "Alice".to_string(),
1594 /// };
1595 ///
1596 /// let encoded_size = alice.encoded_size();
1597 ///
1598 /// let l = Builder::new().with_capacity(1024).alloc::<SkipMap<[u8], [u8]>>().unwrap();
1599 ///
1600 /// let kb = KeyBuilder::new(5u8.into(), |key: &mut skl::VacantBuffer<'_>| {
1601 /// key.put_slice(b"alice").unwrap();
1602 /// Ok(5)
1603 /// });
1604 /// let height = l.random_height();
1605 /// l.get_or_remove_at_height_with_builder::<core::convert::Infallible>(1, height, kb)
1606 /// .unwrap();
1607 /// ```
1608 #[inline]
1609 fn get_or_remove_at_height_with_builder<'a, 'b: 'a, E>(
1610 &'a self,
1611 version: Version,
1612 height: Height,
1613 key_builder: KeyBuilder<impl FnOnce(&mut VacantBuffer<'a>) -> Result<usize, E>>,
1614 ) -> Result<
1615 Option<EntryRef<'a, K, V, Active, C, Self::Allocator, Self::RefCounter>>,
1616 Either<E, Error>,
1617 >
1618 where
1619 K: Type,
1620 V: Type,
1621 C: TypeRefComparator<'a, K>,
1622 {
1623 self
1624 .as_ref()
1625 .get_or_remove_at_height_with_builder(version, height, key_builder)
1626 }
1627}