Skip to content

Commit 446405d

Browse files
committed
lset on cache
1 parent 1cd5e5c commit 446405d

6 files changed

Lines changed: 73 additions & 1 deletion

File tree

duva/src/domains/caches/actor.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,19 @@ impl CacheActor {
220220
| _ => Err(anyhow::anyhow!(WRONG_TYPE_ERR_MSG)),
221221
}
222222
}
223+
224+
pub(crate) fn lset(
225+
&mut self,
226+
key: String,
227+
index: isize,
228+
value: String,
229+
) -> Result<(), anyhow::Error> {
230+
let Some(CacheValue { value: TypedValue::List(list), .. }) = self.cache.get_mut(&key)
231+
else {
232+
return Err(anyhow::anyhow!(WRONG_TYPE_ERR_MSG));
233+
};
234+
list.lset(index, value)
235+
}
223236
}
224237

225238
#[derive(Clone, Debug)]

duva/src/domains/caches/cache_manager.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,21 @@ impl CacheManager {
422422
let value = rx.await??;
423423
Ok(value)
424424
}
425+
426+
pub(crate) async fn route_lset(
427+
&self,
428+
key: String,
429+
index: isize,
430+
value: String,
431+
current_idx: u64,
432+
) -> Result<String> {
433+
let (tx, rx) = tokio::sync::oneshot::channel();
434+
self.select_shard(key.as_str())
435+
.send(CacheCommand::LSet { key, index, value: value.clone(), callback: tx.into() })
436+
.await?;
437+
rx.await??;
438+
Ok(IndexedValueCodec::encode(value, current_idx))
439+
}
425440
}
426441

427442
pub struct IndexedValueCodec;

duva/src/domains/caches/cache_objects/types/quicklist.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,36 @@ impl QuickList {
531531
}
532532
None
533533
}
534+
535+
pub(crate) fn lset(&mut self, index: isize, value: String) -> anyhow::Result<()> {
536+
if self.len == 0 {
537+
return Err(anyhow::anyhow!("List is empty"));
538+
}
539+
540+
// Calculate absolute index
541+
let len = self.len as isize;
542+
let index = if index < 0 { (len + index).max(0) } else { index } as usize;
543+
544+
if index >= self.len {
545+
return Err(anyhow::anyhow!("Index out of bounds"));
546+
}
547+
548+
let mut current_index = 0;
549+
for node in &mut self.nodes {
550+
if current_index + node.entry_count > index {
551+
node.ensure_decompressed(&self.fill_factor);
552+
if let NodeData::Uncompressed(ziplist) = &mut node.data {
553+
let mut entries = ziplist.to_vec();
554+
if let Some(entry) = entries.get_mut(index - current_index) {
555+
*entry = Bytes::from(value.clone());
556+
return Ok(());
557+
}
558+
}
559+
}
560+
current_index += node.entry_count;
561+
}
562+
Err(anyhow::anyhow!("Index not found"))
563+
}
534564
}
535565

536566
#[cfg(test)]

duva/src/domains/caches/command.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,10 @@ pub(crate) enum CacheCommand {
9090
index: isize,
9191
callback: Callback<anyhow::Result<CacheValue>>,
9292
},
93+
LSet {
94+
key: String,
95+
index: isize,
96+
value: String,
97+
callback: Callback<anyhow::Result<()>>,
98+
},
9399
}

duva/src/domains/caches/service.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ impl CacheActor {
9494
| CacheCommand::LIndex { key, index, callback } => {
9595
let _ = callback.send(self.lindex(key, index));
9696
},
97+
| CacheCommand::LSet { key, index, value, callback } => {
98+
let _ = callback.send(self.lset(key, index, value));
99+
},
97100
}
98101
}
99102
Ok(self)

duva/src/presentation/clients/controller.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,12 @@ impl ClientController {
209209
| ClientAction::LIndex { key, index } => {
210210
self.cache_manager.route_lindex(key, index).await?.into()
211211
},
212-
| ClientAction::LSet { key, index, value } => todo!(),
212+
| ClientAction::LSet { key, index, value } => QueryIO::SimpleString(
213+
self.cache_manager
214+
.route_lset(key, index, value, current_index.unwrap())
215+
.await?
216+
.into(),
217+
),
213218
};
214219

215220
Ok(response)

0 commit comments

Comments
 (0)