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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
crate::ix!();

pub struct NodeEvictionCandidate
{
    pub id:                NodeId,
    pub n_time_connected:  Option<OffsetDateTime>,
    pub min_ping_time:     Option<Duration>, /* micros */
    pub n_last_block_time: Option<OffsetDateTime>,
    pub n_last_tx_time:    Option<OffsetDateTime>,
    pub relevant_services: bool,
    pub relay_txes:        bool,
    pub bloom_filter:      bool,
    pub n_keyed_net_group: u64,
    pub prefer_evict:      bool,
    pub is_local:          bool,
    pub network:           Network,
}

//-----------------------------------------------

/**
  | Sort an array by the specified comparator,
  | then erase the last K elements where
  | predicate is true.
  |
  */
pub fn erase_last_kelements<T, Comparator>(
        elements:   &mut Vec<T>,
        comparator: Comparator,
        k:          usize,
        predicate:  fn(_0: &NodeEvictionCandidate) -> bool)  {

    todo!();
        /*
           let predicate = predicate.unwrap_or([](const NodeEvictionCandidate& n) { return true; });
           std::sort(elements.begin(), elements.end(), comparator);
        size_t eraseSize = std::min(k, elements.size());
        elements.erase(std::remove_if(elements.end() - eraseSize, elements.end(), predicate), elements.end());
        */
}

pub fn compare_node_block_time(
        a: &NodeEvictionCandidate,
        b: &NodeEvictionCandidate) -> bool {
    
    todo!();
        /*
            // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block.
        if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime;
        if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices;
        return a.nTimeConnected > b.nTimeConnected;
        */
}

pub fn compare_node_tx_time(
        a: &NodeEvictionCandidate,
        b: &NodeEvictionCandidate) -> bool {
    
    todo!();
        /*
            // There is a fall-through here because it is common for a node to have more than a few peers that have not yet relayed txn.
        if (a.nLastTXTime != b.nLastTXTime) return a.nLastTXTime < b.nLastTXTime;
        if (a.fRelayTxes != b.fRelayTxes) return b.fRelayTxes;
        if (a.fBloomFilter != b.fBloomFilter) return a.fBloomFilter;
        return a.nTimeConnected > b.nTimeConnected;
        */
}

/**
  | Pick out the potential block-relay
  | only peers, and sort them by last block
  | time.
  |
  */
pub fn compare_node_block_relay_only_time(
        a: &NodeEvictionCandidate,
        b: &NodeEvictionCandidate) -> bool {
    
    todo!();
        /*
            if (a.fRelayTxes != b.fRelayTxes) return a.fRelayTxes;
        if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime;
        if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices;
        return a.nTimeConnected > b.nTimeConnected;
        */
}

pub fn reverse_compare_node_min_ping_time(
        a: &NodeEvictionCandidate,
        b: &NodeEvictionCandidate) -> bool {
    
    todo!();
        /*
            return a.m_min_ping_time > b.m_min_ping_time;
        */
}

pub fn reverse_compare_node_time_connected(
        a: &NodeEvictionCandidate,
        b: &NodeEvictionCandidate) -> bool {
    
    todo!();
        /*
            return a.nTimeConnected > b.nTimeConnected;
        */
}

pub fn compare_net_group_keyed(
        a: &NodeEvictionCandidate,
        b: &NodeEvictionCandidate) -> bool {
    
    todo!();
        /*
            return a.nKeyedNetGroup < b.nKeyedNetGroup;
        */
}