History

feat: add `State::prefixed_range()` to obtain a range of entries matching a prefix.

This makes it easier to make changes to entries of a certain prefix.

Sebastian Thiel committed 3 years ago

Commit cfbfa431 parent 8b689c22 files · +14 −3Browse files

Unified · Split

2 files
  1. gix-index/src/access/mod.rs +12 −3
  2. gix-index/tests/index/access.rs +2 −0
gix-index/src/access/mod.rs+12−3
@@ -184,9 +184,18 @@ impl State { · 183 unmodified lines
184 }184 }
185 185
186 /// Return the slice of entries which all share the same `prefix`, or `None` if there isn't a single such entry.186 /// Return the slice of entries which all share the same `prefix`, or `None` if there isn't a single such entry.
187 ///
188 /// If `prefix` is empty, all entries are returned.
187 pub fn prefixed_entries(&self, prefix: &BStr) -> Option<&[Entry]> {189 pub fn prefixed_entries(&self, prefix: &BStr) -> Option<&[Entry]> {
190 self.prefixed_entries_range(prefix).map(|range| &self.entries[range])
191 }
192
193 /// Return the range of entries which all share the same `prefix`, or `None` if there isn't a single such entry.
194 ///
195 /// If `prefix` is empty, the range will include all entries.
196 pub fn prefixed_entries_range(&self, prefix: &BStr) -> Option<Range<usize>> {
188 if prefix.is_empty() {197 if prefix.is_empty() {
189 return Some(self.entries());198 return Some(0..self.entries.len());
190 }199 }
191 let prefix_len = prefix.len();200 let prefix_len = prefix.len();
192 let mut low = self201 let mut low = self
@@ -195,7 +204,7 @@ impl State { · 2 unmodified lines
195 let mut high = low204 let mut high = low
196 + self.entries[low..].partition_point(|e| e.path(self).get(..prefix_len).map_or(false, |p| p <= prefix));205 + self.entries[low..].partition_point(|e| e.path(self).get(..prefix_len).map_or(false, |p| p <= prefix));
197 206
198 let low_entry = &self.entries[low];207 let low_entry = &self.entries.get(low)?;
199 if low_entry.stage() != 0 {208 if low_entry.stage() != 0 {
200 low = self209 low = self
201 .walk_entry_stages(low_entry.path(self), low, Ordering::Less)210 .walk_entry_stages(low_entry.path(self), low, Ordering::Less)
@@ -208,7 +217,7 @@ impl State { · 6 unmodified lines
208 .unwrap_or(high);217 .unwrap_or(high);
209 }218 }
210 }219 }
211 (low != high).then_some(low..high).map(|range| &self.entries[range])220 (low != high).then_some(low..high)
212 }221 }
213 222
214 /// Return the entry at `idx` or _panic_ if the index is out of bounds.223 /// Return the entry at `idx` or _panic_ if the index is out of bounds.
gix-index/tests/index/access.rs+2−0
@@ -50,6 +50,8 @@ fn prefixed_entries_with_multi_stage_file() { · 49 unmodified lines
50 file.entries(),50 file.entries(),
51 "empty prefix matches all"51 "empty prefix matches all"
52 );52 );
53 assert_eq!(file.prefixed_entries_range("".into()), Some(0..3));
54 assert_eq!(file.prefixed_entries_range("foo".into()), None);
53}55}
54 56
55#[test]57#[test]