fxfs/object_store/allocator/
strategy.rs1use crate::object_store::FxfsError;
20use anyhow::{Context, Error};
21use std::collections::{btree_map, BTreeMap, BTreeSet};
22use std::fmt::Debug;
23use std::ops::Range;
24
25#[derive(Debug, Default)]
27struct SizeBucket {
28 overflow: bool,
31 offsets: BTreeSet<u64>,
32}
33
34const DEFAULT_MAX_EXTENT_SIZE: u64 = 2 << 20;
39
40const NUM_MAX_SIZED_EXTENTS_TO_KEEP: u64 = 512;
43
44fn max_entries(len: u64) -> usize {
50 if len < DEFAULT_MAX_EXTENT_SIZE {
51 (4 << 20) / len as usize
54 } else {
55 NUM_MAX_SIZED_EXTENTS_TO_KEEP as usize
56 }
57}
58
59#[derive(Debug, Default)]
69pub struct BestFit {
70 ranges: BTreeMap<u64, SizeBucket>,
72 by_end: BTreeMap<u64, u64>,
74}
75
76impl BestFit {
77 pub fn allocate(&mut self, bytes: u64) -> Result<Range<u64>, FxfsError> {
86 let mut result = self.ranges.range_mut(bytes..).next();
87 if result.is_none() {
88 result = self.ranges.iter_mut().rev().next();
90 }
91 if let Some((&size, size_bucket)) = result {
92 if size_bucket.offsets.is_empty() && size_bucket.overflow {
93 return Err(FxfsError::NotFound);
94 }
95 debug_assert!(!size_bucket.offsets.is_empty());
96 let offset = size_bucket.offsets.pop_first().unwrap();
97 if size_bucket.offsets.is_empty() && !size_bucket.overflow {
98 self.ranges.remove(&size);
99 }
100 self.by_end.remove(&(offset + size));
101 if size > bytes {
102 self.free(offset + bytes..offset + size).expect("give extra back");
103 Ok(offset..offset + bytes)
104 } else {
105 Ok(offset..offset + size)
106 }
107 } else {
108 Err(FxfsError::NoSpace)
109 }
110 }
111
112 pub fn force_free(&mut self, range: Range<u64>) -> Result<bool, Error> {
115 let mut to_add = Vec::new();
116 let mut last = range.start;
117 for (&end, &offset) in self.by_end.range(range.start + 1..) {
118 if offset >= range.end {
119 break;
120 }
121 if offset > last {
122 to_add.push(last..offset);
123 }
124 last = end;
125 assert!(end > range.start);
126 }
127 if last < range.end {
128 to_add.push(last..range.end);
129 }
130 Ok(if to_add.is_empty() {
131 false
132 } else {
133 for range in to_add {
134 self.free(range)?;
135 }
136 true
137 })
138 }
139
140 pub fn remove(&mut self, range: Range<u64>) {
142 let mut to_add = Vec::new();
143 let mut to_remove = Vec::new();
144 for (&end, &offset) in self.by_end.range(range.start + 1..) {
145 if offset >= range.end {
146 break;
147 }
148 assert!(end > range.start);
149 to_remove.push(offset..end);
150 if offset < range.start {
151 to_add.push(offset..range.start);
152 }
153 if end > range.end {
154 to_add.push(range.end..end);
155 }
156 }
157 for range in to_remove {
158 self.remove_range(range);
159 }
160 for range in to_add {
161 self.free(range).unwrap();
162 }
163 }
164
165 fn remove_range(&mut self, range: Range<u64>) {
167 let btree_map::Entry::Occupied(mut size_bucket) =
168 self.ranges.entry(range.end - range.start)
169 else {
170 unreachable!()
171 };
172 size_bucket.get_mut().offsets.remove(&range.start);
173 if size_bucket.get().offsets.is_empty() && !size_bucket.get().overflow {
174 size_bucket.remove_entry();
175 }
176 assert_eq!(Some(range.start), self.by_end.remove(&range.end));
177 }
178
179 pub fn overflow_markers(&self) -> Vec<u64> {
181 self.ranges
182 .iter()
183 .filter_map(|(&size, size_bucket)| size_bucket.overflow.then_some(size))
184 .collect()
185 }
186
187 pub fn reset_overflow_markers(&mut self) {
191 let mut to_remove = Vec::new();
192 for (&size, size_bucket) in self.ranges.iter_mut() {
193 size_bucket.overflow = false;
194 if size_bucket.offsets.is_empty() {
195 to_remove.push(size);
196 }
197 }
198 for size in to_remove {
199 self.ranges.remove(&size);
200 }
201 }
202
203 fn insert_range(&mut self, range: Range<u64>) -> Result<(), Error> {
205 let len = range.end - range.start;
206 let entry = self.ranges.entry(len).or_default();
207 if !entry.offsets.insert(range.start) {
208 return Err(FxfsError::Inconsistent).context("Range already in 'ranges'.");
214 }
215 let other = self.by_end.insert(range.end, range.start);
216 if let Some(_other) = other {
217 return Err(FxfsError::Inconsistent)
221 .context("Range already in 'by_end'. Potential logic bug.");
222 };
223 if entry.offsets.len() > max_entries(len) {
224 let last = entry.offsets.pop_last().unwrap();
225 if self.by_end.remove(&(last + len)) != Some(last) {
226 return Err(FxfsError::Inconsistent)
227 .context("Expected range missing or invalid 'by_end'");
228 };
229 entry.overflow = true;
230 }
231 Ok(())
232 }
233
234 pub fn free(&mut self, mut range: Range<u64>) -> Result<(), Error> {
240 let mut iter = self.by_end.range(range.start..);
242 let mut next_item = iter.next();
243 if let Some((&end, &start)) = next_item {
244 if end == range.start {
245 self.remove_range(start..end);
246 range.start = start;
247 iter = self.by_end.range(range.start + 1..);
248 next_item = iter.next();
249 } else if start < range.end {
250 return Err(FxfsError::Inconsistent).context("overlapping free");
256 }
257 }
258 if let Some((&end, &start)) = next_item {
260 if start == range.end {
261 self.remove_range(start..end);
262 range.end = end;
263 }
264 }
265
266 while (range.end - range.start) >= DEFAULT_MAX_EXTENT_SIZE {
270 self.insert_range(range.end - DEFAULT_MAX_EXTENT_SIZE..range.end)
271 .context("adding max_extent_size fragment")?;
272 range.end -= DEFAULT_MAX_EXTENT_SIZE;
273 }
274 if range.start < range.end {
275 self.insert_range(range).context("adding final range")?;
276 }
277 Ok(())
278 }
279}
280
281#[cfg(test)]
282mod test {
283 use super::*;
284
285 #[test]
286 fn allocate() {
287 let mut bestfit = BestFit::default();
288 bestfit.free(0..0).unwrap(); bestfit.free(0..100).unwrap();
290 assert_eq!(bestfit.allocate(10), Ok(0..10));
291 assert_eq!(bestfit.allocate(10), Ok(10..20));
292 assert_eq!(bestfit.allocate(10), Ok(20..30));
293 assert_eq!(bestfit.allocate(10), Ok(30..40));
294 assert_eq!(bestfit.allocate(10), Ok(40..50));
295 bestfit.free(30..40).unwrap();
297 bestfit.free(10..20).unwrap();
298 assert_eq!(bestfit.allocate(10), Ok(10..20));
300 assert_eq!(bestfit.allocate(10), Ok(30..40));
301 assert_eq!(bestfit.allocate(10), Ok(50..60));
302 bestfit.free(0..50).unwrap();
304 assert_eq!(bestfit.allocate(100), Ok(0..50));
306 assert_eq!(bestfit.allocate(100), Ok(60..100));
308 assert_eq!(bestfit.allocate(100), Err(FxfsError::NoSpace));
310 bestfit.free(50..100).unwrap();
312 assert_eq!(bestfit.allocate(100), Ok(50..100));
313 }
314
315 #[test]
316 fn remove() {
317 let mut bestfit = BestFit::default();
318 bestfit.free(0..100).unwrap();
319 bestfit.remove(25..50);
320 assert_eq!(bestfit.allocate(30), Ok(50..80));
321 assert_eq!(bestfit.allocate(25), Ok(0..25));
322
323 let mut bestfit = BestFit::default();
325 bestfit.free(0..20).unwrap();
326 bestfit.free(30..50).unwrap();
327 bestfit.remove(10..40);
328 assert_eq!(bestfit.allocate(10), Ok(0..10));
329 assert_eq!(bestfit.allocate(10), Ok(40..50));
330 assert_eq!(bestfit.allocate(10), Err(FxfsError::NoSpace));
331
332 let mut bestfit = BestFit::default();
334 let end = DEFAULT_MAX_EXTENT_SIZE * (NUM_MAX_SIZED_EXTENTS_TO_KEEP + 1) + 10000;
335 bestfit.free(0..end).unwrap();
336 bestfit.remove(DEFAULT_MAX_EXTENT_SIZE * 3 + 10000..end);
339 bestfit.remove(0..DEFAULT_MAX_EXTENT_SIZE * 2);
341 assert_eq!(
343 bestfit.allocate(DEFAULT_MAX_EXTENT_SIZE),
344 Ok(DEFAULT_MAX_EXTENT_SIZE * 2 + 10000..DEFAULT_MAX_EXTENT_SIZE * 3 + 10000)
345 );
346 assert_eq!(
348 bestfit.allocate(10000),
349 Ok(DEFAULT_MAX_EXTENT_SIZE * 2..DEFAULT_MAX_EXTENT_SIZE * 2 + 10000)
350 );
351 assert_eq!(
353 bestfit.allocate(DEFAULT_MAX_EXTENT_SIZE),
354 Err(FxfsError::NotFound) );
356 bestfit.reset_overflow_markers();
358 assert_eq!(bestfit.allocate(DEFAULT_MAX_EXTENT_SIZE), Err(FxfsError::NoSpace));
359 }
360
361 #[test]
362 fn coalescing_free() {
363 let mut bestfit = BestFit::default();
364 bestfit.free(0..10).unwrap();
366 bestfit.free(20..32).unwrap();
367 bestfit.free(10..20).unwrap();
369 bestfit.remove(0..32);
372 assert_eq!(bestfit.allocate(32), Err(FxfsError::NoSpace));
373 }
374
375 #[test]
376 fn max_range() {
377 let mut bestfit = BestFit::default();
378 bestfit.free(10..10 + 10 * DEFAULT_MAX_EXTENT_SIZE).unwrap();
379
380 assert_eq!(
382 bestfit.allocate(2 * DEFAULT_MAX_EXTENT_SIZE),
383 Ok(10..10 + DEFAULT_MAX_EXTENT_SIZE)
384 );
385
386 bestfit.free(10..10 + DEFAULT_MAX_EXTENT_SIZE).unwrap();
388 assert_eq!(bestfit.allocate(10), Ok(10..20));
389 assert_eq!(bestfit.allocate(10), Ok(20..30));
390 assert_eq!(
391 bestfit.allocate(DEFAULT_MAX_EXTENT_SIZE - 20),
392 Ok(30..10 + DEFAULT_MAX_EXTENT_SIZE)
393 );
394 }
395
396 #[test]
397 fn fragmenting_free() {
398 let mut bestfit = BestFit::default();
400 bestfit.free(0..100).unwrap();
401 assert_eq!(bestfit.allocate(30), Ok(0..30));
402 assert!(bestfit.free(20..30).is_ok());
403 assert_eq!(bestfit.allocate(10), Ok(20..30));
404 assert!(bestfit.free(0..30).is_ok());
405 assert!(bestfit.free(0..30).is_err());
406
407 let mut bestfit = BestFit::default();
409 bestfit.free(10..20).unwrap();
410 bestfit.free(30..40).unwrap();
411 bestfit.free(0..10).unwrap(); bestfit.free(40..50).unwrap(); bestfit.free(20..30).unwrap(); let mut bestfit = BestFit::default();
417 bestfit.free(10..20).unwrap();
418 assert!(bestfit.free(9..11).is_err());
419 assert!(bestfit.free(19..21).is_err());
420 assert!(bestfit.free(11..29).is_err());
421 assert!(bestfit.free(10..20).is_err());
422 assert!(bestfit.free(9..10).is_ok());
423 assert!(bestfit.free(20..21).is_ok());
424 }
425
426 #[test]
427 fn force_free() {
428 let mut bestfit = BestFit::default();
429 bestfit.free(0..100).unwrap();
430 assert_eq!(bestfit.force_free(0..100).unwrap(), false);
431 assert_eq!(bestfit.force_free(10..100).unwrap(), false);
432 assert_eq!(bestfit.force_free(0..90).unwrap(), false);
433 assert_eq!(bestfit.force_free(10..90).unwrap(), false);
434
435 let mut bestfit = BestFit::default();
436 bestfit.free(0..40).unwrap();
437 bestfit.free(60..100).unwrap();
438 assert_eq!(bestfit.force_free(10..90).unwrap(), true);
439 assert_eq!(bestfit.allocate(100), Ok(0..100));
440
441 let mut bestfit = BestFit::default();
442 bestfit.free(0..40).unwrap();
443 bestfit.free(60..100).unwrap();
444 assert_eq!(bestfit.force_free(10..100).unwrap(), true);
445 assert_eq!(bestfit.allocate(100), Ok(0..100));
446
447 let mut bestfit = BestFit::default();
448 bestfit.free(10..40).unwrap();
449 bestfit.free(60..100).unwrap();
450 assert_eq!(bestfit.force_free(0..110).unwrap(), true);
451 assert_eq!(bestfit.allocate(110), Ok(0..110));
452
453 let mut bestfit = BestFit::default();
454 bestfit.free(10..40).unwrap();
455 bestfit.free(60..100).unwrap();
456 assert_eq!(bestfit.force_free(10..110).unwrap(), true);
457 assert_eq!(bestfit.allocate(100), Ok(10..110));
458
459 let mut bestfit = BestFit::default();
460 bestfit.free(10..40).unwrap();
461 bestfit.free(60..100).unwrap();
462 assert_eq!(bestfit.force_free(0..100).unwrap(), true);
463 assert_eq!(bestfit.allocate(100), Ok(0..100));
464
465 let mut bestfit = BestFit::default();
466 assert_eq!(bestfit.force_free(0..100).unwrap(), true);
467 assert_eq!(bestfit.allocate(100), Ok(0..100));
468 }
469
470 #[test]
471 fn test_overflow_changes() {
472 let mut bestfit = BestFit::default();
475 let mut ofs: u64 = 0;
476 for i in 0..max_entries(256 << 10) as u64 {
478 assert!(bestfit.force_free(i * 2 * (256 << 10)..(i * 2 + 1) * (256 << 10)).unwrap());
479 }
480 ofs += (256 << 10) * max_entries(256 << 10) as u64 * 3;
481
482 for i in 0..max_entries(768 << 10) as u64 + 1 {
484 assert!(bestfit
485 .force_free(ofs + i * 2 * (768 << 10)..ofs + (i * 2 + 1) * (768 << 10))
486 .unwrap());
487 }
488 ofs += (768 << 10) * (max_entries(768 << 10) + 1) as u64 * 3;
489
490 for i in 0..max_entries(512 << 10) as u64 + 1 {
492 assert!(bestfit
493 .force_free(ofs + i * 2 * (512 << 10)..ofs + (i * 2 + 1) * (512 << 10))
494 .unwrap());
495 }
496 ofs += (512 << 10) * max_entries(512 << 10) as u64 * 2 + (512 << 10);
499
500 assert_eq!(bestfit.overflow_markers(), vec![524288, 786432]);
501
502 assert!(bestfit.force_free(ofs..ofs + (256 << 10)).unwrap());
504 assert_eq!(bestfit.overflow_markers(), vec![262144, 524288, 786432]);
507 }
508}