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}