-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added API to read and trim a stream. (#266)
* Added API to read and trim a stream. * fix command flags * Apply suggestions from code review Co-authored-by: Guy Korland <[email protected]> * Format fixes * Fix complition. * Format fixes * Added reverse option. Co-authored-by: Guy Korland <[email protected]>
- Loading branch information
1 parent
dbc7883
commit cc05327
Showing
6 changed files
with
226 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#[macro_use] | ||
extern crate redis_module; | ||
|
||
use redis_module::raw::{KeyType, RedisModuleStreamID}; | ||
use redis_module::{Context, NextArg, RedisError, RedisResult, RedisString, RedisValue}; | ||
|
||
fn stream_read_from(ctx: &Context, args: Vec<RedisString>) -> RedisResult { | ||
let mut args = args.into_iter().skip(1); | ||
|
||
let stream_key = args.next_arg()?; | ||
|
||
let stream = ctx.open_key(&stream_key); | ||
let key_type = stream.key_type(); | ||
|
||
if key_type != KeyType::Stream { | ||
return Err(RedisError::WrongType); | ||
} | ||
|
||
let mut iter = stream.get_stream_iterator(false)?; | ||
let element = iter.next(); | ||
let id_to_keep = iter.next().as_ref().map_or_else( | ||
|| RedisModuleStreamID { | ||
ms: u64::MAX, | ||
seq: u64::MAX, | ||
}, | ||
|e| e.id, | ||
); | ||
|
||
let stream = ctx.open_key_writable(&stream_key); | ||
stream.trim_stream_by_id(id_to_keep, false)?; | ||
Ok(match element { | ||
Some(e) => RedisValue::BulkString(format!("{}-{}", e.id.ms, e.id.seq)), | ||
None => RedisValue::Null, | ||
}) | ||
} | ||
|
||
////////////////////////////////////////////////////// | ||
|
||
redis_module! { | ||
name: "stream", | ||
version: 1, | ||
data_types: [], | ||
commands: [ | ||
["STREAM_POP", stream_read_from, "write", 1, 1, 1], | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use crate::key::RedisKey; | ||
use crate::raw; | ||
use crate::RedisError; | ||
use crate::RedisString; | ||
use crate::Status; | ||
use std::os::raw::c_long; | ||
use std::ptr; | ||
|
||
pub struct StreamRecord { | ||
pub id: raw::RedisModuleStreamID, | ||
pub fields: Vec<(RedisString, RedisString)>, | ||
} | ||
|
||
pub struct StreamIterator<'key> { | ||
key: &'key RedisKey, | ||
} | ||
|
||
impl<'key> StreamIterator<'key> { | ||
pub(crate) fn new( | ||
key: &RedisKey, | ||
mut from: Option<raw::RedisModuleStreamID>, | ||
mut to: Option<raw::RedisModuleStreamID>, | ||
exclusive: bool, | ||
reverse: bool, | ||
) -> Result<StreamIterator, RedisError> { | ||
let mut flags = if exclusive { | ||
raw::REDISMODULE_STREAM_ITERATOR_EXCLUSIVE as i32 | ||
} else { | ||
0 | ||
}; | ||
|
||
flags |= if reverse { | ||
raw::REDISMODULE_STREAM_ITERATOR_REVERSE as i32 | ||
} else { | ||
0 | ||
}; | ||
|
||
let res = unsafe { | ||
raw::RedisModule_StreamIteratorStart.unwrap()( | ||
key.key_inner, | ||
flags, | ||
from.as_mut().map_or(ptr::null_mut(), |v| v), | ||
to.as_mut().map_or(ptr::null_mut(), |v| v), | ||
) | ||
}; | ||
if Status::Ok == res.into() { | ||
Ok(StreamIterator { key }) | ||
} else { | ||
Err(RedisError::Str("Failed creating stream iterator")) | ||
} | ||
} | ||
} | ||
|
||
impl<'key> Iterator for StreamIterator<'key> { | ||
type Item = StreamRecord; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
let mut id = raw::RedisModuleStreamID { ms: 0, seq: 0 }; | ||
let mut num_fields: c_long = 0; | ||
let mut field_name: *mut raw::RedisModuleString = ptr::null_mut(); | ||
let mut field_val: *mut raw::RedisModuleString = ptr::null_mut(); | ||
if Status::Ok | ||
!= unsafe { | ||
raw::RedisModule_StreamIteratorNextID.unwrap()( | ||
self.key.key_inner, | ||
&mut id, | ||
&mut num_fields, | ||
) | ||
} | ||
.into() | ||
{ | ||
return None; | ||
} | ||
let mut fields = Vec::new(); | ||
while Status::Ok | ||
== unsafe { | ||
raw::RedisModule_StreamIteratorNextField.unwrap()( | ||
self.key.key_inner, | ||
&mut field_name, | ||
&mut field_val, | ||
) | ||
.into() | ||
} | ||
{ | ||
fields.push(( | ||
RedisString::from_redis_module_string(self.key.ctx, field_name), | ||
RedisString::from_redis_module_string(self.key.ctx, field_val), | ||
)); | ||
} | ||
Some(StreamRecord { id, fields }) | ||
} | ||
} | ||
|
||
impl<'key> Drop for StreamIterator<'key> { | ||
fn drop(&mut self) { | ||
unsafe { raw::RedisModule_StreamIteratorDelete.unwrap()(self.key.key_inner) }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters