1+ use std:: os:: raw:: c_void;
2+
13extern crate libc;
24
35use libc:: c_int;
@@ -9,12 +11,17 @@ use redismodule::Command;
911use redismodule:: raw;
1012use redismodule:: Redis ;
1113use redismodule:: raw:: module_init;
12- use redismodule:: types:: RedisModuleType ;
14+ use redismodule:: types:: RedisType ;
1315
1416const MODULE_NAME : & str = "alloc" ;
1517const MODULE_VERSION : c_int = 1 ;
1618
17- static MY_TYPE : RedisModuleType = RedisModuleType :: new ( ) ;
19+ #[ allow( unused) ]
20+ struct MyType {
21+ data : String ,
22+ }
23+
24+ static MY_TYPE : RedisType = RedisType :: new ( ) ;
1825
1926struct AllocSetCommand ;
2027
@@ -40,26 +47,21 @@ impl Command for AllocSetCommand {
4047 let size = parse_i64 ( args[ 2 ] ) ?;
4148
4249 // TODO:
43- // 1. Open key
44- // 2. Allocate data
45- // 3. Set the key to the data
50+ // 1. Open key [OK]
51+ // 2. Allocate data [OK]
52+ // 3. Set the key to the data [OK]
4653 // 4. Activate custom allocator and compare Redis memory usage
4754
48- //let data: Vec<u8> = Vec::with_capacity(size as usize);
49-
5055 let key = r. open_key_writable ( key) ;
56+ key. check_type ( & MY_TYPE ) ?;
5157
52- //key.check_type(MY_TYPE)?;
53- key. write ( size. to_string ( ) . as_str ( ) ) ?;
54-
55- /*
56- raw::RedisModule_ModuleTypeSetValue.unwrap()(
57- k,
58- t,
59- data,
60- );
61- */
58+ let my = Box :: into_raw ( Box :: new (
59+ MyType {
60+ data : "A" . repeat ( size as usize )
61+ }
62+ ) ) ;
6263
64+ key. set_value ( & MY_TYPE , my as * mut c_void ) ?;
6365 r. reply_integer ( size) ?;
6466
6567 Ok ( ( ) )
@@ -77,6 +79,61 @@ pub extern "C" fn AllocSetCommand_Redis(
7779
7880//////////////////////////////////////////////////////
7981
82+ struct AllocGetCommand ;
83+
84+ impl Command for AllocGetCommand {
85+ fn name ( ) -> & ' static str { "alloc.get" }
86+
87+ fn external_command ( ) -> raw:: CommandFunc { AllocGetCommand_Redis }
88+
89+ fn str_flags ( ) -> & ' static str { "" }
90+
91+ // Run the command.
92+ fn run ( r : Redis , args : & [ & str ] ) -> Result < ( ) , Error > {
93+ if args. len ( ) != 2 {
94+ // FIXME: Use RedisModule_WrongArity instead. Return an ArityError here and
95+ // in the low-level implementation call RM_WrongArity.
96+ return Err ( Error :: generic ( format ! (
97+ "Usage: {} <key>" , Self :: name( )
98+ ) . as_str ( ) ) ) ;
99+ }
100+
101+ // the first argument is command name (ignore it)
102+ let key = args[ 1 ] ;
103+
104+ let key = r. open_key ( key) ;
105+
106+ key. check_type ( & MY_TYPE ) ?;
107+
108+ let my = key. get_value ( ) as * mut MyType ;
109+
110+ if my. is_null ( ) {
111+ r. reply_integer ( 0 ) ?;
112+ return Ok ( ( ) ) ;
113+ }
114+
115+ let my = unsafe { & mut * my } ;
116+ let size = my. data . len ( ) ;
117+
118+ r. reply_array ( 2 ) ?;
119+ r. reply_integer ( size as i64 ) ?;
120+ r. reply_string ( my. data . as_str ( ) ) ?;
121+
122+ Ok ( ( ) )
123+ }
124+ }
125+
126+ #[ allow( non_snake_case) ]
127+ pub extern "C" fn AllocGetCommand_Redis (
128+ ctx : * mut raw:: RedisModuleCtx ,
129+ argv : * mut * mut raw:: RedisModuleString ,
130+ argc : c_int ,
131+ ) -> c_int {
132+ AllocGetCommand :: execute ( ctx, argv, argc) . into ( )
133+ }
134+
135+ //////////////////////////////////////////////////////
136+
80137struct AllocDelCommand ;
81138
82139impl Command for AllocDelCommand {
@@ -96,7 +153,7 @@ impl Command for AllocDelCommand {
96153 }
97154
98155 // the first argument is command name (ignore it)
99- let key = args[ 1 ] ;
156+ let _key = args[ 1 ] ;
100157
101158 r. reply_string ( "OK" ) ?;
102159
@@ -122,6 +179,7 @@ fn module_on_load(ctx: *mut raw::RedisModuleCtx) -> Result<(), &'static str> {
122179 MY_TYPE . create_data_type ( ctx, "mytype123" ) ?;
123180
124181 AllocSetCommand :: create ( ctx) ?;
182+ AllocGetCommand :: create ( ctx) ?;
125183 AllocDelCommand :: create ( ctx) ?;
126184
127185 Ok ( ( ) )
0 commit comments