Skip to content

Commit f001ee1

Browse files
authored
avoid path clone when not needed (RedisJSON#398)
Avoid path clone when not needed
1 parent fd5889b commit f001ee1

File tree

2 files changed

+39
-23
lines changed

2 files changed

+39
-23
lines changed

src/commands.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ impl<'a, V: SelectValue> KeyValue<'a, V> {
180180
let temp_doc = paths.drain(..).fold(HashMap::new(), |mut acc, path| {
181181
let mut selector = Selector::new();
182182
selector.value(self.val);
183-
if let Err(_) = selector.str_path(&path.fixed) {
183+
if let Err(_) = selector.str_path(path.get_path()) {
184184
return acc;
185185
}
186186
let value = match selector.select() {
@@ -190,20 +190,25 @@ impl<'a, V: SelectValue> KeyValue<'a, V> {
190190
},
191191
Err(_) => None,
192192
};
193-
acc.insert(path.path, value);
193+
acc.insert(path.take_original(), value);
194194
acc
195195
});
196196
Ok(self
197197
.serialize_object(&temp_doc, &indent, &newline, &space)
198198
.into())
199199
} else {
200200
let path = &paths[0];
201-
if path.is_legacy {
201+
if path.is_legacy() {
202202
Ok(self
203-
.serialize_object(self.get_first(&paths[0].fixed)?, &indent, &newline, &space)
203+
.serialize_object(
204+
self.get_first(paths[0].get_path())?,
205+
&indent,
206+
&newline,
207+
&space,
208+
)
204209
.into())
205210
} else {
206-
let values = self.get_values(&path.fixed)?;
211+
let values = self.get_values(path.get_path())?;
207212
Ok(self
208213
.serialize_object(&values, &indent, &newline, &space)
209214
.into())
@@ -1071,7 +1076,7 @@ pub fn command_json_clear<M: Manager>(manager: M, ctx: &Context, args: Vec<Strin
10711076
paths
10721077
};
10731078

1074-
let path = paths.first().unwrap().fixed.as_str();
1079+
let path = paths.first().unwrap().get_path();
10751080

10761081
// FIXME: handle multi paths
10771082
let mut redis_key = manager.open_key_write(ctx, &key)?;
@@ -1080,7 +1085,7 @@ pub fn command_json_clear<M: Manager>(manager: M, ctx: &Context, args: Vec<Strin
10801085
.get_value()?
10811086
.ok_or_else(RedisError::nonexistent_key)?;
10821087

1083-
let paths = find_paths(&path, root, |_v| true)?;
1088+
let paths = find_paths(path, root, |_v| true)?;
10841089
if paths.len() > 0 {
10851090
let mut res = None;
10861091
for p in paths {

src/redisjson.rs

+27-16
Original file line numberDiff line numberDiff line change
@@ -45,31 +45,42 @@ impl Format {
4545
/// Backwards compatibility convertor for RedisJSON 1.x clients
4646
///
4747
pub struct Path {
48-
pub path: String,
49-
pub fixed: String,
50-
pub is_legacy: bool,
48+
original_path: String,
49+
fixed_path: Option<String>,
5150
}
5251

5352
impl Path {
5453
pub fn new(path: String) -> Path {
55-
let mut fixed = path.clone();
56-
let mut is_legacy = false;
57-
if !fixed.starts_with('$') {
58-
is_legacy = true;
59-
if fixed == "." {
60-
fixed.replace_range(..1, "$");
61-
} else if fixed.starts_with('.') {
62-
fixed.insert(0, '$');
54+
let fixed_path = if path.starts_with('$') {
55+
None
56+
} else {
57+
let mut cloned = path.clone();
58+
if path == "." {
59+
cloned.replace_range(..1, "$");
60+
} else if path.starts_with('.') {
61+
cloned.insert(0, '$')
6362
} else {
64-
fixed.insert_str(0, "$.");
63+
cloned.insert_str(0, "$.");
6564
}
66-
}
65+
Some(cloned)
66+
};
6767
Path {
68-
path,
69-
fixed,
70-
is_legacy,
68+
original_path: path,
69+
fixed_path,
7170
}
7271
}
72+
73+
pub fn is_legacy(&self) -> bool {
74+
self.fixed_path.is_some()
75+
}
76+
77+
pub fn get_path(&self) -> &String {
78+
self.fixed_path.as_ref().unwrap_or(&self.original_path)
79+
}
80+
81+
pub fn take_original(self) -> String {
82+
self.original_path
83+
}
7384
}
7485

7586
#[derive(Debug)]

0 commit comments

Comments
 (0)