libdpf/examples/evaluation/output_buffers.cpp

82 lines
2.7 KiB
C++

#include <cstdint>
#include <iostream>
#include "dpf.hpp"
/// Output buffers are move-only. `eval_interval` takes the buffer by
/// non-const reference, so name it. The iterable points into that buffer;
/// read it only while the buffer is still alive, and only over the points
/// the iterable covers.
int main()
{
const std::uint8_t alpha = 42;
const std::uint64_t beta = 7;
const std::uint8_t from = 40;
const std::uint8_t to = 50;
auto [k0, k1] = dpf::make_dpf(alpha, beta);
using key_t = dpf::unwrap_party_key_t<std::decay_t<decltype(k0)>>;
//! [output-buffer]
auto buf0 = dpf::make_output_buffer_for_interval(k0, from, to);
auto buf1 = dpf::make_output_buffer_for_interval(k1, from, to);
auto memo0 = dpf::make_basic_interval_memoizer<key_t>(from, to);
auto memo1 = dpf::make_basic_interval_memoizer<key_t>(from, to);
auto iter0 = dpf::eval_interval(k0, from, to, buf0, memo0);
auto iter1 = dpf::eval_interval(k1, from, to, buf1, memo1);
auto it0 = std::begin(iter0);
auto it1 = std::begin(iter1);
for (std::uint8_t x = from; x <= to; ++x, ++it0, ++it1)
{
std::uint64_t got = dpf::reconstruct(*it0, *it1);
std::uint64_t expect = (x == alpha) ? beta : 0;
if (got != expect)
{
std::cerr << "output buffer\n";
return 1;
}
}
//! [output-buffer]
// The next evaluation overwrites the same slots.
auto [k0b, k1b] = dpf::make_dpf(std::uint8_t{44}, std::uint64_t{9});
iter0 = dpf::eval_interval(k0b, from, to, buf0, memo0);
iter1 = dpf::eval_interval(k1b, from, to, buf1, memo1);
it0 = std::begin(iter0);
it1 = std::begin(iter1);
for (std::uint8_t x = from; x <= to; ++x, ++it0, ++it1)
{
std::uint64_t got = dpf::reconstruct(*it0, *it1);
std::uint64_t expect = (x == 44) ? 9 : 0;
if (got != expect)
{
std::cerr << "output buffer reuse\n";
return 1;
}
}
//! [output-buffer-full]
auto full0 = dpf::make_output_buffer_for_full(k0);
auto full1 = dpf::make_output_buffer_for_full(k1);
auto fmemo0 = dpf::make_basic_full_memoizer<key_t>();
auto fmemo1 = dpf::make_basic_full_memoizer<key_t>();
auto f0 = dpf::eval_full(k0, full0, fmemo0);
auto f1 = dpf::eval_full(k1, full1, fmemo1);
//! [output-buffer-full]
it0 = std::begin(f0);
it1 = std::begin(f1);
for (int x = 0; x < 256; ++x, ++it0, ++it1)
{
std::uint64_t got = dpf::reconstruct(*it0, *it1);
std::uint64_t expect = (static_cast<std::uint8_t>(x) == alpha) ? beta : 0;
if (got != expect)
{
std::cerr << "full output buffer\n";
return 1;
}
}
std::cout << beta << "\n";
return 0;
}