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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
//! Tree search result structure.
//!
//!
//! Returned by tree search operations to indicate the result of a search
//! and the location where a key was found (or should be inserted).
/// Result of a tree search operation.
///
/// Contains information about whether an exact parent match was found,
/// the index within that parent, and whether the child is resident in memory.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SearchResult {
/// True if an exact match for the parent was found.
pub exact_parent_found: bool,
/// Index within the parent where the key was found (or should be inserted).
///
/// This is the slot index in the parent IN/BIN. For insertions, this is
/// where the new entry should go. For exact matches, this is where the
/// matching entry is located.
pub index: i32,
/// True if the child node is not currently resident in memory.
///
/// When true, the child needs to be fetched from disk before access.
/// The LSN in the parent's slot indicates where to read the child from.
pub child_not_resident: bool,
}
impl SearchResult {
/// Creates a new SearchResult with all fields set to default values.
///
/// Default values:
/// - `exact_parent_found`: false
/// - `index`: -1
/// - `child_not_resident`: false
pub fn new() -> Self {
SearchResult {
exact_parent_found: false,
index: -1,
child_not_resident: false,
}
}
/// Creates a SearchResult with specific values.
///
/// # Arguments
/// * `exact_parent_found` - Whether an exact parent match was found
/// * `index` - The slot index in the parent
/// * `child_not_resident` - Whether the child needs to be fetched from disk
pub fn with_values(
exact_parent_found: bool,
index: i32,
child_not_resident: bool,
) -> Self {
SearchResult { exact_parent_found, index, child_not_resident }
}
/// Resets all fields to their default values.
///
/// This allows reusing a SearchResult instance across multiple searches.
pub fn reset(&mut self) {
self.exact_parent_found = false;
self.index = -1;
self.child_not_resident = false;
}
/// Returns true if this search result indicates a successful exact match.
///
/// An exact match means the parent was found and contains the key at the
/// specified index.
#[inline]
pub fn is_exact_match(&self) -> bool {
self.exact_parent_found && self.index >= 0
}
/// Returns true if the index is valid (>= 0).
#[inline]
pub fn has_valid_index(&self) -> bool {
self.index >= 0
}
}
impl Default for SearchResult {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let result = SearchResult::new();
assert!(!result.exact_parent_found);
assert_eq!(result.index, -1);
assert!(!result.child_not_resident);
}
#[test]
fn test_default() {
let result = SearchResult::default();
assert!(!result.exact_parent_found);
assert_eq!(result.index, -1);
assert!(!result.child_not_resident);
}
#[test]
fn test_with_values() {
let result = SearchResult::with_values(true, 5, true);
assert!(result.exact_parent_found);
assert_eq!(result.index, 5);
assert!(result.child_not_resident);
}
#[test]
fn test_reset() {
let mut result = SearchResult::with_values(true, 10, true);
result.reset();
assert!(!result.exact_parent_found);
assert_eq!(result.index, -1);
assert!(!result.child_not_resident);
}
#[test]
fn test_is_exact_match() {
let mut result = SearchResult::new();
assert!(!result.is_exact_match());
result.exact_parent_found = true;
result.index = 5;
assert!(result.is_exact_match());
result.exact_parent_found = false;
assert!(!result.is_exact_match());
result.exact_parent_found = true;
result.index = -1;
assert!(!result.is_exact_match());
}
#[test]
fn test_has_valid_index() {
let mut result = SearchResult::new();
assert!(!result.has_valid_index());
result.index = 0;
assert!(result.has_valid_index());
result.index = 100;
assert!(result.has_valid_index());
result.index = -1;
assert!(!result.has_valid_index());
result.index = -5;
assert!(!result.has_valid_index());
}
#[test]
fn test_clone() {
let result1 = SearchResult::with_values(true, 42, true);
let result2 = result1;
assert_eq!(result1, result2);
assert!(result2.exact_parent_found);
assert_eq!(result2.index, 42);
assert!(result2.child_not_resident);
}
#[test]
fn test_equality() {
let result1 = SearchResult::with_values(true, 5, false);
let result2 = SearchResult::with_values(true, 5, false);
let result3 = SearchResult::with_values(false, 5, false);
assert_eq!(result1, result2);
assert_ne!(result1, result3);
}
}