Skip to content

Commit 673e8ec

Browse files
committed
Reallocate when setting existing key
1 parent 092e276 commit 673e8ec

File tree

3 files changed

+45
-34
lines changed

3 files changed

+45
-34
lines changed

examples/data_type.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,36 @@ impl Command for AllocSetCommand {
5151
// 2. Allocate data [OK]
5252
// 3. Set the key to the data [OK]
5353
// 4. Activate custom allocator and compare Redis memory usage [OK]
54-
// 5. Handle deallocation of existing value
54+
// 5. Handle deallocation of existing value [OK]
5555

5656
let key = r.open_key_writable(key);
57-
key.check_type(&MY_TYPE)?;
58-
59-
// TODO: If there is an existing value, reuse it or deallocate it.
60-
61-
let my = Box::into_raw(Box::new(
62-
MyType {
63-
data: "A".repeat(size as usize)
57+
let key_type = key.verify_and_get_type(&MY_TYPE)?;
58+
59+
let my = match key_type {
60+
raw::KeyType::Empty => {
61+
// Create a new value
62+
Box::new(
63+
MyType {
64+
data: "A".repeat(size as usize)
65+
}
66+
)
67+
}
68+
_ => {
69+
// There is an existing value, reuse it
70+
let my = key.get_value() as *mut MyType;
71+
72+
if my.is_null() {
73+
r.reply_integer(0)?;
74+
return Ok(());
75+
}
76+
77+
let mut my = unsafe { Box::from_raw(my) };
78+
my.data = "B".repeat(size as usize);
79+
my
6480
}
65-
));
81+
};
82+
83+
let my = Box::into_raw(my);
6684

6785
key.set_value(&MY_TYPE, my as *mut c_void)?;
6886
r.reply_integer(size)?;
@@ -105,9 +123,7 @@ impl Command for AllocGetCommand {
105123
let key = args[1];
106124

107125
let key = r.open_key(key);
108-
109-
key.check_type(&MY_TYPE)?;
110-
126+
key.verify_and_get_type(&MY_TYPE)?;
111127
let my = key.get_value() as *mut MyType;
112128

113129
if my.is_null() {
@@ -179,7 +195,7 @@ pub extern "C" fn AllocDelCommand_Redis(
179195
fn module_on_load(ctx: *mut raw::RedisModuleCtx) -> Result<(), &'static str> {
180196
module_init(ctx, MODULE_NAME, MODULE_VERSION)?;
181197

182-
// TODO: Call this from inside module_init
198+
// TODO: Call this from inside module_init
183199
redismodule::use_redis_alloc();
184200

185201
MY_TYPE.create_data_type(ctx, "mytype123")?;

src/lib.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
extern crate bitflags;
55

66
pub mod redisraw;
7+
pub mod error;
78
pub mod raw;
89
pub mod types;
910

@@ -34,7 +35,6 @@ extern crate num_traits;
3435
#[macro_use]
3536
mod macros;
3637

37-
pub mod error;
3838

3939
use std::alloc::{System, GlobalAlloc, Layout};
4040
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering::SeqCst};
@@ -254,10 +254,6 @@ pub enum KeyMode {
254254
ReadWrite,
255255
}
256256

257-
trait RedisKeyType {
258-
fn check_type(&self, redis_type: &RedisType) -> Result<(), Error>;
259-
}
260-
261257
/// `RedisKey` is an abstraction over a Redis key that allows readonly
262258
/// operations.
263259
///
@@ -299,15 +295,12 @@ impl RedisKey {
299295
Ok(val)
300296
}
301297

302-
pub fn check_type(&self, redis_type: &RedisType) -> Result<(), Error> {
303-
match raw::check_key_type(
298+
pub fn verify_and_get_type(&self, redis_type: &RedisType) -> Result<raw::KeyType, Error> {
299+
raw::verify_and_get_type(
304300
self.ctx,
305301
self.key_inner,
306302
*redis_type.raw_type.borrow_mut(),
307-
) {
308-
Ok(_) => Ok(()),
309-
Err(s) => Err(Error::generic(s))
310-
}
303+
)
311304
}
312305

313306
pub fn get_value(&self) -> *mut c_void {
@@ -386,15 +379,16 @@ impl RedisKeyWritable {
386379
}
387380
}
388381

389-
pub fn check_type(&self, redis_type: &RedisType) -> Result<(), Error> {
390-
match raw::check_key_type(
382+
pub fn verify_and_get_type(&self, redis_type: &RedisType) -> Result<raw::KeyType, Error> {
383+
raw::verify_and_get_type(
391384
self.ctx,
392385
self.key_inner,
393386
*redis_type.raw_type.borrow_mut(),
394-
) {
395-
Ok(_) => Ok(()),
396-
Err(s) => Err(Error::generic(s))
397-
}
387+
)
388+
}
389+
390+
pub fn get_value(&self) -> *mut c_void {
391+
raw::module_type_get_value(self.key_inner)
398392
}
399393

400394
pub fn set_value(&self, redis_type: &RedisType, value: *mut c_void) -> Result<(), Error> {

src/raw.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use libc::size_t;
1515

1616
pub use crate::redisraw::bindings::*;
1717
use crate::types::redis_log;
18+
use crate::error::Error;
1819

1920
bitflags! {
2021
pub struct KeyMode: c_int {
@@ -332,11 +333,11 @@ pub fn module_type_set_value(
332333
}.into()
333334
}
334335

335-
pub fn check_key_type(
336+
pub fn verify_and_get_type(
336337
ctx: *mut RedisModuleCtx,
337338
key: *mut RedisModuleKey,
338339
redis_type: *mut RedisModuleType,
339-
) -> Result<(), &'static str> {
340+
) -> Result<KeyType, Error> {
340341

341342
let key_type = key_type(key);
342343

@@ -346,12 +347,12 @@ pub fn check_key_type(
346347
if key_type != KeyType::Empty {
347348
let raw_type = module_type_get_type(key);
348349
if raw_type != redis_type{
349-
return Err("Key has existing value with wrong Redis type");
350+
return Err(Error::generic("Key has existing value with wrong Redis type"));
350351
}
351352
redis_log(ctx, "Existing key has the correct type");
352353
}
353354

354355
redis_log(ctx, "All OK");
355356

356-
Ok(())
357+
Ok(key_type)
357358
}

0 commit comments

Comments
 (0)