Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 4 additions & 177 deletions libbz2-rs-sys/src/blocksort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,182 +9,6 @@ use crate::{
};
use crate::{debug_log, debug_logln};

/// Fallback O(N log(N)^2) sorting algorithm, for repetitive blocks
#[inline]
fn fallbackSimpleSort(fmap: &mut [u32], eclass: &[u32], lo: i32, hi: i32) {
let mut j: i32;
let mut tmp: i32;
let mut ec_tmp: u32;

if lo == hi {
return;
}

if hi - lo > 3 {
for i in (lo..=hi - 4).rev() {
tmp = fmap[i as usize] as i32;
ec_tmp = eclass[tmp as usize];
j = i + 4;
while j <= hi && ec_tmp > eclass[fmap[j as usize] as usize] {
fmap[(j - 4) as usize] = fmap[j as usize];
j += 4;
}
fmap[(j - 4) as usize] = tmp as u32;
}
}

for i in (lo..=hi - 1).rev() {
tmp = fmap[i as usize] as i32;
ec_tmp = eclass[tmp as usize];
j = i + 1;
while j <= hi && ec_tmp > eclass[fmap[j as usize] as usize] {
fmap[(j - 1) as usize] = fmap[j as usize];
j += 1;
}
fmap[(j - 1) as usize] = tmp as u32;
}
}

const FALLBACK_QSORT_SMALL_THRESH: i32 = 10;
const FALLBACK_QSORT_STACK_SIZE: usize = 100;

fn fallbackQSort3(fmap: &mut [u32], eclass: &[u32], loSt: i32, hiSt: i32) {
let mut unLo: i32;
let mut unHi: i32;
let mut ltLo: i32;
let mut gtHi: i32;
let mut n: i32;
let mut m: i32;
let mut sp: usize;
let mut lo: i32;
let mut hi: i32;
let mut stackLo: [i32; FALLBACK_QSORT_STACK_SIZE] = [0; FALLBACK_QSORT_STACK_SIZE];
let mut stackHi: [i32; FALLBACK_QSORT_STACK_SIZE] = [0; FALLBACK_QSORT_STACK_SIZE];

macro_rules! fpush {
($lz:expr, $hz:expr) => {
stackLo[sp] = $lz;
stackHi[sp] = $hz;
sp += 1;
};
}

macro_rules! fvswap {
($zzp1:expr, $zzp2:expr, $zzn:expr) => {
let mut yyp1: i32 = $zzp1;
let mut yyp2: i32 = $zzp2;
let mut yyn: i32 = $zzn;

while (yyn > 0) {
fmap.swap(yyp1 as usize, yyp2 as usize);
yyp1 += 1;
yyp2 += 1;
yyn -= 1;
}
};
}

let mut r = 0u32;

sp = 0;
fpush!(loSt, hiSt);

while sp > 0 {
assert_h!(sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004);

// the `fpop` macro has one occurence, so it was inlined here
sp -= 1;
lo = stackLo[sp];
hi = stackHi[sp];

if hi - lo < FALLBACK_QSORT_SMALL_THRESH {
fallbackSimpleSort(fmap, eclass, lo, hi);
continue;
}

/* Random partitioning. Median of 3 sometimes fails to
avoid bad cases. Median of 9 seems to help but
looks rather expensive. This too seems to work but
is cheaper. Guidance for the magic constants
7621 and 32768 is taken from Sedgewick's algorithms
book, chapter 35.
*/
r = r.wrapping_mul(7621).wrapping_add(1).wrapping_rem(32768);
let index = match r.wrapping_rem(3) {
0 => fmap[lo as usize],
1 => fmap[((lo + hi) >> 1) as usize],
_ => fmap[hi as usize],
};
let med = eclass[index as usize];

ltLo = lo;
unLo = lo;

gtHi = hi;
unHi = hi;

loop {
while unLo <= unHi {
match eclass[fmap[unLo as usize] as usize].cmp(&med) {
Ordering::Greater => break,
Ordering::Equal => {
fmap.swap(unLo as usize, ltLo as usize);
ltLo += 1;
unLo += 1;
}
Ordering::Less => {
unLo += 1;
}
}
}

while unLo <= unHi {
match eclass[fmap[unHi as usize] as usize].cmp(&med) {
Ordering::Less => break,
Ordering::Equal => {
fmap.swap(unHi as usize, gtHi as usize);
gtHi -= 1;
unHi -= 1;
}
Ordering::Greater => {
unHi -= 1;
}
}
}

if unLo > unHi {
break;
}

fmap.swap(unLo as usize, unHi as usize);
unLo += 1;
unHi -= 1;
}

debug_assert_eq!(unHi, unLo - 1, "fallbackQSort3(2)");

if gtHi < ltLo {
continue;
}

n = Ord::min(ltLo - lo, unLo - ltLo);
fvswap!(lo, unLo - n, n);
m = Ord::min(hi - gtHi, gtHi - unHi);
fvswap!(unLo, hi - m + 1, m);

n = lo + unLo - ltLo - 1;
m = hi - (gtHi - unHi) + 1;

if n - lo > hi - m {
fpush!(lo, n);
fpush!(m, hi);
} else {
fpush!(m, hi);
fpush!(lo, n);
}
}
}

fn fallbackSort(
fmap: &mut [u32],
arr2: &mut Arr2,
Expand Down Expand Up @@ -339,7 +163,10 @@ fn fallbackSort(
/*-- now [l, r] bracket current bucket --*/
if r > l {
nNotDone += r - l + 1;
fallbackQSort3(fmap, arr2.eclass(), l, r);

if let Some(slice) = fmap.get_mut(l as usize..=r as usize) {
slice.sort_unstable_by_key(|v| arr2.eclass()[*v as usize]);
}

/*-- scan bucket and generate header bits-- */
cc = -1;
Expand Down
Loading