Skip to content

Commit 47e6129

Browse files
committed
feat: optimising all the commands args
Reducing string allocations. Directly accessing args. SD-7448
1 parent e51c109 commit 47e6129

File tree

3 files changed

+61
-49
lines changed

3 files changed

+61
-49
lines changed

src/commands/pubsub.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::time::Duration;
22

3-
use redis_module::{Context, NextArg, RedisError, RedisResult, RedisString, RedisValue};
3+
use redis_module::{Context, RedisError, RedisResult, RedisString, RedisValue};
44

55
use super::redis_module_ext::call;
66

@@ -36,15 +36,15 @@ pub fn publishset(ctx: &Context, args: Vec<RedisString>) -> RedisResult {
3636
return Err(RedisError::WrongArity);
3737
}
3838

39-
let mut mutable_args = args.into_iter().skip(1);
40-
let channel = mutable_args.next_arg()?;
41-
let message = mutable_args.next_arg()?;
39+
let [_, channel, message] = &args[..] else {
40+
return Err(RedisError::WrongArity);
41+
};
4242

43-
let redis_key = ctx.open_key_writable(&channel);
43+
let redis_key = ctx.open_key_writable(channel);
4444

4545
let result = redis_key.write(&message.to_string_lossy())?;
4646

47-
call(ctx, "publish", &[&channel, &message])?;
47+
call(ctx, "publish", &[channel, message])?;
4848

4949
Ok(result)
5050
}
@@ -54,17 +54,20 @@ pub fn publishsetex(ctx: &Context, args: Vec<RedisString>) -> RedisResult {
5454
return Err(RedisError::WrongArity);
5555
}
5656

57-
let mut mutable_args = args.into_iter().skip(1);
58-
let channel = mutable_args.next_arg()?;
59-
let seconds = mutable_args.next_u64()?;
60-
let message = mutable_args.next_arg()?;
57+
let [_, channel, seconds, message] = &args[..] else {
58+
return Err(RedisError::WrongArity);
59+
};
60+
61+
let seconds = seconds
62+
.parse_unsigned_integer()
63+
.map_err(|_| RedisError::Str("Invalid seconds value"))?;
6164

62-
let redis_key = ctx.open_key_writable(&channel);
65+
let redis_key = ctx.open_key_writable(channel);
6366

6467
let result = redis_key.write(&message.to_string_lossy())?;
6568
redis_key.set_expire(Duration::from_secs(seconds))?;
6669

67-
call(ctx, "publish", &[&channel, &message])?;
70+
call(ctx, "publish", &[channel, message])?;
6871

6972
Ok(result)
7073
}

src/commands/sorted_sets.rs

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,57 @@
11
use itertools::Itertools;
2-
use redis_module::{Context, NextArg, RedisError, RedisResult, RedisString, RedisValue};
2+
use redis_module::{Context, RedisError, RedisResult, RedisString, RedisValue};
3+
4+
use super::redis_module_ext::call;
35

