Mirror von
https://github.com/Chaoscaot/schemsearch
synchronisiert 2024-11-19 10:20:08 +01:00
Some Unsafe Optimizations
Dieser Commit ist enthalten in:
Ursprung
dd3e3a3c78
Commit
971e453d46
@ -14,3 +14,6 @@ lto = true
|
|||||||
strip = true
|
strip = true
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
@ -108,7 +108,7 @@ fn main() {
|
|||||||
.long("threshold")
|
.long("threshold")
|
||||||
.action(ArgAction::Set)
|
.action(ArgAction::Set)
|
||||||
.default_value("0.9")
|
.default_value("0.9")
|
||||||
.value_parser(|s: &str| s.parse::<f64>().map_err(|e| e.to_string())),
|
.value_parser(|s: &str| s.parse::<f32>().map_err(|e| e.to_string())),
|
||||||
)
|
)
|
||||||
.about("Searches for a pattern in a schematic")
|
.about("Searches for a pattern in a schematic")
|
||||||
.bin_name("schemsearch");
|
.bin_name("schemsearch");
|
||||||
@ -152,7 +152,7 @@ fn main() {
|
|||||||
ignore_air: matches.get_flag("ignore-air"),
|
ignore_air: matches.get_flag("ignore-air"),
|
||||||
air_as_any: matches.get_flag("air-as-any"),
|
air_as_any: matches.get_flag("air-as-any"),
|
||||||
ignore_entities: matches.get_flag("ignore-entities"),
|
ignore_entities: matches.get_flag("ignore-entities"),
|
||||||
threshold: *matches.get_one::<f64>("threshold").expect("Couldn't get threshold"),
|
threshold: *matches.get_one::<f32>("threshold").expect("Couldn't get threshold"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let pattern = match Schematic::load(Path::new(matches.get_one::<String>("pattern").unwrap())) {
|
let pattern = match Schematic::load(Path::new(matches.get_one::<String>("pattern").unwrap())) {
|
||||||
|
@ -28,14 +28,14 @@ pub struct SearchBehavior {
|
|||||||
pub ignore_air: bool,
|
pub ignore_air: bool,
|
||||||
pub air_as_any: bool,
|
pub air_as_any: bool,
|
||||||
pub ignore_entities: bool,
|
pub ignore_entities: bool,
|
||||||
pub threshold: f64,
|
pub threshold: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn search(
|
pub fn search(
|
||||||
schem: Schematic,
|
schem: Schematic,
|
||||||
pattern_schem: &Schematic,
|
pattern_schem: &Schematic,
|
||||||
search_behavior: SearchBehavior,
|
search_behavior: SearchBehavior,
|
||||||
) -> Vec<(u16, u16, u16, f64)> {
|
) -> Vec<(u16, u16, u16, f32)> {
|
||||||
if schem.width < pattern_schem.width || schem.height < pattern_schem.height || schem.length < pattern_schem.length {
|
if schem.width < pattern_schem.width || schem.height < pattern_schem.height || schem.length < pattern_schem.length {
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
@ -46,9 +46,9 @@ pub fn search(
|
|||||||
|
|
||||||
let pattern_schem = match_palette(&schem, &pattern_schem, search_behavior.ignore_block_data);
|
let pattern_schem = match_palette(&schem, &pattern_schem, search_behavior.ignore_block_data);
|
||||||
|
|
||||||
let mut matches: Vec<(u16, u16, u16, f64)> = Vec::new();
|
let mut matches: Vec<(u16, u16, u16, f32)> = Vec::new();
|
||||||
|
|
||||||
let pattern_data = pattern_schem.block_data;
|
let pattern_data = pattern_schem.block_data.as_slice();
|
||||||
|
|
||||||
let schem_data = if search_behavior.ignore_block_data {
|
let schem_data = if search_behavior.ignore_block_data {
|
||||||
match_palette_adapt(&schem, &pattern_schem.palette, search_behavior.ignore_block_data)
|
match_palette_adapt(&schem, &pattern_schem.palette, search_behavior.ignore_block_data)
|
||||||
@ -56,28 +56,38 @@ pub fn search(
|
|||||||
schem.block_data
|
schem.block_data
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let schem_data = schem_data.as_slice();
|
||||||
|
|
||||||
let air_id = if search_behavior.ignore_air || search_behavior.air_as_any { pattern_schem.palette.get("minecraft:air").unwrap_or(&-1) } else { &-1};
|
let air_id = if search_behavior.ignore_air || search_behavior.air_as_any { pattern_schem.palette.get("minecraft:air").unwrap_or(&-1) } else { &-1};
|
||||||
|
|
||||||
let pattern_blocks = (pattern_schem.width * pattern_schem.height * pattern_schem.length) as f64;
|
let pattern_blocks = (pattern_schem.width * pattern_schem.height * pattern_schem.length) as f32;
|
||||||
|
|
||||||
for x in 0..=schem.width as usize - pattern_schem.width as usize {
|
let pattern_width = pattern_schem.width as usize;
|
||||||
for y in 0..=schem.height as usize - pattern_schem.height as usize {
|
let pattern_height = pattern_schem.height as usize;
|
||||||
for z in 0..=schem.length as usize - pattern_schem.length as usize {
|
let pattern_length = pattern_schem.length as usize;
|
||||||
|
|
||||||
|
let schem_width = schem.width as usize;
|
||||||
|
let schem_height = schem.height as usize;
|
||||||
|
let schem_length = schem.length as usize;
|
||||||
|
|
||||||
|
for y in 0..=schem_height - pattern_height {
|
||||||
|
for z in 0..=schem_length - pattern_length {
|
||||||
|
for x in 0..=schem_width - pattern_width {
|
||||||
let mut matching = 0;
|
let mut matching = 0;
|
||||||
for i in 0..pattern_schem.width as usize {
|
for j in 0..pattern_height {
|
||||||
for j in 0..pattern_schem.height as usize {
|
for k in 0..pattern_length {
|
||||||
for k in 0..pattern_schem.length as usize {
|
for i in 0..pattern_width {
|
||||||
let index = (x + i) + (z + k) * (schem.width as usize) + (y + j) * (schem.width as usize) * (schem.length as usize);
|
let index = (x + i) + schem_width * ((z + k) + (y + j) * schem_length);
|
||||||
let pattern_index = i + k * pattern_schem.width as usize + j * pattern_schem.width as usize * pattern_schem.length as usize;
|
let pattern_index = i + pattern_width * (k + j * pattern_length);
|
||||||
let data = schem_data.get(index as usize).expect("Index out of bounds");
|
let data = unsafe {schem_data.get_unchecked(index) };
|
||||||
let pattern_data = pattern_data.get(pattern_index as usize).expect("Index out of bounds");
|
let pattern_data = unsafe { pattern_data.get_unchecked(pattern_index) };
|
||||||
if *data == *pattern_data || (search_behavior.ignore_air && *data == *air_id) || (search_behavior.air_as_any && *pattern_data == *air_id) {
|
if *data == *pattern_data || (search_behavior.ignore_air && *data == *air_id) || (search_behavior.air_as_any && *pattern_data == *air_id) {
|
||||||
matching += 1;
|
matching += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let matching_percent = matching as f64 / pattern_blocks;
|
let matching_percent = matching as f32 / pattern_blocks;
|
||||||
if matching_percent >= search_behavior.threshold {
|
if matching_percent >= search_behavior.threshold {
|
||||||
matches.push((x as u16, y as u16, z as u16, matching_percent));
|
matches.push((x as u16, y as u16, z as u16, matching_percent));
|
||||||
}
|
}
|
||||||
@ -88,11 +98,12 @@ pub fn search(
|
|||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn normalize_data(data: &String, ignore_data: bool) -> String {
|
#[inline]
|
||||||
|
pub fn normalize_data(data: &str, ignore_data: bool) -> &str {
|
||||||
if ignore_data {
|
if ignore_data {
|
||||||
data.split('[').next().unwrap().to_string()
|
data.split('[').next().unwrap()
|
||||||
} else {
|
} else {
|
||||||
data.to_string()
|
data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,11 @@ use nbt::Map;
|
|||||||
use schemsearch_files::Schematic;
|
use schemsearch_files::Schematic;
|
||||||
use crate::normalize_data;
|
use crate::normalize_data;
|
||||||
|
|
||||||
fn create_reverse_palette(schem: &Schematic) -> Vec<String> {
|
fn create_reverse_palette(schem: &Schematic) -> Vec<&str> {
|
||||||
let mut reverse_palette = Vec::with_capacity(schem.palette_max as usize);
|
let mut reverse_palette = Vec::with_capacity(schem.palette_max as usize);
|
||||||
(0..schem.palette_max).for_each(|_| reverse_palette.push(String::new()));
|
(0..schem.palette_max).for_each(|_| reverse_palette.push(""));
|
||||||
for (key, value) in schem.palette.iter() {
|
for (key, value) in schem.palette.iter() {
|
||||||
reverse_palette[*value as usize] = key.clone();
|
reverse_palette[*value as usize] = key;
|
||||||
}
|
}
|
||||||
reverse_palette
|
reverse_palette
|
||||||
}
|
}
|
||||||
@ -68,9 +68,9 @@ pub fn match_palette_adapt(schem: &Schematic, matching_palette: &Map<String, i32
|
|||||||
let reverse_palette = create_reverse_palette(schem);
|
let reverse_palette = create_reverse_palette(schem);
|
||||||
|
|
||||||
for x in &schem.block_data {
|
for x in &schem.block_data {
|
||||||
let blockname = &reverse_palette[*x as usize];
|
let blockname = reverse_palette[*x as usize];
|
||||||
let blockname = if ignore_data { normalize_data(&blockname, ignore_data) } else { blockname.clone() };
|
let blockname = if ignore_data { normalize_data(blockname, ignore_data) } else { blockname };
|
||||||
let block_id = match matching_palette.get(&blockname) {
|
let block_id = match matching_palette.get(&*blockname) {
|
||||||
None => -1,
|
None => -1,
|
||||||
Some(x) => *x
|
Some(x) => *x
|
||||||
};
|
};
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren