hll: hll_multi_add — batch many (name,items) into one RPC

Mirrors the new waymaker-server HllMultiAdd: one call writes several reserved
HLLs (e.g. a presence flush across scope/bucket sketches), returning per-entry
result codes. Vendored proto synced. Processed locally server-side for now
(multi-name batch can't ring-route).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Michael Netshipise 2026-06-20 09:30:21 +02:00
parent 14a75f503e
commit 6366612250
2 changed files with 41 additions and 1 deletions

View File

@ -36,6 +36,9 @@ service WaymakerSketchesService {
// ----- HyperLogLog -----
rpc HllReserve (HllReserveRequest) returns (HllReserveResponse);
rpc HllAdd (HllAddRequest) returns (HllAddResponse);
// Batch many (name, items) into ONE call (e.g. a presence flush). Processed
// locally today (can't ring-route a multi-name batch) see the server TODO.
rpc HllMultiAdd (HllMultiAddRequest) returns (HllMultiAddResponse);
rpc HllCount (HllCountRequest) returns (HllCountResponse);
rpc HllMerge (HllMergeRequest) returns (HllMergeResponse);
rpc HllDelete (HllDeleteRequest) returns (HllDeleteResponse);
@ -165,6 +168,20 @@ message HllAddResponse {
string message = 3;
}
message HllMultiAddEntry {
string name = 1;
repeated bytes items = 2;
}
message HllMultiAddRequest {
repeated HllMultiAddEntry entries = 1;
}
message HllMultiAddResponse {
bool success = 1;
string result_code = 2;
string message = 3;
repeated string entry_results = 4;
}
message HllCountRequest { string name = 1; }
message HllCountResponse {
bool success = 1;

View File

@ -3,7 +3,8 @@
use crate::client::Client;
use crate::error::{Error, Result};
use crate::sketches_server::{
HllAddRequest, HllCountRequest, HllDeleteRequest, HllMergeRequest, HllReserveRequest,
HllAddRequest, HllCountRequest, HllDeleteRequest, HllMergeRequest, HllMultiAddEntry,
HllMultiAddRequest, HllReserveRequest,
};
use tonic::Request;
@ -108,6 +109,28 @@ impl Client {
Hll::new(self.clone(), name.into())
}
/// Batch many `(name, items)` HLL adds into ONE RPC — e.g. a presence flush that
/// writes the same id-set into several scope/bucket HLLs. Each name must already
/// be reserved (no auto-create); returns the per-entry result codes (`"ok"` /
/// `"no_such_hll"`, parallel to `entries`). NOTE: processed locally server-side
/// today (a multi-name batch can't ring-route) — single-node use only for now.
pub async fn hll_multi_add(&self, entries: Vec<(String, Vec<Vec<u8>>)>) -> Result<Vec<String>> {
let mut c = self.sketches_client();
let r = c
.hll_multi_add(Request::new(HllMultiAddRequest {
entries: entries
.into_iter()
.map(|(name, items)| HllMultiAddEntry { name, items })
.collect(),
}))
.await?
.into_inner();
if !r.success {
return Err(Error::server(r.result_code, r.message));
}
Ok(r.entry_results)
}
pub async fn delete_hll(&self, name: impl Into<String>) -> Result<()> {
let mut c = self.sketches_client();
let r = c