#ifndef _VAR_OPT_UNION_HPP_
#define _VAR_OPT_UNION_HPP_
#include "var_opt_sketch.hpp"
#include "common_defs.hpp"
#include "serde.hpp"
#include <vector>
namespace datasketches {
template<typename A> using AllocU8 = typename std::allocator_traits<A>::template rebind_alloc<uint8_t>;
template<
typename T,
typename A = std::allocator<T>
>
class var_opt_union {
public:
explicit var_opt_union(uint32_t max_k, const A& allocator = A());
var_opt_union(const var_opt_union& other);
var_opt_union(var_opt_union&& other) noexcept;
~var_opt_union();
var_opt_union& operator=(const var_opt_union& other);
var_opt_union& operator=(var_opt_union&& other);
void update(const var_opt_sketch<T, A>& sk);
void update(var_opt_sketch<T, A>&& sk);
var_opt_sketch<T, A> get_result() const;
void reset();
template<typename SerDe = serde<T>>
size_t get_serialized_size_bytes(const SerDe& sd = SerDe()) const;
typedef vector_u8<A> vector_bytes;
template<typename SerDe = serde<T>>
vector_bytes serialize(unsigned header_size_bytes = 0, const SerDe& sd = SerDe()) const;
template<typename SerDe = serde<T>>
void serialize(std::ostream& os, const SerDe& sd = SerDe()) const;
template<typename SerDe = serde<T>>
static var_opt_union deserialize(std::istream& is, const SerDe& sd = SerDe(), const A& allocator = A());
template<typename SerDe = serde<T>>
static var_opt_union deserialize(const void* bytes, size_t size, const SerDe& sd = SerDe(), const A& allocator = A());
string<A> to_string() const;
private:
using AllocSketch = typename std::allocator_traits<A>::template rebind_alloc<var_opt_sketch<T, A>>;
using AllocDouble = typename std::allocator_traits<A>::template rebind_alloc<double>;
using AllocBool = typename std::allocator_traits<A>::template rebind_alloc<bool>;
static const uint8_t PREAMBLE_LONGS_EMPTY = 1;
static const uint8_t PREAMBLE_LONGS_NON_EMPTY = 4;
static const uint8_t SER_VER = 2;
static const uint8_t FAMILY_ID = 14;
static const uint8_t EMPTY_FLAG_MASK = 4;
uint64_t n_;
double outer_tau_numer_;
uint64_t outer_tau_denom_;
uint32_t max_k_;
A allocator_;
var_opt_sketch<T, A> gadget_;
var_opt_union(uint64_t n, double outer_tau_numer, uint64_t outer_tau_denom,
uint32_t max_k, var_opt_sketch<T, A>&& gadget, const A& allocator = A());
inline void merge_items(const var_opt_sketch<T, A>& sk);
inline void merge_items(var_opt_sketch<T, A>&& sk);
inline void resolve_tau(const var_opt_sketch<T, A>& sketch);
double get_outer_tau() const;
var_opt_sketch<T, A> simple_gadget_coercer() const;
bool there_exist_unmarked_h_items_lighter_than_target(double threshold) const;
bool detect_and_handle_subcase_of_pseudo_exact(var_opt_sketch<T, A>& sk) const;
void mark_moving_gadget_coercer(var_opt_sketch<T, A>& sk) const;
void migrate_marked_items_by_decreasing_k(var_opt_sketch<T, A>& sk) const;
static void check_preamble_longs(uint8_t preamble_longs, uint8_t flags);
static void check_family_and_serialization_version(uint8_t family_id, uint8_t ser_ver);
};
}
#include "var_opt_union_impl.hpp"
#endif