use std::sync::Arc;
use crate::msgpack::encoder::pack_hll_op;
use crate::operations::cdt::{CdtArgument, CdtOperation};
use crate::operations::cdt_context::DEFAULT_CTX;
use crate::operations::{Operation, OperationBin, OperationData, OperationType};
use crate::Value;
#[derive(Debug, Clone, Copy)]
pub enum HLLWriteFlags {
Default = 0,
CreateOnly = 1,
UpdateOnly = 2,
NoFail = 4,
AllowFold = 8,
}
pub trait ToHLLWriteFlagsBitmask {
fn to_bitmask(self) -> i64;
}
impl ToHLLWriteFlagsBitmask for HLLWriteFlags {
fn to_bitmask(self) -> i64 {
self as i64
}
}
impl<T: IntoIterator<Item = HLLWriteFlags>> ToHLLWriteFlagsBitmask for T {
fn to_bitmask(self) -> i64 {
let mut out = 0;
for val in self {
out |= val.to_bitmask();
}
out
}
}
#[derive(Debug, Clone, Copy)]
pub struct HLLPolicy {
pub flags: i64,
}
impl HLLPolicy {
pub const fn new(write_flags: HLLWriteFlags) -> Self {
HLLPolicy {
flags: write_flags as i64,
}
}
pub fn new_with_flags<HWF: ToHLLWriteFlagsBitmask>(write_flags: HWF) -> Self {
HLLPolicy {
flags: write_flags.to_bitmask(),
}
}
}
impl Default for HLLPolicy {
fn default() -> Self {
HLLPolicy::new(HLLWriteFlags::Default)
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) enum HLLOpType {
Init = 0,
Add = 1,
SetUnion = 2,
SetCount = 3,
Fold = 4,
Count = 50,
Union = 51,
UnionCount = 52,
IntersectCount = 53,
Similarity = 54,
Describe = 55,
}
pub fn init(policy: &HLLPolicy, bin: &str, index_bit_count: i64) -> Operation {
init_with_min_hash(policy, bin, index_bit_count, -1)
}
pub fn init_with_min_hash(
policy: &HLLPolicy,
bin: &str,
index_bit_count: i64,
min_hash_bit_count: i64,
) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::Init as u8,
encoder: Arc::new(pack_hll_op),
args: vec![
CdtArgument::Int(index_bit_count),
CdtArgument::Int(min_hash_bit_count),
CdtArgument::Byte(policy.flags as u8),
],
};
Operation {
op: OperationType::HllWrite,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn add(policy: &HLLPolicy, bin: &str, list: Vec<Value>) -> Operation {
add_with_index_and_min_hash(policy, bin, list, -1, -1)
}
pub fn add_with_index(
policy: &HLLPolicy,
bin: &str,
list: Vec<Value>,
index_bit_count: i64,
) -> Operation {
add_with_index_and_min_hash(policy, bin, list, index_bit_count, -1)
}
pub fn add_with_index_and_min_hash(
policy: &HLLPolicy,
bin: &str,
list: Vec<Value>,
index_bit_count: i64,
min_hash_bit_count: i64,
) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::Add as u8,
encoder: Arc::new(pack_hll_op),
args: vec![
CdtArgument::List(list),
CdtArgument::Int(index_bit_count),
CdtArgument::Int(min_hash_bit_count),
CdtArgument::Byte(policy.flags as u8),
],
};
Operation {
op: OperationType::HllWrite,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn set_union(policy: &HLLPolicy, bin: &str, list: Vec<Value>) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::SetUnion as u8,
encoder: Arc::new(pack_hll_op),
args: vec![
CdtArgument::List(list),
CdtArgument::Byte(policy.flags as u8),
],
};
Operation {
op: OperationType::HllWrite,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn refresh_count(bin: &str) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::SetCount as u8,
encoder: Arc::new(pack_hll_op),
args: vec![],
};
Operation {
op: OperationType::HllWrite,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn fold(bin: &str, index_bit_count: i64) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::Fold as u8,
encoder: Arc::new(pack_hll_op),
args: vec![CdtArgument::Int(index_bit_count)],
};
Operation {
op: OperationType::HllWrite,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn get_count(bin: &str) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::Count as u8,
encoder: Arc::new(pack_hll_op),
args: vec![],
};
Operation {
op: OperationType::HllRead,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn get_union(bin: &str, list: Vec<Value>) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::Union as u8,
encoder: Arc::new(pack_hll_op),
args: vec![CdtArgument::List(list)],
};
Operation {
op: OperationType::HllRead,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn get_union_count(bin: &str, list: Vec<Value>) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::UnionCount as u8,
encoder: Arc::new(pack_hll_op),
args: vec![CdtArgument::List(list)],
};
Operation {
op: OperationType::HllRead,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn get_intersect_count(bin: &str, list: Vec<Value>) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::IntersectCount as u8,
encoder: Arc::new(pack_hll_op),
args: vec![CdtArgument::List(list)],
};
Operation {
op: OperationType::HllRead,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn get_similarity(bin: &str, list: Vec<Value>) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::Similarity as u8,
encoder: Arc::new(pack_hll_op),
args: vec![CdtArgument::List(list)],
};
Operation {
op: OperationType::HllRead,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}
pub fn describe(bin: &str) -> Operation {
let cdt_op = CdtOperation {
op: HLLOpType::Describe as u8,
encoder: Arc::new(pack_hll_op),
args: vec![],
};
Operation {
op: OperationType::HllRead,
ctx: DEFAULT_CTX,
bin: OperationBin::Name(bin.into()),
data: OperationData::HLLOp(cdt_op),
}
}