MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / handle_zadd

Function handle_zadd

nodedb/src/control/server/resp/handler_sorted.rs:29–86  ·  view source on GitHub ↗

ZADD key score member [score member ...] Adds members with scores to a sorted index. The "key" is the sorted index name. Each score/member pair is inserted by writing to the underlying KV collection (which triggers sorted index auto-maintenance). For RESP compatibility, ZADD dispatches a KV PUT with the score embedded in the value, which auto-updates the sorted index.

(
    cmd: &RespCommand,
    session: &RespSession,
    state: &SharedState,
)

Source from the content-addressed store, hash-verified

27/// For RESP compatibility, ZADD dispatches a KV PUT with the score embedded
28/// in the value, which auto-updates the sorted index.
29pub(super) async fn handle_zadd(
30 cmd: &RespCommand,
31 session: &RespSession,
32 state: &SharedState,
33) -> RespValue {
34 // ZADD needs at least: key score member
35 if cmd.argc() < 3 || !cmd.argc().is_multiple_of(2) {
36 return RespValue::err("ERR wrong number of arguments for 'zadd' command");
37 }
38
39 // In RESP mode, the sorted index name = session.collection.
40 // The args are: score1 member1 [score2 member2 ...]
41 let index_name = session.collection.clone();
42 let mut added = 0i64;
43
44 let mut i = 0;
45 while i + 1 < cmd.argc() {
46 let score_str = match cmd.arg_str(i) {
47 Some(s) => s,
48 None => return RespValue::err("ERR value is not a valid float"),
49 };
50 let score: f64 = match score_str.parse() {
51 Ok(v) => v,
52 Err(_) => return RespValue::err("ERR value is not a valid float"),
53 };
54 let member = cmd.args[i + 1].clone();
55
56 // Write to the underlying KV collection as a MessagePack document
57 // containing the score and member. The sorted index auto-maintenance
58 // in KvEngine::put will update the order-statistic tree.
59 let value = nodedb_types::json_to_msgpack(&serde_json::json!({
60 "score": score,
61 "member": String::from_utf8_lossy(&member),
62 }))
63 .unwrap_or_default();
64
65 let surrogate = match state.surrogate_assigner.assign(&index_name, &member) {
66 Ok(s) => s,
67 Err(e) => return RespValue::err(format!("ERR {e}")),
68 };
69 let plan = PhysicalPlan::Kv(KvOp::Put {
70 collection: index_name.clone(),
71 key: member,
72 value,
73 ttl_ms: 0,
74 surrogate,
75 });
76
77 match dispatch_kv_write(state, session, plan).await {
78 Ok(_) => added += 1,
79 Err(e) => return RespValue::err(format!("ERR {e}")),
80 }
81
82 i += 2;
83 }
84
85 RespValue::integer(added)
86}

Callers 1

executeFunction · 0.85

Calls 8

dispatch_kv_writeFunction · 0.85
argcMethod · 0.80
arg_strMethod · 0.80
errFunction · 0.50
json_to_msgpackFunction · 0.50
cloneMethod · 0.45
parseMethod · 0.45
assignMethod · 0.45

Tested by

no test coverage detected