use crate::error::*;
use pravega_client_shared::{Segment, SegmentWithRange};
use serde::{Deserialize, Serialize};
use serde_cbor::from_slice;
use serde_cbor::to_vec;
use snafu::ResultExt;
use std::collections::HashMap;
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub(crate) enum PositionVersioned {
V1(PositionV1),
}
impl PositionVersioned {
fn to_bytes(&self) -> Result<Vec<u8>, SerdeError> {
let encoded = to_vec(&self).context(Cbor {
msg: "serialize PositionVersioned".to_owned(),
})?;
Ok(encoded)
}
fn from_bytes(input: &[u8]) -> Result<PositionVersioned, SerdeError> {
let decoded: PositionVersioned = from_slice(&input[..]).context(Cbor {
msg: "serialize PositionVersioned".to_owned(),
})?;
Ok(decoded)
}
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub(crate) struct PositionV1 {
owned_segments: HashMap<Segment, i64>,
segment_ranges: HashMap<Segment, SegmentWithRange>,
}
impl PositionV1 {
pub(crate) fn new(segments: HashMap<SegmentWithRange, i64>) -> Self {
let mut owned_segments = HashMap::with_capacity(segments.len());
let mut segment_ranges = HashMap::with_capacity(segments.len());
for (k, v) in segments {
owned_segments.insert(k.get_segment(), v);
segment_ranges.insert(k.get_segment(), k);
}
PositionV1 {
owned_segments,
segment_ranges,
}
}
pub(crate) fn get_owned_segments_with_offsets(&self) -> HashMap<Segment, i64> {
self.owned_segments.to_owned()
}
}
#[cfg(test)]
mod tests {
use super::*;
use ordered_float::OrderedFloat;
use pravega_client_shared::{Scope, ScopedSegment, Stream};
#[test]
fn test_position_serde() {
let mut segments = HashMap::new();
let segment_with_range = SegmentWithRange {
scoped_segment: ScopedSegment {
scope: Scope {
name: "test".to_string(),
},
stream: Stream {
name: "test".to_string(),
},
segment: Segment {
number: 0,
tx_id: None,
},
},
min_key: OrderedFloat::from(0.0),
max_key: OrderedFloat::from(1.0),
};
segments.insert(segment_with_range, 0);
let v1 = PositionV1::new(segments);
let position = PositionVersioned::V1(v1.clone());
let encoded = position.to_bytes().expect("encode to byte array");
let decoded = PositionVersioned::from_bytes(&encoded).expect("decode from byte array");
assert_eq!(PositionVersioned::V1(v1), decoded);
}
}