46
/// ZUNIONBYSCORE numkeys key [key ...] min max [LIMIT] offset count
57
pub fn zunionbyscore(ctx: &Context, args: Vec<RedisString>) -> RedisResult {
68
if args.len() < 8 {
79
return Err(RedisError::WrongArity);
810
}
911

10-
let mut mutable_args = args.into_iter().skip(1);
11-
let numkeys = mutable_args.next_i64()?;
12-
let numkeys_string = numkeys.to_string();
12+
let mut args_iter = args.iter().skip(1);
13+
let numkeys_str = args_iter.next().ok_or(RedisError::WrongArity)?;
14+
let numkeys = numkeys_str
15+
.parse_integer()
16+
.map_err(|_| RedisError::WrongArity)?;
1317

14-
let mut keys: Vec<&str> = Vec::new();
15-
keys.push(&numkeys_string);
18+
let keys = &args[2..(2 + numkeys as usize)];
19+
let min_arg = &args[2 + numkeys as usize];
20+
let max_arg = &args[3 + numkeys as usize];
21+
let limit_arg = &args[4 + numkeys as usize];
22+
let offset_arg = &args[5 + numkeys as usize];
23+
let count_arg = &args[6 + numkeys as usize];
1624

17-
for _i in 0..numkeys {
18-
let key = mutable_args.next_str()?;
19-
keys.push(key);
25+
if limit_arg.to_string_lossy() != "LIMIT" {
26+
return Err(RedisError::WrongType);
2027
}
2128

22-
let min = mutable_args.next_f64()?;
23-
let max = mutable_args.next_f64()?;
29+
let min = min_arg.parse_float().map_err(|_| RedisError::WrongType)?;
30+
let max = max_arg.parse_float().map_err(|_| RedisError::WrongType)?;
2431

25-
let limit = mutable_args.next_str()?;
26-
if limit != "LIMIT" {
27-
return Err(RedisError::WrongArity);
28-
}
32+
let offset = offset_arg
33+
.parse_unsigned_integer()
34+
.map_err(|_| RedisError::WrongType)?;
35+
let count = count_arg
36+
.parse_unsigned_integer()
37+
.map_err(|_| RedisError::WrongType)?;
2938

30-
let offset = mutable_args.next_u64()?;
31-
let count = mutable_args.next_u64()?;
39+
let min_str = min.to_string();
40+
let max_str = max.to_string();
41+
let byscore = ctx.create_string("BYSCORE");
42+
let withscores = ctx.create_string("WITHSCORES");
43+
let min_redis_str = ctx.create_string(&min_str);
44+
let max_redis_str = ctx.create_string(&max_str);
3245

3346
let response = keys
34-
.into_iter()
47+
.iter()
3548
.filter_map(|key| {
36-
let min_str = min.to_string();
37-
let max_str = max.to_string();
38-
39-
let results = ctx
40-
.call(
41-
"zrange",
42-
&[key, &min_str, &max_str, "BYSCORE", "WITHSCORES"],
43-
)
44-
.ok()?;
49+
let results = call(
50+
ctx,
51+
"zrange",
52+
&[key, &min_redis_str, &max_redis_str, &byscore, &withscores],
53+
)
54+
.ok()?;
4555
match results {
4656
RedisValue::Array(values) => {
4757
let keys = values

src/commands/streams.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1-
use redis_module::{Context, NextArg, RedisError, RedisResult, RedisString, RedisValue};
1+
use redis_module::{Context, RedisError, RedisResult, RedisString, RedisValue};
2+
3+
use super::redis_module_ext::call;
24

35
/// XMREVRANGE end start COUNT count key [key ...]
46
pub fn xmrevrange(ctx: &Context, args: Vec<RedisString>) -> RedisResult {
57
if args.len() < 6 {
68
return Err(RedisError::WrongArity);
79
}
810

9-
let mut mutable_args = args.into_iter().skip(1);
10-
let end = mutable_args.next_string()?;
11-
let start = mutable_args.next_string()?;
12-
let keyword = mutable_args.next_string()?;
13-
let count = mutable_args.next_string()?;
11+
let [_, end, start, keyword, count, keys @ ..] = &args[..] else {
12+
return Err(RedisError::WrongArity);
13+
};
1414

15-
let mut response: Vec<RedisValue> = Vec::with_capacity(mutable_args.len());
15+
let mut response: Vec<RedisValue> = Vec::with_capacity(keys.len());
1616

17-
for arg in mutable_args {
18-
let key = RedisString::to_string_lossy(&arg);
19-
let result = ctx.call("xrevrange", &[&key, &end, &start, &keyword, &count]);
17+
for key in keys {
18+
let result = call(ctx, "xrevrange", &[key, end, start, keyword, count]);
2019
match result {
2120
Ok(value) => {
2221
response.push(value);

0 commit comments

Comments
 (0)