Skip to content

Commit

Permalink
checksum: add gxhash
Browse files Browse the repository at this point in the history
This commit required modifying the build context to allow for the AES
optimizations of GxHash. It should not prove to be an issue on the system we
use (x86-64 and maybe ARM64) which I've tested before this commit.
  • Loading branch information
Johannes Wünsche committed Apr 15, 2024
1 parent 57bd6be commit 9192b43
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 1 deletion.
2 changes: 2 additions & 0 deletions betree/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
rustflags = ["-C","target-cpu=native"]
1 change: 1 addition & 0 deletions betree/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ rand = { version = "0.8", features = ["std_rng"] }

pmdk = { path = "./pmdk", optional = true }
rustc-hash = "1.1.0"
gxhash = "3.1.1"

[dev-dependencies]
rand_xorshift = "0.3"
Expand Down
69 changes: 69 additions & 0 deletions betree/src/checksum/gxhash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/// Impl for Checksum for FxHashw.
use super::{Builder, Checksum, ChecksumError, State};
use crate::size::StaticSize;
use gxhash::GxHasher;
use serde::{Deserialize, Serialize};
use std::hash::Hasher;

/// A checksum created by `GxHash`.
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
pub struct GxHash(u64);

impl StaticSize for GxHash {
fn static_size() -> usize {
8
}
}

impl Checksum for GxHash {
type Builder = GxHashBuilder;

fn verify_buffer<I: IntoIterator<Item = T>, T: AsRef<[u8]>>(
&self,
data: I,
) -> Result<(), ChecksumError> {
let mut state = GxHashBuilder.build();
for x in data {
state.ingest(x.as_ref());
}
let other = state.finish();
if *self == other {
Ok(())
} else {
Err(ChecksumError)
}
}

fn builder() -> Self::Builder {
GxHashBuilder
}
}

/// The corresponding `Builder` for `GxHash`.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GxHashBuilder;

impl Builder<GxHash> for GxHashBuilder {
type State = GxHashState;

fn build(&self) -> Self::State {
// Due to security concerns the default `GxHasher` is randomized, which
// does not work for us, therefore, use pinned seed.
GxHashState(GxHasher::with_seed(0))
}
}

/// The internal state of `GxHash`.
pub struct GxHashState(GxHasher);

impl State for GxHashState {
type Checksum = GxHash;

fn ingest(&mut self, data: &[u8]) {
self.0.write(data);
}

fn finish(self) -> Self::Checksum {
GxHash(self.0.finish())
}
}
2 changes: 2 additions & 0 deletions betree/src/checksum/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ use serde::{de::DeserializeOwned, Serialize};
use std::{error::Error, fmt, iter::once};

mod fxhash;
mod gxhash;
mod xxhash;

pub use fxhash::{FxHash, FxHashBuilder};
pub use gxhash::{GxHash, GxHashBuilder};
pub use xxhash::{XxHash, XxHashBuilder};

/// A checksum to verify data integrity.
Expand Down
1 change: 1 addition & 0 deletions betree/src/checksum/xxhash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::size::StaticSize;
use serde::{Deserialize, Serialize};
use std::hash::Hasher;

/// A checksum created by `XxHash`.
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
pub struct XxHash(u64);

Expand Down
2 changes: 1 addition & 1 deletion betree/src/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::{
atomic_option::AtomicOption,
cache::ClockCache,
checksum::{FxHash, FxHashBuilder, XxHash, XxHashBuilder},
checksum::XxHash,
compression::CompressionConfiguration,
cow_bytes::SlicedCowBytes,
data_management::{
Expand Down

0 comments on commit 9192b43

Please sign in to comment.