use crate::common::{ReadExecutor, WriteExecutor};
use crate::{atomic, store::{StoreConfigProvider, StoreEventListener}, Atomic};
use std::any::Any;
use std::sync::Arc;
#[derive(Default, Clone)]
pub struct InMemoryStoreConfig {
inner: Arc<InMemoryStoreConfigInner>,
}
impl InMemoryStoreConfig {
pub fn new() -> InMemoryStoreConfig {
InMemoryStoreConfig {
inner: Arc::new(InMemoryStoreConfigInner::new()),
}
}
pub fn event_listeners(&self) -> Vec<StoreEventListener> {
self.inner.event_listeners()
}
}
impl StoreConfigProvider for InMemoryStoreConfig {
fn file_path(&self) -> String {
"".to_string()
}
fn is_read_only(&self) -> bool {
false
}
fn add_store_listener(&self, listener: StoreEventListener) {
self.inner.add_store_listener(listener)
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[derive(Default)]
struct InMemoryStoreConfigInner {
event_listeners: Atomic<Vec<StoreEventListener>>,
}
impl InMemoryStoreConfigInner {
fn new() -> InMemoryStoreConfigInner {
InMemoryStoreConfigInner {
event_listeners: atomic(Vec::new()),
}
}
fn add_store_listener(&self, listener: StoreEventListener) {
self.event_listeners.write_with(|it| it.push(listener))
}
fn event_listeners(&self) -> Vec<StoreEventListener> {
self.event_listeners.read_with(|listeners| {
let mut result = Vec::with_capacity(listeners.len());
result.extend(listeners.iter().cloned());
result
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::store::StoreEventListener;
#[test]
fn test_in_memory_store_config_new() {
let config = InMemoryStoreConfig::new();
assert!(Arc::strong_count(&config.inner) > 0);
}
#[test]
fn test_in_memory_store_config_event_listeners() {
let config = InMemoryStoreConfig::new();
assert!(config.event_listeners().is_empty());
let listener = StoreEventListener::new(|_| {Ok(())});
config.add_store_listener(listener.clone());
assert_eq!(config.event_listeners().len(), 1);
}
#[test]
fn test_in_memory_store_config_file_path() {
let config = InMemoryStoreConfig::new();
assert_eq!(config.file_path(), "");
}
#[test]
fn test_in_memory_store_config_is_read_only() {
let config = InMemoryStoreConfig::new();
assert!(!config.is_read_only());
}
#[test]
fn test_in_memory_store_config_add_store_listener() {
let config = InMemoryStoreConfig::new();
let listener = StoreEventListener::new(|_| {Ok(())});
config.add_store_listener(listener.clone());
assert_eq!(config.event_listeners().len(), 1);
}
#[test]
fn test_in_memory_store_config_inner_new() {
let inner = InMemoryStoreConfigInner::new();
assert!(inner.event_listeners().is_empty());
}
#[test]
fn test_in_memory_store_config_inner_add_store_listener() {
let inner = InMemoryStoreConfigInner::new();
let listener = StoreEventListener::new(|_| {Ok(())});
inner.add_store_listener(listener.clone());
assert_eq!(inner.event_listeners().len(), 1);
}
#[test]
fn test_in_memory_store_config_inner_event_listeners() {
let inner = InMemoryStoreConfigInner::new();
assert!(inner.event_listeners().is_empty());
let listener = StoreEventListener::new(|_| {Ok(())});
inner.add_store_listener(listener.clone());
assert_eq!(inner.event_listeners().len(), 1);
}
#[test]
fn test_event_listeners_pre_allocation_efficiency() {
let inner = InMemoryStoreConfigInner::new();
for _ in 0..10 {
let listener = StoreEventListener::new(|_| {Ok(())});
inner.add_store_listener(listener);
}
let listeners = inner.event_listeners();
assert_eq!(listeners.len(), 10);
assert_eq!(listeners.capacity(), 10);
}
#[test]
fn test_event_listeners_empty_vector_capacity() {
let inner = InMemoryStoreConfigInner::new();
let listeners = inner.event_listeners();
assert!(listeners.is_empty());
assert_eq!(listeners.capacity(), 0);
}
#[test]
fn test_event_listeners_single_listener_capacity() {
let inner = InMemoryStoreConfigInner::new();
let listener = StoreEventListener::new(|_| {Ok(())});
inner.add_store_listener(listener);
let listeners = inner.event_listeners();
assert_eq!(listeners.len(), 1);
assert_eq!(listeners.capacity(), 1);
}
#[test]
fn test_event_listeners_large_batch_efficiency() {
let inner = InMemoryStoreConfigInner::new();
for _ in 0..100 {
let listener = StoreEventListener::new(|_| {Ok(())});
inner.add_store_listener(listener);
}
let listeners = inner.event_listeners();
assert_eq!(listeners.len(), 100);
assert_eq!(listeners.capacity(), 100);
}
}