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
mod half;
mod keys;
mod size;
mod table;
use kvproto::metapb::Region;
use kvproto::pdpb::CheckPolicy;
use tikv_util::box_try;
use super::config::Config;
use super::error::Result;
use super::{KeyEntry, ObserverContext, SplitChecker};
pub use self::half::{get_region_approximate_middle, HalfCheckObserver};
pub use self::keys::{get_region_approximate_keys, KeysCheckObserver};
pub use self::size::{get_region_approximate_size, SizeCheckObserver};
pub use self::table::TableCheckObserver;
pub struct Host<'a, E> {
checkers: Vec<Box<dyn SplitChecker<E>>>,
auto_split: bool,
cfg: &'a Config,
}
impl<'a, E> Host<'a, E> {
pub fn new(auto_split: bool, cfg: &'a Config) -> Host<'a, E> {
Host {
auto_split,
checkers: vec![],
cfg,
}
}
#[inline]
pub fn auto_split(&self) -> bool {
self.auto_split
}
#[inline]
pub fn skip(&self) -> bool {
self.checkers.is_empty()
}
pub fn policy(&self) -> CheckPolicy {
for checker in &self.checkers {
if checker.policy() == CheckPolicy::Approximate {
return CheckPolicy::Approximate;
}
}
CheckPolicy::Scan
}
pub fn on_kv(&mut self, region: &Region, entry: &KeyEntry) -> bool {
let mut ob_ctx = ObserverContext::new(region);
for checker in &mut self.checkers {
if checker.on_kv(&mut ob_ctx, entry) {
return true;
}
}
false
}
pub fn split_keys(&mut self) -> Vec<Vec<u8>> {
for checker in &mut self.checkers {
let keys = checker.split_keys();
if !keys.is_empty() {
return keys;
}
}
vec![]
}
pub fn approximate_split_keys(&mut self, region: &Region, engine: &E) -> Result<Vec<Vec<u8>>> {
for checker in &mut self.checkers {
let keys = box_try!(checker.approximate_split_keys(region, engine));
if !keys.is_empty() {
return Ok(keys);
}
}
Ok(vec![])
}
#[inline]
pub fn add_checker(&mut self, checker: Box<dyn SplitChecker<E>>) {
self.checkers.push(checker);
}
}