Skip to content

Commit 89101b1

Browse files
committed
fingerprint
1 parent 06ce69e commit 89101b1

File tree

8 files changed

+67
-53
lines changed

8 files changed

+67
-53
lines changed

lib/bencher_context/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ license-file.workspace = true
77
publish = false
88

99
[features]
10-
client = ["dep:gix", "dep:uuid", "dep:windows"]
11-
server = ["dep:uuid", "bencher_valid/server", "uuid/v4"]
10+
client = ["dep:gix", "dep:uuid", "dep:windows", "bencher_valid/client"]
11+
server = ["bencher_valid/server"]
1212
schema = ["dep:schemars"]
1313

1414
[dependencies]
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use bencher_valid::BASE_36;
2+
use uuid::Uuid;
3+
4+
pub fn encode_uuid(uuid: Uuid) -> String {
5+
const ENCODED_LEN: usize = 13;
6+
7+
let base = BASE_36.len() as u64;
8+
let chars = BASE_36.chars().collect::<Vec<_>>();
9+
10+
let (lhs, rhs) = uuid.as_u64_pair();
11+
let mut num = hash_combined(lhs, rhs);
12+
13+
let mut result = String::new();
14+
while num > 0 {
15+
#[allow(clippy::cast_possible_truncation)]
16+
let remainder = (num % base) as usize;
17+
if let Some(c) = chars.get(remainder) {
18+
result.push(*c);
19+
}
20+
num /= base;
21+
}
22+
23+
result
24+
.chars()
25+
.chain(std::iter::repeat('0'))
26+
.take(ENCODED_LEN)
27+
.collect()
28+
}
29+
30+
// https://stackoverflow.com/a/27952689
31+
// https://www.boost.org/doc/libs/1_43_0/doc/html/hash/reference.html#boost.hash_combine
32+
#[allow(clippy::unreadable_literal)]
33+
const GOLDEN_RATIO: u64 = 0x9e3779b97f4a7c15;
34+
fn hash_combined(lhs: u64, rhs: u64) -> u64 {
35+
lhs ^ (rhs
36+
.wrapping_add(GOLDEN_RATIO)
37+
.wrapping_add(lhs << 6)
38+
.wrapping_add(lhs >> 2))
39+
}
40+
41+
#[cfg(test)]
42+
mod tests {
43+
use super::*;
44+
use uuid::Uuid;
45+
46+
#[test]
47+
fn test_encode_uuid() {
48+
let uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap();
49+
assert_eq!(encode_uuid(uuid), "p78ezm4408me2");
50+
51+
let uuid = Uuid::parse_str("ffffffff-ffff-ffff-ffff-ffffffffffff").unwrap();
52+
assert_eq!(encode_uuid(uuid), "gf47mznnithi0");
53+
54+
let uuid = Uuid::parse_str("12345678-1234-5678-1234-567812345678").unwrap();
55+
assert_eq!(encode_uuid(uuid), "nfi03cu0p7x71");
56+
}
57+
}

lib/bencher_context/src/client/platform/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ use std::fmt;
22

33
use uuid::Uuid;
44

5+
mod base36;
56
mod target_os;
67

78
#[derive(Debug, Clone, Copy)]
89
pub struct Fingerprint(Uuid);
910

1011
impl fmt::Display for Fingerprint {
1112
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12-
write!(f, "{}", self.0)
13+
write!(f, "{}", base36::encode_uuid(self.0))
1314
}
1415
}
1516

lib/bencher_context/src/client/platform/target_os/windows.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ fn digital_product_id() -> Option<Uuid> {
5353

5454
// There appear to be quite a few zeroed out bytes at the beginning of the digital product ID.
5555
// In order to ensure as much entropy as possible,
56-
// we'll just sum all of the bytes together in a wrapping fashion.
56+
// we'll just shift all of the bits dropped by the leading bytes as needed.
5757
let digital_product_id = data
5858
.into_iter()
5959
.take(data_size as usize)
60-
.fold(0u128, |acc, byte| acc.overflowing_add(byte.into()).0);
60+
.fold(0u128, |acc, byte| (acc << 8) | u128::from(byte));
6161
Some(Uuid::from_u128(digital_product_id))
6262
}
6363

lib/bencher_context/src/server/base36.rs

Lines changed: 0 additions & 37 deletions
This file was deleted.

lib/bencher_context/src/server/mod.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
use bencher_valid::{ResourceName, Slug};
2-
use uuid::Uuid;
32

43
use crate::{ContextPath, RunContext};
54

6-
mod base36;
7-
85
#[allow(clippy::multiple_inherent_impl)]
96
impl RunContext {
107
fn get(&self, path: &str) -> Option<&String> {
@@ -36,8 +33,9 @@ impl RunContext {
3633
self.get(ContextPath::TESTBED_OS).map(String::as_str)
3734
}
3835

39-
pub fn testbed_fingerprint(&self) -> Option<Uuid> {
40-
self.get(ContextPath::TESTBED_FINGERPRINT)?.parse().ok()
36+
pub fn testbed_fingerprint(&self) -> Option<&str> {
37+
self.get(ContextPath::TESTBED_FINGERPRINT)
38+
.map(String::as_str)
4139
}
4240

4341
pub fn name(&self) -> Option<ResourceName> {
@@ -52,8 +50,6 @@ impl RunContext {
5250
let hash = self.repo_hash().map(short_hash).unwrap_or_default();
5351
let fingerprint = self
5452
.testbed_fingerprint()
55-
.map(base36::encode_uuid)
56-
.as_deref()
5753
.map(short_fingerprint)
5854
.unwrap_or_default();
5955
// The spaces here are important,

lib/bencher_valid/src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ mod url;
2727
mod user_name;
2828

2929
pub use crate::git_hash::GitHash;
30-
pub use crate::slug::Slug;
31-
#[cfg(feature = "server")]
32-
pub use crate::slug::BASE_36;
30+
pub use crate::slug::{Slug, BASE_36};
3331
pub use crate::url::Url;
3432
pub use benchmark_name::BenchmarkName;
3533
pub use branch_name::BranchName;

lib/bencher_valid/src/slug.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use serde::{
1212

1313
use crate::{is_valid_len, ValidError, MAX_LEN};
1414

15-
#[cfg(feature = "server")]
1615
pub const BASE_36: &str = "0123456789abcdefghijklmnopqrstuvwxyz";
1716

1817
#[typeshare::typeshare]

0 commit comments

Comments
 (0)