///|
struct SampleInput {
timestamp : UInt64
value : Double
quality : @telemetry.Quality
}
///|
struct Fixture {
samples : Array[SampleInput]
plain : Array[Bytes]
packed : Array[Bytes]
}
///|
enum Operation {
Encode
SelectedRead
FullScan
Pack
Unpack
OpaqueCopy
}
///|
fn Operation::name(self : Operation) -> String {
match self {
Encode => "encode"
SelectedRead => "selected_read"
FullScan => "full_scan"
Pack => "pack"
Unpack => "unpack"
OpaqueCopy => "opaque_copy"
}
}
///|
fn mix(checksum : UInt32, value : UInt32) -> UInt32 {
checksum.lxor(value) * 16777619U
}
///|
fn mix_u64(checksum : UInt32, value : UInt64) -> UInt32 {
mix(mix(checksum, value.to_uint()), (value >> 32).to_uint())
}
///|
fn mix_text(checksum : UInt32, value : String) -> UInt32 {
let mut result = checksum
for c in value {
result = mix(result, c.to_int().reinterpret_as_uint())
}
result
}
///|
fn job_id(variant : Int32) -> UInt64 {
9007199254740993UL + variant.to_uint64()
}
///|
fn encode(
samples : Array[SampleInput],
variant : Int32,
) -> Bytes raise @capnp.CapnpError {
let message = @capnp.Builder::new()
let root = @telemetry.BatchBuilder::init_root(message)
root.set_job_id(job_id(variant))
root.set_source("benchmark-room-中文")
root.set_unit("celsius")
let list = root.init_samples(samples.length())
for i, input in samples {
let item = list.get(i)
item.set_timestamp_ns(input.timestamp)
item.set_value(input.value)
item.set_quality(input.quality)
}
message.finish()
}
///|
fn selected_read(bytes : Bytes) -> UInt32 raise @capnp.CapnpError {
let root = @telemetry.BatchReader::from_message(@capnp.read_message(bytes))
let samples = root.get_samples()
let mut sum = mix_u64(2166136261U, root.get_job_id())
sum = mix(sum, samples.length().reinterpret_as_uint())
sum = mix_u64(sum, samples.get(0).get_value().reinterpret_as_uint64())
mix_u64(
sum,
samples.get(samples.length() - 1).get_value().reinterpret_as_uint64(),
)
}
///|
fn full_scan(bytes : Bytes) -> UInt32 raise @capnp.CapnpError {
let root = @telemetry.BatchReader::from_message(@capnp.read_message(bytes))
let samples = root.get_samples()
let mut sum = mix_u64(2166136261U, root.get_job_id())
sum = mix_text(sum, root.get_source())
sum = mix_text(sum, root.get_unit())
sum = mix(sum, samples.length().reinterpret_as_uint())
for i in 0.. Bytes raise @capnp.CapnpError {
let source = @capnp.read_message(bytes)
let target = @capnp.Builder::new()
target.root_pointer().set(source.root_pointer())
target.finish()
}
///|
// Constant-size observation of an output allocation; full correctness checks
// are performed before measurement. This cost is included in all byte-producing
// operations. The checksum is emitted and checked after every measured batch.
fn fingerprint(bytes : Bytes) -> UInt32 {
let mut sum = mix(2166136261U, bytes.length().reinterpret_as_uint())
let head = if bytes.length() < 24 { bytes.length() } else { 24 }
for i in 0.. UInt32 raise @capnp.CapnpError {
match operation {
Encode => fingerprint(encode(fixture.samples, variant))
SelectedRead => selected_read(fixture.plain[variant])
FullScan => full_scan(fixture.plain[variant])
Pack => fingerprint(@capnp.pack(fixture.plain[variant]))
Unpack => fingerprint(@capnp.unpack(fixture.packed[variant]))
OpaqueCopy => fingerprint(opaque_copy(fixture.plain[variant]))
}
}
///|
fn validate_batch(
bytes : Bytes,
inputs : Array[SampleInput],
variant : Int32,
) -> Unit raise {
let root = @telemetry.BatchReader::from_message(@capnp.read_message(bytes))
assert_eq(root.get_job_id(), job_id(variant))
assert_eq(root.get_source(), "benchmark-room-中文")
assert_eq(root.get_unit(), "celsius")
let samples = root.get_samples()
assert_eq(samples.length(), inputs.length())
let mut expected = mix_u64(2166136261U, job_id(variant))
expected = mix_text(expected, "benchmark-room-中文")
expected = mix_text(expected, "celsius")
expected = mix(expected, inputs.length().reinterpret_as_uint())
for i, input in inputs {
let sample = samples.get(i)
assert_eq(sample.get_timestamp_ns(), input.timestamp)
assert_eq(sample.get_value(), input.value)
assert_eq(sample.get_quality().to_raw(), input.quality.to_raw())
expected = mix_u64(expected, input.timestamp)
expected = mix_u64(expected, input.value.reinterpret_as_uint64())
expected = mix(expected, input.quality.to_raw())
}
assert_eq(full_scan(bytes), expected)
let expected_selected = mix_u64(
mix_u64(
mix(
mix_u64(2166136261U, job_id(variant)),
inputs.length().reinterpret_as_uint(),
),
inputs[0].value.reinterpret_as_uint64(),
),
inputs[inputs.length() - 1].value.reinterpret_as_uint64(),
)
assert_eq(selected_read(bytes), expected_selected)
}
///|
fn make_fixture(count : Int32) -> Fixture raise {
let samples = Array::makei(count, i => {
(
{
timestamp: 1700000000000000000UL + i.to_uint64() * 1000000UL,
value: 18.0 + (i % 80).to_double() * 0.25,
quality: @telemetry.Quality::from_raw((i % 3).reinterpret_as_uint()),
} : SampleInput)
})
let plain : Array[Bytes] = []
let packed : Array[Bytes] = []
for variant in 0..<2 {
let bytes = encode(samples, variant)
validate_batch(bytes, samples, variant)
let compressed = @capnp.pack(bytes)
assert_eq(@capnp.unpack(compressed), bytes)
let copy = opaque_copy(bytes)
validate_batch(copy, samples, variant)
assert_eq(
@capnp.canonicalize(@capnp.read_message(copy)),
@capnp.canonicalize(@capnp.read_message(bytes)),
)
plain.push(bytes)
packed.push(compressed)
}
assert_eq(plain[0].length(), plain[1].length())
assert_eq(packed[0].length(), packed[1].length())
{ samples, plain, packed, }
}