Skip to main content

v_storage/
vstorage.rs

1use v_individual_model::onto::individual::Individual;
2use crate::common::{Storage, StorageId, StorageResult, StorageDispatcher};
3
4// ========================================================================================
5// ОПТИМИЗИРОВАННАЯ ENUM-BASED ВЕРСИЯ ДЛЯ КРИТИЧНЫХ ПО ПРОИЗВОДИТЕЛЬНОСТИ СЛУЧАЕВ
6// ========================================================================================
7
8/// Enum-based хранилище для максимальной производительности
9/// 
10/// Преимущества:
11/// - Нет vtable lookups - все вызовы статически диспетчируются
12/// - Компилятор может лучше оптимизировать код
13/// - Нет heap allocations для storage
14/// - Лучшая производительность чем trait objects
15/// 
16/// Рекомендуется для:
17/// - Горячих путей в приложении
18/// - Batch операций
19/// - Высокопроизводительных сценариев
20pub enum VStorageEnum {
21    Memory(crate::memory_storage::MemoryStorage),
22    Lmdb(crate::lmdb_storage::LMDBStorage),
23    Remote(crate::remote_storage_client::StorageROClient),
24    Tarantool(crate::tt_storage::TTStorage),
25    None,
26}
27
28impl Default for VStorageEnum {
29    fn default() -> Self {
30        VStorageEnum::None
31    }
32}
33
34impl VStorageEnum {
35    /// Создает память хранилище
36    pub fn memory() -> Self {
37        VStorageEnum::Memory(crate::memory_storage::MemoryStorage::new())
38    }
39
40    /// Создает LMDB хранилище
41    pub fn lmdb(path: &str, mode: crate::common::StorageMode, max_read_counter_reopen: Option<u64>) -> Self {
42        VStorageEnum::Lmdb(crate::lmdb_storage::LMDBStorage::new(path, mode, max_read_counter_reopen))
43    }
44
45    /// Создает удаленное хранилище
46    pub fn remote(address: &str) -> Self {
47        VStorageEnum::Remote(crate::remote_storage_client::StorageROClient::new(address))
48    }
49
50    /// Создает Tarantool хранилище
51    pub fn tarantool(uri: String, login: &str, password: &str) -> Self {
52        VStorageEnum::Tarantool(crate::tt_storage::TTStorage::new(uri, login, password))
53    }
54
55    /// Проверяет, пусто ли хранилище
56    pub fn is_empty(&self) -> bool {
57        matches!(self, VStorageEnum::None)
58    }
59}
60
61impl Storage for VStorageEnum {
62    fn get_individual(&mut self, storage: StorageId, id: &str, iraw: &mut Individual) -> StorageResult<()> {
63        match self {
64            VStorageEnum::Memory(s) => s.get_individual(storage, id, iraw),
65            VStorageEnum::Lmdb(s) => s.get_individual(storage, id, iraw),
66            VStorageEnum::Remote(s) => s.get_individual(storage, id, iraw),
67            VStorageEnum::Tarantool(s) => s.get_individual(storage, id, iraw),
68            VStorageEnum::None => StorageResult::NotReady,
69        }
70    }
71
72    fn get_value(&mut self, storage: StorageId, key: &str) -> StorageResult<String> {
73        match self {
74            VStorageEnum::Memory(s) => s.get_value(storage, key),
75            VStorageEnum::Lmdb(s) => s.get_value(storage, key),
76            VStorageEnum::Remote(s) => s.get_value(storage, key),
77            VStorageEnum::Tarantool(s) => s.get_value(storage, key),
78            VStorageEnum::None => StorageResult::NotReady,
79        }
80    }
81
82    fn get_raw_value(&mut self, storage: StorageId, key: &str) -> StorageResult<Vec<u8>> {
83        match self {
84            VStorageEnum::Memory(s) => s.get_raw_value(storage, key),
85            VStorageEnum::Lmdb(s) => s.get_raw_value(storage, key),
86            VStorageEnum::Remote(s) => s.get_raw_value(storage, key),
87            VStorageEnum::Tarantool(s) => s.get_raw_value(storage, key),
88            VStorageEnum::None => StorageResult::NotReady,
89        }
90    }
91
92    fn put_value(&mut self, storage: StorageId, key: &str, val: &str) -> StorageResult<()> {
93        match self {
94            VStorageEnum::Memory(s) => s.put_value(storage, key, val),
95            VStorageEnum::Lmdb(s) => s.put_value(storage, key, val),
96            VStorageEnum::Remote(s) => s.put_value(storage, key, val),
97            VStorageEnum::Tarantool(s) => s.put_value(storage, key, val),
98            VStorageEnum::None => StorageResult::NotReady,
99        }
100    }
101
102    fn put_raw_value(&mut self, storage: StorageId, key: &str, val: Vec<u8>) -> StorageResult<()> {
103        match self {
104            VStorageEnum::Memory(s) => s.put_raw_value(storage, key, val),
105            VStorageEnum::Lmdb(s) => s.put_raw_value(storage, key, val),
106            VStorageEnum::Remote(s) => s.put_raw_value(storage, key, val),
107            VStorageEnum::Tarantool(s) => s.put_raw_value(storage, key, val),
108            VStorageEnum::None => StorageResult::NotReady,
109        }
110    }
111
112    fn remove_value(&mut self, storage: StorageId, key: &str) -> StorageResult<()> {
113        match self {
114            VStorageEnum::Memory(s) => s.remove_value(storage, key),
115            VStorageEnum::Lmdb(s) => s.remove_value(storage, key),
116            VStorageEnum::Remote(s) => s.remove_value(storage, key),
117            VStorageEnum::Tarantool(s) => s.remove_value(storage, key),
118            VStorageEnum::None => StorageResult::NotReady,
119        }
120    }
121
122    fn count(&mut self, storage: StorageId) -> StorageResult<usize> {
123        match self {
124            VStorageEnum::Memory(s) => s.count(storage),
125            VStorageEnum::Lmdb(s) => s.count(storage),
126            VStorageEnum::Remote(s) => s.count(storage),
127            VStorageEnum::Tarantool(s) => s.count(storage),
128            VStorageEnum::None => StorageResult::NotReady,
129        }
130    }
131}
132
133// ========================================================================================
134// ОСНОВНОЙ VSTORAGE - КОНТЕЙНЕР И ДИСПЕТЧЕР  
135// ========================================================================================
136
137/// Контейнер для хранилища с динамической диспетчеризацией
138/// 
139/// Ответственности:
140/// - Хранение экземпляра Storage
141/// - Диспетчеризация вызовов к хранилищу
142/// - Обработка состояния "не инициализировано"
143pub struct VStorage {
144    storage: Option<Box<dyn Storage>>,
145}
146
147impl StorageDispatcher for VStorage {
148    type Storage = Box<dyn Storage>;
149
150    fn with_storage<T, F>(&mut self, default_value: T, operation: F) -> T 
151    where 
152        F: FnOnce(&mut Self::Storage) -> T,
153    {
154        match self.storage.as_mut() {
155            Some(storage) => operation(storage),
156            None => default_value,
157        }
158    }
159}
160
161impl VStorage {
162    /// Создает пустое хранилище (не инициализированное)
163    pub fn none() -> VStorage {
164        VStorage {
165            storage: None,
166        }
167    }
168
169    /// Проверяет, пусто ли хранилище
170    pub fn is_empty(&self) -> bool {
171        self.storage.is_none()
172    }
173
174    /// Основной конструктор принимающий готовое хранилище
175    pub fn new(storage: Box<dyn Storage>) -> VStorage {
176        VStorage {
177            storage: Some(storage),
178        }
179    }
180
181    /// Получает ссылку на Builder для создания хранилищ
182    pub fn builder() -> crate::storage_factory::StorageBuilder {
183        crate::storage_factory::StorageBuilder::new()
184    }
185
186    /// Создание через конфигурацию
187    pub fn from_config(config: crate::storage_factory::StorageConfig) -> Result<VStorage, crate::storage_factory::StorageError> {
188        let storage = crate::storage_factory::DefaultStorageFactory::new()
189            .create_storage_from_config(config)?;
190        Ok(VStorage::new(storage))
191    }
192
193    // ========================================================================================
194    // ПУБЛИЧНЫЕ МЕТОДЫ API - УНИФИЦИРОВАННОЕ ИМЕНОВАНИЕ
195    // ========================================================================================
196
197    pub fn get_individual(&mut self, id: &str, iraw: &mut Individual) -> StorageResult<()> {
198        self.with_storage(StorageResult::NotReady, |s| s.get_individual(StorageId::Individuals, id, iraw))
199    }
200
201    pub fn get_individual_from_storage(&mut self, storage: StorageId, id: &str, iraw: &mut Individual) -> StorageResult<()> {
202        self.with_storage(StorageResult::NotReady, |s| s.get_individual(storage, id, iraw))
203    }
204
205    pub fn get_value(&mut self, storage: StorageId, id: &str) -> StorageResult<String> {
206        self.with_storage_value(|s| s.get_value(storage, id))
207    }
208
209    pub fn get_raw_value(&mut self, storage: StorageId, id: &str) -> StorageResult<Vec<u8>> {
210        self.with_storage_value(|s| s.get_raw_value(storage, id))
211    }
212
213    pub fn put_value(&mut self, storage: StorageId, key: &str, val: &str) -> StorageResult<()> {
214        self.with_storage_result(|s| s.put_value(storage, key, val))
215    }
216
217    pub fn put_raw_value(&mut self, storage: StorageId, key: &str, val: Vec<u8>) -> StorageResult<()> {
218        self.with_storage_result(|s| s.put_raw_value(storage, key, val))
219    }
220
221    pub fn remove_value(&mut self, storage: StorageId, key: &str) -> StorageResult<()> {
222        self.with_storage_result(|s| s.remove_value(storage, key))
223    }
224
225    pub fn count(&mut self, storage: StorageId) -> StorageResult<usize> {
226        self.with_storage_value(|s| s.count(storage))
227    }
228
229    // ========================================================================================
230    // DEPRECATED МЕТОДЫ ДЛЯ ОБРАТНОЙ СОВМЕСТИМОСТИ
231    // ========================================================================================
232
233    #[deprecated(since = "0.1.0", note = "Use get_individual_from_storage instead")]
234    pub fn get_individual_from_db(&mut self, storage: StorageId, id: &str, iraw: &mut Individual) -> StorageResult<()> {
235        self.get_individual_from_storage(storage, id, iraw)
236    }
237
238    #[deprecated(since = "0.1.0", note = "Use get_value instead")]
239    pub fn get_v(&mut self, storage: StorageId, id: &str) -> Option<String> {
240        match self.get_value(storage, id) {
241            StorageResult::Ok(value) => Some(value),
242            _ => None,
243        }
244    }
245
246    #[deprecated(since = "0.1.0", note = "Use get_raw_value instead")]
247    pub fn get_raw(&mut self, storage: StorageId, id: &str) -> Vec<u8> {
248        self.get_raw_value(storage, id).unwrap_or_default()
249    }
250
251    #[deprecated(since = "0.1.0", note = "Use put_value instead")]
252    pub fn put_kv(&mut self, storage: StorageId, key: &str, val: &str) -> bool {
253        self.put_value(storage, key, val).is_ok()
254    }
255
256    #[deprecated(since = "0.1.0", note = "Use put_raw_value instead")]
257    pub fn put_kv_raw(&mut self, storage: StorageId, key: &str, val: Vec<u8>) -> bool {
258        self.put_raw_value(storage, key, val).is_ok()
259    }
260
261    #[deprecated(since = "0.1.0", note = "Use remove_value instead")]
262    pub fn remove(&mut self, storage: StorageId, key: &str) -> bool {
263        self.remove_value(storage, key).is_ok()
264    }
265}
266
267// ========================================================================================
268// GENERIC ВЕРСИЯ - VStorageGeneric<S>
269// ========================================================================================
270
271/// Generic версия VStorage с статической диспетчеризацией
272/// 
273/// Преимущества:
274/// - Нет накладных расходов на динамическую диспетчеризацию
275/// - Нет heap allocations для storage
276/// - Лучшая производительность
277/// - Больше возможностей для оптимизации компилятором
278pub struct VStorageGeneric<S: Storage> {
279    storage: Option<S>,
280}
281
282impl<S: Storage> StorageDispatcher for VStorageGeneric<S> {
283    type Storage = S;
284
285    fn with_storage<T, F>(&mut self, default_value: T, operation: F) -> T 
286    where 
287        F: FnOnce(&mut Self::Storage) -> T,
288    {
289        match self.storage.as_mut() {
290            Some(storage) => operation(storage),
291            None => default_value,
292        }
293    }
294}
295
296impl<S: Storage> VStorageGeneric<S> {
297    /// Создает новое generic хранилище с конкретным типом
298    pub fn new(storage: S) -> Self {
299        Self {
300            storage: Some(storage),
301        }
302    }
303
304    /// Создает пустое хранилище
305    pub fn none() -> Self {
306        Self {
307            storage: None,
308        }
309    }
310
311    /// Проверяет, пусто ли хранилище
312    pub fn is_empty(&self) -> bool {
313        self.storage.is_none()
314    }
315
316    /// Берет хранилище из структуры, оставляя None
317    pub fn take_storage(mut self) -> Option<S> {
318        self.storage.take()
319    }
320
321    /// Возвращает ссылку на хранилище
322    pub fn storage(&self) -> Option<&S> {
323        self.storage.as_ref()
324    }
325
326    /// Возвращает мутабельную ссылку на хранилище
327    pub fn storage_mut(&mut self) -> Option<&mut S> {
328        self.storage.as_mut()
329    }
330
331    // ========================================================================================
332    // ПУБЛИЧНЫЕ МЕТОДЫ API - ИДЕНТИЧНЫЕ VStorage
333    // ========================================================================================
334
335    pub fn get_individual(&mut self, id: &str, iraw: &mut Individual) -> StorageResult<()> {
336        self.with_storage(StorageResult::NotReady, |s| s.get_individual(StorageId::Individuals, id, iraw))
337    }
338
339    pub fn get_individual_from_storage(&mut self, storage: StorageId, id: &str, iraw: &mut Individual) -> StorageResult<()> {
340        self.with_storage(StorageResult::NotReady, |s| s.get_individual(storage, id, iraw))
341    }
342
343    pub fn get_value(&mut self, storage: StorageId, id: &str) -> StorageResult<String> {
344        self.with_storage_value(|s| s.get_value(storage, id))
345    }
346
347    pub fn get_raw_value(&mut self, storage: StorageId, id: &str) -> StorageResult<Vec<u8>> {
348        self.with_storage_value(|s| s.get_raw_value(storage, id))
349    }
350
351    pub fn put_value(&mut self, storage: StorageId, key: &str, val: &str) -> StorageResult<()> {
352        self.with_storage_result(|s| s.put_value(storage, key, val))
353    }
354
355    pub fn put_raw_value(&mut self, storage: StorageId, key: &str, val: Vec<u8>) -> StorageResult<()> {
356        self.with_storage_result(|s| s.put_raw_value(storage, key, val))
357    }
358
359    pub fn remove_value(&mut self, storage: StorageId, key: &str) -> StorageResult<()> {
360        self.with_storage_result(|s| s.remove_value(storage, key))
361    }
362
363    pub fn count(&mut self, storage: StorageId) -> StorageResult<usize> {
364        self.with_storage_value(|s| s.count(storage))
365    }
366}
367
368// Реализация Default для случаев, когда S реализует Default
369impl<S: Storage + Default> Default for VStorageGeneric<S> {
370    fn default() -> Self {
371        Self::new(S::default())
372    }
373}
374
375// Реализация Clone для случаев, когда S реализует Clone
376impl<S: Storage + Clone> Clone for VStorageGeneric<S> {
377    fn clone(&self) -> Self {
378        Self {
379            storage: self.storage.clone(),
380        }
381    }
382}
383
384// Реализация Debug для случаев, когда S реализует Debug
385impl<S: Storage + std::fmt::Debug> std::fmt::Debug for VStorageGeneric<S> {
386    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
387        f.debug_struct("VStorageGeneric")
388            .field("storage", &self.storage)
389            .finish()
390    }
391}
392
393// ========================================================================================
394// TYPE ALIASES ДЛЯ УДОБСТВА
395// ========================================================================================
396
397pub type VMemoryStorage = VStorageGeneric<crate::memory_storage::MemoryStorage>;
398pub type VLMDBStorage = VStorageGeneric<crate::lmdb_storage::LMDBStorage>;
399pub type VRemoteStorage = VStorageGeneric<crate::remote_storage_client::StorageROClient>;
400pub type VTTStorage = VStorageGeneric<crate::tt_storage::TTStorage>;
401
402// ========================================================================================
403// ТЕСТЫ
404// ========================================================================================
405
406#[cfg(test)]
407mod tests {
408    use super::*;
409    use crate::storage_factory::StorageConfig;
410
411    #[test]
412    fn test_enum_storage_performance() {
413        let mut enum_storage = VStorageEnum::memory();
414        
415        // Test enum dispatch operations
416        assert!(enum_storage.put_value(StorageId::Individuals, "key1", "value1").is_ok());
417        let get_result = enum_storage.get_value(StorageId::Individuals, "key1");
418        assert!(get_result.is_ok(), "Expected Ok, got: {:?}", get_result);
419        if let StorageResult::Ok(value) = get_result {
420            assert_eq!(value, "value1");
421        }
422        
423        // Test count
424        let count_result = enum_storage.count(StorageId::Individuals);
425        assert!(count_result.is_ok(), "Expected Ok count, got: {:?}", count_result);
426        if let StorageResult::Ok(count) = count_result {
427            assert_eq!(count, 1);
428        }
429    }
430
431    #[test]
432    fn test_enum_storage_empty() {
433        let mut storage = VStorageEnum::default();
434        assert!(storage.is_empty());
435        
436        // Operations on empty storage should return NotReady
437        let get_result = storage.get_value(StorageId::Individuals, "key");
438        assert_eq!(get_result, StorageResult::NotReady, "Expected NotReady, got: {:?}", get_result);
439        
440        // Test other operations on empty storage
441        let put_result = storage.put_value(StorageId::Individuals, "key", "value");
442        assert_eq!(put_result, StorageResult::NotReady, "Expected NotReady for put, got: {:?}", put_result);
443        
444        let count_result = storage.count(StorageId::Individuals);
445        assert_eq!(count_result, StorageResult::NotReady, "Expected NotReady for count, got: {:?}", count_result);
446    }
447
448    #[test]
449    fn test_memory_storage_builder() {
450        let storage_result = VStorage::builder()
451            .memory()
452            .build();
453        
454        assert!(storage_result.is_ok(), "Failed to build storage");
455        if let Ok(storage_box) = storage_result {
456            let mut storage = VStorage::new(storage_box);
457
458            // Test new unified API
459            assert!(storage.put_value(StorageId::Individuals, "test_key", "test_value").is_ok());
460            let get_result = storage.get_value(StorageId::Individuals, "test_key");
461            assert!(get_result.is_ok(), "Expected Ok, got: {:?}", get_result);
462            if let StorageResult::Ok(value) = get_result {
463                assert_eq!(value, "test_value");
464            }
465        }
466    }
467
468    #[test]
469    fn test_storage_from_config() {
470        let config = StorageConfig::Memory;
471        let storage_result = VStorage::from_config(config);
472        
473        assert!(storage_result.is_ok(), "Failed to create storage from config");
474        if let Ok(mut storage) = storage_result {
475            // Test unified API
476            assert!(storage.put_value(StorageId::Individuals, "test_key", "test_value").is_ok());
477            let get_result = storage.get_value(StorageId::Individuals, "test_key");
478            assert!(get_result.is_ok(), "Expected Ok, got: {:?}", get_result);
479            if let StorageResult::Ok(value) = get_result {
480                assert_eq!(value, "test_value");
481            }
482        }
483    }
484
485    #[test]
486    fn test_empty_storage() {
487        let storage = VStorage::none();
488        assert!(storage.is_empty());
489    }
490
491    #[test]
492    fn test_individual_operations() {
493        let storage_box = VStorage::builder()
494            .memory()
495            .build()
496            .unwrap();
497        let mut storage = VStorage::new(storage_box);
498        let mut individual = Individual::default();
499
500        // Test with non-existent individual
501        assert_eq!(storage.get_individual("non-existent", &mut individual), StorageResult::NotFound);
502    }
503
504    #[test]
505    fn test_backward_compatibility() {
506        let storage_box = VStorage::builder()
507            .memory()
508            .build()
509            .unwrap();
510        let mut storage = VStorage::new(storage_box);
511
512        // Test deprecated methods still work
513        #[allow(deprecated)]
514        {
515            assert!(storage.put_kv(StorageId::Individuals, "key", "value"));
516            assert_eq!(storage.get_v(StorageId::Individuals, "key"), Some("value".to_string()));
517            assert!(storage.remove(StorageId::Individuals, "key"));
518        }
519    }
520
521    // ========================================================================================
522    // ТЕСТЫ ДЛЯ GENERIC ВЕРСИИ
523    // ========================================================================================
524
525    #[test]
526    fn test_generic_memory_storage() {
527        let mut storage = VMemoryStorage::new(crate::memory_storage::MemoryStorage::new());
528
529        // Test unified API
530        assert!(storage.put_value(StorageId::Individuals, "test_key", "test_value").is_ok());
531        let get_result = storage.get_value(StorageId::Individuals, "test_key");
532        assert!(get_result.is_ok(), "Expected Ok, got: {:?}", get_result);
533        if let StorageResult::Ok(value) = get_result {
534            assert_eq!(value, "test_value");
535        }
536        
537        // Test count
538        let count_result = storage.count(StorageId::Individuals);
539        assert!(count_result.is_ok(), "Expected Ok count, got: {:?}", count_result);
540        if let StorageResult::Ok(count) = count_result {
541            assert_eq!(count, 1);
542        }
543        
544        // Test remove
545        assert!(storage.remove_value(StorageId::Individuals, "test_key").is_ok());
546        let count_after_remove = storage.count(StorageId::Individuals);
547        assert!(count_after_remove.is_ok(), "Expected Ok count after remove, got: {:?}", count_after_remove);
548        if let StorageResult::Ok(count) = count_after_remove {
549            assert_eq!(count, 0);
550        }
551        
552        // Test edge case: remove non-existent key
553        let remove_result = storage.remove_value(StorageId::Individuals, "non-existent");
554        assert_eq!(remove_result, StorageResult::NotFound, "Expected NotFound for non-existent key");
555    }
556
557    #[test]
558    fn test_generic_storage_creation() {
559        // Создание через конструктор
560        let memory_storage = crate::memory_storage::MemoryStorage::new();
561        let mut generic_storage = VStorageGeneric::new(memory_storage);
562        
563        assert!(!generic_storage.is_empty());
564        assert!(generic_storage.put_value(StorageId::Individuals, "key", "value").is_ok());
565        
566        // Извлечение хранилища
567        let extracted = generic_storage.take_storage();
568        assert!(extracted.is_some());
569    }
570
571    #[test]
572    fn test_generic_storage_none() {
573        let storage: VStorageGeneric<crate::memory_storage::MemoryStorage> = VStorageGeneric::none();
574        assert!(storage.is_empty());
575    }
576
577    #[test]
578    fn test_generic_storage_individual_operations() {
579        let mut storage = VMemoryStorage::new(crate::memory_storage::MemoryStorage::new());
580        let mut individual = Individual::default();
581
582        // Test with non-existent individual
583        assert_eq!(storage.get_individual("non-existent", &mut individual), StorageResult::NotFound);
584    }
585
586    #[test]
587    fn test_unified_api_consistency() {
588        // Проверяем что все три типа хранилищ имеют одинаковый API
589        let mut dynamic_storage = VStorage::new(Box::new(crate::memory_storage::MemoryStorage::new()));
590        let mut generic_storage = VMemoryStorage::new(crate::memory_storage::MemoryStorage::new());
591        let mut enum_storage = VStorageEnum::memory();
592
593        // Одинаковые операции должны работать одинаково
594        assert!(dynamic_storage.put_value(StorageId::Individuals, "key", "value").is_ok());
595        assert!(generic_storage.put_value(StorageId::Individuals, "key", "value").is_ok());
596        assert!(enum_storage.put_value(StorageId::Individuals, "key", "value").is_ok());
597
598        let dynamic_result = dynamic_storage.get_value(StorageId::Individuals, "key");
599        let generic_result = generic_storage.get_value(StorageId::Individuals, "key");
600        let enum_result = enum_storage.get_value(StorageId::Individuals, "key");
601        
602        // Все результаты должны быть Ok
603        assert!(dynamic_result.is_ok(), "Dynamic storage should return Ok");
604        assert!(generic_result.is_ok(), "Generic storage should return Ok");
605        assert!(enum_result.is_ok(), "Enum storage should return Ok");
606        
607        // Все значения должны быть одинаковыми
608        if let (StorageResult::Ok(val1), StorageResult::Ok(val2), StorageResult::Ok(val3)) = 
609            (dynamic_result, generic_result, enum_result) {
610            assert_eq!(val1, val2, "Dynamic and generic storage values should match");
611            assert_eq!(val2, val3, "Generic and enum storage values should match");
612        }
613        
614        // Test count consistency
615        let count1 = dynamic_storage.count(StorageId::Individuals);
616        let count2 = generic_storage.count(StorageId::Individuals);
617        let count3 = enum_storage.count(StorageId::Individuals);
618        
619        assert!(count1.is_ok() && count2.is_ok() && count3.is_ok(), "All counts should be Ok");
620        if let (StorageResult::Ok(c1), StorageResult::Ok(c2), StorageResult::Ok(c3)) = (count1, count2, count3) {
621            assert_eq!(c1, c2);
622            assert_eq!(c2, c3);
623        }
624    }
625}