Skip to content

Commit

Permalink
Merge pull request #28 from Pr0methean/hash-object-pool
Browse files Browse the repository at this point in the history
Use an object pool for ZopfliHash instances
  • Loading branch information
kornelski committed Mar 18, 2024
2 parents 99bf167 + 6645bdc commit 92a40f2
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 6 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ crc32fast = { version = "1.4.0", default-features = false, optional = true }
simd-adler32 = { version = "0.3.7", default-features = false, optional = true }
typed-arena = { version = "2.0.2", default-features = false }
log = "0.4.21"
lockfree-object-pool = "0.1.5"
once_cell = "1.19.0"

[dev-dependencies]
proptest = "1.4.0"
Expand Down
6 changes: 6 additions & 0 deletions src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ use alloc::{
};
use core::ptr::{addr_of, addr_of_mut, NonNull};

use lockfree_object_pool::LinearObjectPool;
use once_cell::sync::Lazy;

use crate::util::{ZOPFLI_MIN_MATCH, ZOPFLI_WINDOW_MASK, ZOPFLI_WINDOW_SIZE};

const HASH_SHIFT: i32 = 5;
Expand Down Expand Up @@ -176,3 +179,6 @@ impl ZopfliHash {
}
}
}

pub static HASH_POOL: Lazy<LinearObjectPool<Box<ZopfliHash>>> =
Lazy::new(|| LinearObjectPool::new(ZopfliHash::new, |boxed| boxed.reset()));
8 changes: 8 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ use std::io::{Error, Write};
#[cfg(any(doc, not(feature = "std")))]
pub use io::{Error, ErrorKind, Write};

use crate::hash::HASH_POOL;

/// Options for the Zopfli compression algorithm.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(all(test, feature = "std"), derive(proptest_derive::Arbitrary))]
Expand Down Expand Up @@ -169,6 +171,12 @@ pub fn compress<R: std::io::Read, W: Write>(
}
}

/// Populates object pools for expensive objects that Zopfli uses. Call this on a background thread
/// when you know ahead of time that compression will be needed.
pub fn prewarm_object_pools() {
HASH_POOL.pull();
}

#[cfg(all(test, feature = "std"))]
mod test {
use std::io;
Expand Down
8 changes: 5 additions & 3 deletions src/lz77.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::cmp;

use crate::{
cache::Cache,
hash::{Which, ZopfliHash},
hash::{Which, ZopfliHash, HASH_POOL},
symbols::{get_dist_symbol, get_length_symbol},
util::{
boxed_array, ZOPFLI_MAX_CHAIN_HITS, ZOPFLI_MAX_MATCH, ZOPFLI_MIN_MATCH, ZOPFLI_NUM_D,
Expand Down Expand Up @@ -139,7 +139,8 @@ impl Lz77Store {
return;
}
let windowstart = instart.saturating_sub(ZOPFLI_WINDOW_SIZE);
let mut h = ZopfliHash::new();
let hash_pool = &*HASH_POOL;
let mut h = hash_pool.pull();

let arr = &in_data[..inend];
h.warmup(arr, windowstart, inend);
Expand Down Expand Up @@ -239,7 +240,8 @@ impl Lz77Store {
return;
}

let mut h = ZopfliHash::new();
let hash_pool = &*HASH_POOL;
let mut h = hash_pool.pull();

let arr = &in_data[..inend];
h.warmup(arr, windowstart, inend);
Expand Down
8 changes: 5 additions & 3 deletions src/squeeze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use log::{debug, trace};
use crate::{
cache::Cache,
deflate::{calculate_block_size, BlockType},
hash::ZopfliHash,
hash::{ZopfliHash, HASH_POOL},
lz77::{find_longest_match, LitLen, Lz77Store},
symbols::{get_dist_extra_bits, get_dist_symbol, get_length_extra_bits, get_length_symbol},
util::{ZOPFLI_MAX_MATCH, ZOPFLI_NUM_D, ZOPFLI_NUM_LL, ZOPFLI_WINDOW_MASK, ZOPFLI_WINDOW_SIZE},
Expand Down Expand Up @@ -421,7 +421,8 @@ pub fn lz77_optimal_fixed<C: Cache>(
inend: usize,
store: &mut Lz77Store,
) {
let mut h = ZopfliHash::new();
let hash_pool = &*HASH_POOL;
let mut h = hash_pool.pull();
let mut costs = Vec::with_capacity(inend - instart);
lz77_optimal_run(
lmc,
Expand Down Expand Up @@ -455,7 +456,8 @@ pub fn lz77_optimal<C: Cache>(
let mut stats = SymbolStats::default();
stats.get_statistics(&currentstore);

let mut h = ZopfliHash::new();
let hash_pool = &*HASH_POOL;
let mut h = hash_pool.pull();
let mut costs = Vec::with_capacity(inend - instart + 1);

let mut beststats = SymbolStats::default();
Expand Down

0 comments on commit 92a40f2

Please sign in to comment.