Skip to content

Commit 115d4a9

Browse files
author
Your Name
committed
Improve performance by indexing addresses
1 parent 6ae40a5 commit 115d4a9

File tree

6 files changed

+35
-24
lines changed

6 files changed

+35
-24
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rbase"
3-
version = "0.1.3"
3+
version = "0.1.4"
44
edition = "2021"
55
repository = "https://github.com/WorksButNotTested/rbase.git"
66
authors = [ "WorksButNotTested" ]

data/Image-arm32le.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
MD5SUM: bf520953defc78434726f4794376b8e5
2+
BASE: 0xc0208000

data/Image-arm64be.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
MD5SUM: 5f895efe5fe77cebb790690b915370e0
2+
BASE: 0xffffffc000080000

src/addresses.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use {
2-
crate::progress::Progress,
2+
crate::{progress::Progress, PAGE_OFFSET_MASK},
33
dashmap::DashMap,
44
indicatif::ParallelProgressIterator,
55
rayon::iter::{IntoParallelRefIterator, ParallelIterator},
6-
std::{hash::Hash, mem::size_of, num::TryFromIntError},
6+
std::{hash::Hash, mem::size_of, num::TryFromIntError, ops::BitAnd},
77
};
88

99
pub struct Addresses<T> {
10-
addresses: Vec<T>,
10+
addresses: DashMap<T, Vec<T>>,
1111
}
1212

1313
impl<
@@ -18,6 +18,7 @@ impl<
1818
+ PartialEq
1919
+ Eq
2020
+ Hash
21+
+ BitAnd<Output = T>
2122
+ TryFrom<usize, Error = TryFromIntError>,
2223
> Addresses<T>
2324
{
@@ -39,31 +40,35 @@ impl<
3940
map
4041
}
4142

42-
fn get_unique_addresses(frequencies: DashMap<T, usize>) -> Vec<T> {
43+
fn get_unique_addresses_by_page_offset(frequencies: DashMap<T, usize>) -> DashMap<T, Vec<T>> {
4344
let pb = Progress::get("Finding unique addresses", frequencies.len());
45+
let map = DashMap::<T, Vec<T>>::new();
4446
frequencies
4547
.par_iter()
4648
.progress_with(pb)
47-
.filter_map(|r| {
48-
let (&k, &v) = r.pair();
49-
if v == 1 {
50-
Some(k)
49+
.filter(|r| *r.value() != 1)
50+
.for_each(|r| {
51+
let &k = r.key();
52+
let offset = k & T::try_from(PAGE_OFFSET_MASK).unwrap();
53+
if let Some(mut v) = map.get_mut(&offset) {
54+
v.push(k);
5155
} else {
52-
None
56+
map.insert(k, vec![k]);
5357
}
54-
})
55-
.collect()
58+
});
59+
map
5660
}
5761

5862
pub fn new<F: Fn(&[u8]) -> T + Sync + Send + Copy>(bytes: &[u8], convert: F) -> Self {
5963
let frequencies = Self::get_address_frequencies(bytes, convert);
6064
println!("Found: {:?} addresses", frequencies.len());
61-
let unique = Self::get_unique_addresses(frequencies);
62-
println!("Found: {:?} unique addresses", unique.len());
63-
Self { addresses: unique }
65+
66+
let addresses = Self::get_unique_addresses_by_page_offset(frequencies);
67+
println!("Found: {:?} unique addresses", addresses.len());
68+
Self { addresses }
6469
}
6570

66-
pub fn get_addresses(&self) -> &Vec<T> {
71+
pub fn get_addresses(&self) -> &DashMap<T, Vec<T>> {
6772
return &self.addresses;
6873
}
6974
}

src/base.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use {
2-
crate::{progress::Progress, Addresses, Strings, PAGE_OFFSET_MASK},
2+
crate::{progress::Progress, Addresses, Strings},
33
dashmap::DashMap,
44
indicatif::ParallelProgressIterator,
55
rayon::iter::{IntoParallelRefIterator, ParallelIterator},
@@ -34,13 +34,15 @@ impl<
3434
let list = addresses.get_addresses();
3535
let pb = Progress::get("Collecting candidate base addresses", list.len());
3636
let map = DashMap::<T, usize>::new();
37-
list.par_iter().progress_with(pb).for_each(|&ptr| {
38-
let offset = ptr & T::try_from(PAGE_OFFSET_MASK).unwrap();
39-
if let Some(strings) = strings.get().get(&offset) {
37+
list.par_iter().progress_with(pb).for_each(|r| {
38+
let (offset, addresses) = r.pair();
39+
if let Some(strings) = strings.get().get(offset) {
4040
for &s in strings.deref() {
41-
if ptr > s {
42-
let base = ptr - s;
43-
*map.entry(base).or_insert(0) += 1;
41+
for &a in addresses.deref() {
42+
if a > s {
43+
let base = a - s;
44+
*map.entry(base).or_insert(0) += 1;
45+
}
4446
}
4547
}
4648
}

0 commit comments

Comments
 (0)