parse: handle many curvepoints efficiently

This commit is contained in:
MaxOhn
2021-02-04 16:27:07 +01:00
parent f429509c75
commit 09e88c2872
3 changed files with 32 additions and 6 deletions
+3
View File
@@ -1,5 +1,8 @@
# Upcoming
- parse:
- Efficiently handle huge amounts of curvepoints
- osu:
- Fixed panic on unwrapping unavailable hit results
- Fixed occasional underflow when calculating pp with passed_objects
+6 -6
View File
@@ -280,7 +280,7 @@ mod tests {
#[test]
#[ignore]
fn no_leniency_single() {
let file = match File::open("./maps/1791963.osu") {
let file = match File::open("./maps/2573164.osu") {
Ok(file) => file,
Err(why) => panic!("Could not open file: {}", why),
};
@@ -291,11 +291,11 @@ mod tests {
};
let result = OsuPP::new(&map)
.n300(1206)
.n100(15)
.n50(0)
.combo(1643)
.mods(24)
.mods(0)
// .n300(1206)
// .n100(15)
// .n50(0)
// .combo(1643)
.calculate();
println!("Stars: {}", result.stars());
+23
View File
@@ -115,6 +115,12 @@ pub struct Beatmap {
pub(crate) const OSU_FILE_HEADER: &str = "osu file format v";
#[cfg(any(
feature = "fruits",
all(feature = "osu", not(feature = "no_sliders_no_leniency"))
))]
const CURVE_POINT_THRESHOLD: usize = 256;
impl Beatmap {
const CIRCLE_FLAG: u8 = 1 << 0;
const SLIDER_FLAG: u8 = 1 << 1;
@@ -476,6 +482,23 @@ impl Beatmap {
}
}
// Reduce amount of curvepoints but keep the elements evenly spaced.
// Necessary to handle maps like XNOR (2573164) that have
// tens of thousands of curvepoints more efficiently.
if curve_points.len() > CURVE_POINT_THRESHOLD {
while curve_points.len() > CURVE_POINT_THRESHOLD {
let last = curve_points[curve_points.len() - 1];
let last_idx = (curve_points.len() - 1) / 2;
for i in 1..=last_idx {
curve_points.swap(i, 2 * i);
}
curve_points[last_idx] = last;
curve_points.truncate(last_idx + 1);
}
}
if curve_points.is_empty() {
HitObjectKind::Circle
} else {