parse: handle many curvepoints efficiently
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user