valkey_module/defrag.rs
1use std::os::raw::c_void;
2
3use crate::{raw, Status};
4
5/// `Defrag` is a high-level rust interface to the Valkey module C API
6/// abstracting away the raw C ffi calls.
7pub struct Defrag {
8 pub defrag_ctx: *mut raw::RedisModuleDefragCtx,
9}
10
11impl Defrag {
12 pub const fn new(defrag_ctx: *mut raw::RedisModuleDefragCtx) -> Self {
13 Self { defrag_ctx }
14 }
15
16 /// # Returns a pointer to the new alloction of the data, if no defragmentation was needed a null pointer is returned
17 ///
18 /// # Panics
19 ///
20 /// Will panic if `RedisModule_DefragAlloc` is missing in redismodule.h
21 pub unsafe fn alloc(&self, ptr: *mut c_void) -> *mut c_void {
22 raw::RedisModule_DefragAlloc.unwrap()(self.defrag_ctx, ptr)
23 }
24
25 /// # Sets a cursor on the last item defragged so that on the next defrag cycle, the Module can resume from that position using `get_cursor`.
26 /// # Should only be called if `should_stop_defrag` has returned `true` and the defrag callback is about to exit without fully iterating its data type.
27 ///
28 /// # Panics
29 ///
30 /// Will panic if `RedisModule_DefragCursorSet` is missing in redismodule.h
31 pub unsafe fn set_cursor(&self, cursor: u64) -> Status {
32 let status = raw::RedisModule_DefragCursorSet.unwrap()(self.defrag_ctx, cursor);
33 if status as isize == raw::REDISMODULE_OK {
34 Status::Ok
35 } else {
36 Status::Err
37 }
38 }
39
40 /// # Returns the cursor value that has been previously stored using `set_cursor`
41 ///
42 /// # Panics
43 ///
44 /// Will panic if `RedisModule_DefragCursorGet` is missing in redismodule.h
45 pub unsafe fn get_cursor(&self) -> Option<u64> {
46 let mut cursor: u64 = 0;
47 let status = raw::RedisModule_DefragCursorGet.unwrap()(self.defrag_ctx, &mut cursor);
48 if status as isize == raw::REDISMODULE_OK {
49 Some(cursor)
50 } else {
51 None
52 }
53 }
54
55 /// # Returns true if the engine has been defragging for too long and the Module should need to stop.
56 /// # Returns false otherwise for the Module to know it can continue its work.
57 ///
58 /// # Panics
59 ///
60 /// Will panic if `RedisModule_DefragShouldStop` is missing in redismodule.h
61 pub unsafe fn should_stop_defrag(&self) -> bool {
62 raw::RedisModule_DefragShouldStop.unwrap()(self.defrag_ctx) != 0
63 }
64
65 /// # Returns the name of the key being processed.
66 /// # If the key name isn't available this will return NULL instead
67 ///
68 /// # Panics
69 ///
70 /// Will panic if `RedisModule_GetKeyNameFromDefragCtx` is missing in redismodule.h
71 pub unsafe fn get_key_name_from_defrag_context(&self) -> *const raw::RedisModuleString {
72 raw::RedisModule_GetKeyNameFromDefragCtx.unwrap()(self.defrag_ctx)
73 }
74
75 /// # Returns the database id of the key that is currently being defragged.
76 /// # If this information isn't available it will return -1
77 ///
78 /// # Panics
79 ///
80 /// Will panic if `RedisModule_GetDbIdFromDefragCtx` is missing in redismodule.h
81 pub unsafe fn get_db_id_from_defrag_context(&self) -> i32 {
82 raw::RedisModule_GetDbIdFromDefragCtx.unwrap()(self.defrag_ctx)
83 }
84}