scylla/transport/locator/
replicas.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use itertools::Either;

use crate::transport::{Node, NodeRef};
use std::{ops::Index, sync::Arc};

/// Container holding replicas, enabling unified use of both borrowed and owned `Node` sequences.
///
/// This type is very similar to `Cow`, but unlike `Cow`,
/// it holds references in an `Owned` variant `Vec`.
#[derive(Debug)]
pub(crate) enum ReplicasArray<'a> {
    Borrowed(&'a [Arc<Node>]),
    Owned(Vec<NodeRef<'a>>),
}

impl<'a> ReplicasArray<'a> {
    pub(crate) fn get(&self, index: usize) -> Option<NodeRef<'a>> {
        match self {
            ReplicasArray::Borrowed(slice) => slice.get(index),
            ReplicasArray::Owned(vec) => vec.get(index).copied(),
        }
    }

    pub(crate) fn len(&self) -> usize {
        match self {
            ReplicasArray::Borrowed(slice) => slice.len(),
            ReplicasArray::Owned(vec) => vec.len(),
        }
    }

    pub(crate) fn iter<'s>(&'s self) -> impl Iterator<Item = NodeRef<'a>> + 's {
        match self {
            ReplicasArray::Borrowed(slice) => Either::Left(slice.iter()),
            ReplicasArray::Owned(vec) => Either::Right(vec.iter().copied()),
        }
    }
}

impl<'a> FromIterator<NodeRef<'a>> for ReplicasArray<'a> {
    fn from_iter<T: IntoIterator<Item = NodeRef<'a>>>(iter: T) -> Self {
        Self::Owned(iter.into_iter().collect())
    }
}

impl<'a> From<&'a [Arc<Node>]> for ReplicasArray<'a> {
    fn from(item: &'a [Arc<Node>]) -> Self {
        Self::Borrowed(item)
    }
}

impl<'a> Index<usize> for ReplicasArray<'a> {
    type Output = Arc<Node>;

    fn index(&self, index: usize) -> &Self::Output {
        match self {
            ReplicasArray::Borrowed(b) => &b[index],
            ReplicasArray::Owned(o) => o[index],
        }
    }
}

pub(crate) const EMPTY_REPLICAS: ReplicasArray<'static> = ReplicasArray::Borrowed(&[]);