Skip to content

Commit 2262c79

Browse files
committed
Feature: LogIdList: add method purge() to delete log ids
1 parent deeb67b commit 2262c79

File tree

2 files changed

+98
-15
lines changed

2 files changed

+98
-15
lines changed

openraft/src/engine/log_id_list.rs

+28
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,34 @@ impl<NID: NodeId> LogIdList<NID> {
8080
self.key_log_ids.push(new_log_id);
8181
}
8282

83+
/// Purge log ids upto the log with index `upto_index`, inclusive.
84+
#[allow(dead_code)]
85+
pub(crate) fn purge(&mut self, upto: &LogId<NID>) {
86+
// When installing snapshot it may need to purge across the `last_log_id`.
87+
if upto.index > self.key_log_ids[self.key_log_ids.len() - 1].index {
88+
assert!(upto > &self.key_log_ids[self.key_log_ids.len() - 1]);
89+
self.key_log_ids = vec![*upto];
90+
}
91+
92+
if upto.index < self.key_log_ids[0].index {
93+
return;
94+
}
95+
96+
let res = self.key_log_ids.binary_search_by(|log_id| log_id.index.cmp(&upto.index));
97+
98+
match res {
99+
Ok(i) => {
100+
if i > 0 {
101+
self.key_log_ids = self.key_log_ids.split_off(i)
102+
}
103+
}
104+
Err(i) => {
105+
self.key_log_ids = self.key_log_ids.split_off(i - 1);
106+
self.key_log_ids[0].index = upto.index;
107+
}
108+
}
109+
}
110+
83111
/// Get the log id at the specified index.
84112
///
85113
/// It will return `last_purged_log_id` if index is at the last purged index.

openraft/src/engine/log_id_list_test.rs

+70-15
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ use crate::LogId;
44

55
#[test]
66
fn test_log_id_list_extend_from_same_leader() -> anyhow::Result<()> {
7-
let log_id = |t, i| LogId::<u64> {
8-
leader_id: LeaderId { term: t, node_id: 1 },
9-
index: i,
10-
};
11-
127
let mut ids = LogIdList::<u64>::default();
138

149
// Extend one log id to an empty LogIdList: Just store it directly
@@ -55,11 +50,6 @@ fn test_log_id_list_extend_from_same_leader() -> anyhow::Result<()> {
5550

5651
#[test]
5752
fn test_log_id_list_append() -> anyhow::Result<()> {
58-
let log_id = |t, i| LogId::<u64> {
59-
leader_id: LeaderId { term: t, node_id: 1 },
60-
index: i,
61-
};
62-
6353
let mut ids = LogIdList::<u64>::default();
6454

6555
// Append log id one by one, check the internally constructed `key_log_id` as expected.
@@ -82,12 +72,71 @@ fn test_log_id_list_append() -> anyhow::Result<()> {
8272
}
8373

8474
#[test]
85-
fn test_log_id_list_get_log_id() -> anyhow::Result<()> {
86-
let log_id = |t, i| LogId::<u64> {
87-
leader_id: LeaderId { term: t, node_id: 1 },
88-
index: i,
89-
};
75+
fn test_log_id_list_purge() -> anyhow::Result<()> {
76+
// Append log id one by one, check the internally constructed `key_log_id` as expected.
77+
78+
let cases = vec![
79+
//
80+
(log_id(2, 1), vec![
81+
log_id(2, 2),
82+
log_id(3, 3),
83+
log_id(6, 6),
84+
log_id(9, 9),
85+
log_id(9, 11),
86+
]),
87+
(log_id(2, 2), vec![
88+
log_id(2, 2),
89+
log_id(3, 3),
90+
log_id(6, 6),
91+
log_id(9, 9),
92+
log_id(9, 11),
93+
]),
94+
(log_id(3, 3), vec![
95+
log_id(3, 3),
96+
log_id(6, 6),
97+
log_id(9, 9),
98+
log_id(9, 11),
99+
]),
100+
(log_id(3, 4), vec![
101+
log_id(3, 4),
102+
log_id(6, 6),
103+
log_id(9, 9),
104+
log_id(9, 11),
105+
]),
106+
(log_id(3, 5), vec![
107+
log_id(3, 5),
108+
log_id(6, 6),
109+
log_id(9, 9),
110+
log_id(9, 11),
111+
]),
112+
(log_id(6, 6), vec![log_id(6, 6), log_id(9, 9), log_id(9, 11)]),
113+
(log_id(6, 7), vec![log_id(6, 7), log_id(9, 9), log_id(9, 11)]),
114+
(log_id(6, 8), vec![log_id(6, 8), log_id(9, 9), log_id(9, 11)]),
115+
(log_id(9, 9), vec![log_id(9, 9), log_id(9, 11)]),
116+
(log_id(9, 10), vec![log_id(9, 10), log_id(9, 11)]),
117+
(log_id(9, 11), vec![log_id(9, 11)]),
118+
(log_id(9, 12), vec![log_id(9, 12)]),
119+
(log_id(10, 12), vec![log_id(10, 12)]),
120+
];
121+
122+
for (upto, want) in cases {
123+
let mut ids = LogIdList::<u64>::new(vec![
124+
log_id(2, 2), // force multi line
125+
log_id(3, 3),
126+
log_id(6, 6),
127+
log_id(9, 9),
128+
log_id(9, 11),
129+
]);
130+
131+
ids.purge(&upto);
132+
assert_eq!(want, ids.key_log_ids(), "purge upto: {}", upto);
133+
}
134+
135+
Ok(())
136+
}
90137

138+
#[test]
139+
fn test_log_id_list_get_log_id() -> anyhow::Result<()> {
91140
// Get log id from empty list always returns `None`.
92141

93142
let ids = LogIdList::<u64>::default();
@@ -122,3 +171,9 @@ fn test_log_id_list_get_log_id() -> anyhow::Result<()> {
122171

123172
Ok(())
124173
}
174+
fn log_id(term: u64, index: u64) -> LogId<u64> {
175+
LogId::<u64> {
176+
leader_id: LeaderId { term, node_id: 1 },
177+
index,
178+
}
179+
}

0 commit comments

Comments
 (0)