|
|
@ -1,6 +1,10 @@ |
|
|
|
use std::{collections::BTreeMap, ops::Bound}; |
|
|
|
use std::{collections::BTreeMap, ops::Bound}; |
|
|
|
|
|
|
|
|
|
|
|
pub struct RangedNumberAllocator { |
|
|
|
pub struct RangedNumberAllocator { |
|
|
|
|
|
|
|
// Keys are range starts, values are range ends (inclusive).
|
|
|
|
|
|
|
|
// The following invariants always hold:
|
|
|
|
|
|
|
|
// 1. key <= value;
|
|
|
|
|
|
|
|
// 2. if key1 < key2, then key1 < value1+1 < key2.
|
|
|
|
pub tree: BTreeMap<u32, u32>, |
|
|
|
pub tree: BTreeMap<u32, u32>, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -56,6 +60,7 @@ impl RangedNumberAllocator { |
|
|
|
// There is another range; eliminated scenario 2, left with 3-4
|
|
|
|
// There is another range; eliminated scenario 2, left with 3-4
|
|
|
|
if next_range_start == range_end + 2 { |
|
|
|
if next_range_start == range_end + 2 { |
|
|
|
// Scenario 3
|
|
|
|
// Scenario 3
|
|
|
|
|
|
|
|
// Update current range end, and remove next range
|
|
|
|
*cursor.value_mut().unwrap() = next_range_end; |
|
|
|
*cursor.value_mut().unwrap() = next_range_end; |
|
|
|
cursor.move_next(); |
|
|
|
cursor.move_next(); |
|
|
|
cursor.remove_current_and_move_back().unwrap(); |
|
|
|
cursor.remove_current_and_move_back().unwrap(); |
|
|
@ -72,6 +77,7 @@ impl RangedNumberAllocator { |
|
|
|
} |
|
|
|
} |
|
|
|
} else if range_start == 2 { |
|
|
|
} else if range_start == 2 { |
|
|
|
// Scenario 5
|
|
|
|
// Scenario 5
|
|
|
|
|
|
|
|
// Replace current range with the one starting at 1
|
|
|
|
cursor.insert_before(1, range_end); |
|
|
|
cursor.insert_before(1, range_end); |
|
|
|
cursor.remove_current().unwrap(); |
|
|
|
cursor.remove_current().unwrap(); |
|
|
|
return 1; |
|
|
|
return 1; |
|
|
@ -81,6 +87,7 @@ impl RangedNumberAllocator { |
|
|
|
return 1; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
// Scenario 1
|
|
|
|
cursor.insert_after(1, 1); |
|
|
|
cursor.insert_after(1, 1); |
|
|
|
return 1; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|