use crate::concurrent::atomic_buffer::AtomicBuffer;
use crate::concurrent::counters::CountersReader;
use crate::utils::types::{Index, I64_SIZE};
pub const CHANNEL_ENDPOINT_INITIALIZING: i64 = 0;
pub const CHANNEL_ENDPOINT_ERRORED: i64 = -1;
pub const CHANNEL_ENDPOINT_ACTIVE: i64 = 1;
pub const CHANNEL_ENDPOINT_CLOSING: i64 = 2;
pub const NO_ID_ALLOCATED: i32 = -1;
static mut STATIC_BUFFER_SLICE: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
#[repr(align(64))]
struct AlignedBufferSlice([u8; 8]);
static mut STATIC_ALIGNED_BUFFER_SLICE: AlignedBufferSlice = unsafe { AlignedBufferSlice(STATIC_BUFFER_SLICE) };
pub fn channel_status_to_str(status_id: i64) -> String {
match status_id {
CHANNEL_ENDPOINT_INITIALIZING => String::from("Initializing"),
CHANNEL_ENDPOINT_ERRORED => String::from("Errored"),
CHANNEL_ENDPOINT_ACTIVE => String::from("Active"),
CHANNEL_ENDPOINT_CLOSING => String::from("Closing"),
_ => String::from("Unknown"),
}
}
fn static_buffer() -> AtomicBuffer {
let buffer = unsafe {
assert_eq!(STATIC_ALIGNED_BUFFER_SLICE.0.len(), I64_SIZE as usize);
AtomicBuffer::wrap_slice(&mut STATIC_ALIGNED_BUFFER_SLICE.0)
};
buffer.put_ordered(0, CHANNEL_ENDPOINT_ACTIVE);
buffer
}
#[derive(Debug)]
pub struct StatusIndicatorReader {
buffer: AtomicBuffer,
id: i32,
offset: Index,
}
impl StatusIndicatorReader {
pub fn new(input_buffer: AtomicBuffer, id: i32) -> Self {
if NO_ID_ALLOCATED == id {
Self {
buffer: AtomicBuffer::wrap(static_buffer()),
id,
offset: 0,
}
} else {
let offset = CountersReader::counter_offset(id);
Self {
buffer: AtomicBuffer::wrap(input_buffer),
id,
offset,
}
}
}
pub fn id(&self) -> i32 {
self.id
}
pub fn volatile(&self) -> i64 {
self.buffer.get_volatile::<i64>(self.offset)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::concurrent::atomic_buffer::AlignedBuffer;
#[test]
fn test() {
let buffer = AlignedBuffer::with_capacity(65536);
let atomic_buffer = AtomicBuffer::from_aligned(&buffer);
let reader = StatusIndicatorReader::new(atomic_buffer, 239);
let counters_reader = CountersReader::counter_offset(239);
assert_eq!(reader.id(), 239);
assert_eq!(reader.offset, counters_reader);
assert_eq!(reader.volatile(), reader.buffer.get_volatile::<i64>(counters_reader));
}
#[test]
fn test_id_not_allocated() {
let buffer = AlignedBuffer::with_capacity(1024);
let atomic_buffer = AtomicBuffer::from_aligned(&buffer);
let reader = StatusIndicatorReader::new(atomic_buffer, NO_ID_ALLOCATED);
assert_eq!(reader.id(), NO_ID_ALLOCATED);
assert_eq!(reader.volatile(), reader.buffer.get_volatile::<i64>(reader.offset));
assert_eq!(reader.buffer.as_slice(), &[1, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(reader.buffer.as_slice(), static_buffer().as_slice());
}
}