mutant_lib/mutant/
update_logic.rs1use super::MutAnt;
2use crate::error::Error;
3use crate::events::{invoke_callback, PutCallback, PutEvent};
4use log::{debug, error, info, trace, warn};
5
6pub(super) async fn update_item(
10 es: &MutAnt,
11 key: &str,
12 data_bytes: &[u8],
13 mut callback: Option<PutCallback>,
14) -> Result<(), Error> {
15 let data_size = data_bytes.len();
16 trace!(
17 "MutAnt [{}]: Starting update_item for key '{}' ({} bytes) using PadManager",
18 es.master_index_addr, key,
20 data_size
21 );
22
23 {
24 let mis_guard = es.master_index_storage.lock().await;
25 if !mis_guard.index.contains_key(key) {
26 debug!("UpdateItem[{}]: Key does not exist.", key);
27 return Err(Error::KeyNotFound(key.to_string()));
28 }
29 }
30
31 let mut needs_confirmation = false;
32 let mut estimated_new_pads_needed = 0;
33
34 match es.pad_manager.estimate_reservation(data_size).await {
35 Ok(Some(pads)) => {
36 if pads > 0 {
37 needs_confirmation = true;
38 estimated_new_pads_needed = pads;
39 debug!(
40 "UpdateItem[{}]: Estimate indicates {} new pads needed. Confirmation required.",
41 key, pads
42 );
43 invoke_callback(
44 &mut callback,
45 PutEvent::ReservingScratchpads {
46 needed: pads as u64,
47 },
48 )
49 .await?;
50 } else {
51 warn!(
52 "UpdateItem[{}]: estimate_reservation returned Some(0), which is unexpected. Proceeding.",
53 key
54 );
55 }
56 }
57 Ok(None) => {
58 debug!(
59 "UpdateItem[{}]: Estimate indicates enough free/existing pads available. No confirmation needed.",
60 key
61 );
62 }
63 Err(e) => {
64 error!(
65 "UpdateItem[{}]: Failed to estimate reservation needs: {}",
66 key, e
67 );
68 return Err(e);
69 }
70 }
71
72 if needs_confirmation {
73 let (total_space_bytes, free_space_bytes, current_scratchpads, _scratchpad_size) = {
74 let mis_guard = es.master_index_storage.lock().await;
75 let total_pads = mis_guard
76 .index
77 .values()
78 .map(|v| v.pads.len())
79 .sum::<usize>()
80 + mis_guard.free_pads.len();
81 let pad_size = mis_guard.scratchpad_size;
82 let total_space = total_pads * pad_size;
83 let free_space = mis_guard.free_pads.len() * pad_size;
84 (total_space, free_space, total_pads, pad_size)
85 };
86
87 debug!(
88 "UpdateItem[{}]: Invoking ConfirmReservation callback...",
89 key
90 );
91 invoke_callback(
92 &mut callback,
93 PutEvent::ConfirmReservation {
94 needed: estimated_new_pads_needed as u64,
95 data_size: data_size as u64,
96 total_space: total_space_bytes as u64,
97 free_space: free_space_bytes as u64,
98 current_scratchpads,
99 estimated_cost: None,
100 },
101 )
102 .await?;
103 info!(
104 "UpdateItem[{}]: Reservation confirmation received from user.",
105 key
106 );
107 } else {
108 info!(
109 "UpdateItem[{}]: Reservation confirmation not required.",
110 key
111 );
112 }
113
114 debug!(
115 "UpdateItem[{}]: Calling pad_manager.allocate_and_write...",
116 key
117 );
118
119 es.pad_manager
120 .allocate_and_write(key, data_bytes, callback)
121 .await?;
122
123 info!(
124 "UpdateItem[{}]: PadManager allocate_and_write completed successfully for update.",
125 key
126 );
127
128 debug!("UpdateItem[{}]: Saving final master index state...", key);
129 es.save_master_index().await?;
130
131 info!("UpdateItem[{}]: Update operation fully completed.", key);
132 Ok(())
133}