Skip to content

Commit

Permalink
string: Add sub_str command
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Jun 9, 2024
1 parent 77e5275 commit faa9f7d
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 13 deletions.
7 changes: 7 additions & 0 deletions src/cmd/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub enum StringCommand {
Append(String, Bytes),
Get(String),
GetDel(String),
GetRange(String, i64, i64),
GetSet(String, Bytes),
Set(String, Bytes),
StrLen(String),
Expand All @@ -37,6 +38,12 @@ impl StringCommand {
let key = parser.next_string()?;
Self::GetDel(key)
}
"getrange" => {
let key = parser.next_string()?;
let start = parser.next_i64()?;
let end = parser.next_i64()?;
Self::GetRange(key, start, end)
}
"getset" => {
let key = parser.next_string()?;
let value = parser.next_bytes()?;
Expand Down
13 changes: 13 additions & 0 deletions src/mem/string/get_range.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) 2024 Xu Shaohua <[email protected]>. All rights reserved.
// Use of this source is governed by GNU Affero General Public License
// that can be found in the LICENSE file.

use crate::cmd::frame::Frame;
use crate::mem::db::Db;
use crate::mem::string::sub_str::sub_str;

#[must_use]
#[inline]
pub fn get_range(db: &Db, key: &str, start: i64, end: i64) -> Frame {
sub_str(db, key, start, end)
}
2 changes: 2 additions & 0 deletions src/mem/string/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod append;
mod get_del;
mod get_set;
mod sub_str;
mod get_range;

#[derive(Debug, Clone)]
pub enum StrObject {
Expand Down Expand Up @@ -73,6 +74,7 @@ impl Mem {
StringCommand::Append(key, value) => append::append(&mut self.db, key, value),
StringCommand::Get(key) => get::get(&self.db, &key),
StringCommand::GetDel(key) => get_del::get_del(&mut self.db, &key),
StringCommand::GetRange(key, start, end) => get_range::get_range(&self.db, &key, start, end),
StringCommand::GetSet(key, value) => get_set::get_set(&mut self.db, key, value),
StringCommand::Set(key, value) => set::set(&mut self.db, key, value),
StringCommand::StrLen(key) => strlen::strlen(&self.db, &key),
Expand Down
10 changes: 8 additions & 2 deletions src/mem/string/sub_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// Use of this source is governed by GNU Affero General Public License
// that can be found in the LICENSE file.

use bytes::Bytes;

use crate::cmd::frame::Frame;
use crate::mem::db::{Db, MemObject};
use crate::mem::string::StrObject;
use crate::util::prune_range::slice_range_to_bytes;
use crate::util::prune_range::prune_range;

/// Returns the substring of the string value stored at key,
/// determined by the offsets start and end (both are inclusive).
Expand All @@ -19,7 +21,11 @@ pub fn sub_str(db: &Db, key: &str, start: i64, end: i64) -> Frame {
Some(MemObject::Str(value)) => match value {
StrObject::Integer(_) => todo!(),
StrObject::Vec(vec) => {
let bytes = slice_range_to_bytes(vec, start, end);
let bytes = if let Some((start, end)) = prune_range(vec.len(), start, end) {
Bytes::copy_from_slice(&vec[start..=end])
} else {
Bytes::new()
};
Frame::Bulk(bytes)
}
}
Expand Down
16 changes: 5 additions & 11 deletions src/util/prune_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@
// Use of this source is governed by GNU Affero General Public License
// that can be found in the LICENSE file.

use bytes::Bytes;

pub fn slice_range_to_bytes(slice: &[u8], start: i64, end: i64) -> Bytes {
if let Some((start, end)) = prune_range(slice.len(), start, end) {
Bytes::copy_from_slice(&slice[start..=end])
} else {
Bytes::new()
}
}

#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_possible_wrap)]
#[allow(clippy::cast_sign_loss)]
pub fn prune_range(len: usize, mut start: i64, mut end: i64) -> Option<(usize, usize)> {
// TODO(Shaohua): Handle cast error
let len_i64 = len as i64;
if start < 0 {
start += len_i64 + start
start += len_i64;
}
if end < 0 {
end += len_i64;
Expand Down

0 comments on commit faa9f7d

Please sign in to comment.