1#![allow(non_snake_case)]
19
20use std::sync::{Arc, RwLock};
88use std::collections::HashMap;
89use std::time::Duration;
90use serde::{Serialize, Deserialize};
91
92use super::core::{DMSCDevice, DMSCDeviceType, DMSCDeviceStatus};
93
94
95#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
101pub struct DMSCResourcePool {
102 name: String,
104 device_type: DMSCDeviceType,
106 devices: HashMap<String, Arc<DMSCDevice>>,
108 total_capacity: usize,
110 available_capacity: usize,
112 allocated_capacity: usize,
114 pending_requests: usize,
116 total_compute_units: usize,
118 total_memory_gb: f64,
120 total_storage_gb: f64,
122 total_bandwidth_gbps: f64,
124 available_compute_units: usize,
126 available_memory_gb: f64,
128 available_storage_gb: f64,
130 available_bandwidth_gbps: f64,
132 connection_pool: Arc<RwLock<DMSCConnectionPool>>,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
141#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass(get_all, set_all))]
142pub struct DMSCResourcePoolConfig {
143 pub name: String,
145 pub device_type: DMSCDeviceType,
147 pub max_concurrent_allocations: usize,
149 pub allocation_timeout_secs: u64,
151 pub health_check_interval_secs: u64,
153}
154
155impl Default for DMSCResourcePoolConfig {
156 fn default() -> Self {
157 Self {
158 name: "default_pool".to_string(),
159 device_type: DMSCDeviceType::CPU,
160 max_concurrent_allocations: 10,
161 allocation_timeout_secs: 60,
162 health_check_interval_secs: 30,
163 }
164 }
165}
166
167impl DMSCResourcePool {
168 pub fn new(config: DMSCResourcePoolConfig) -> Self {
178 let connection_pool = Arc::new(RwLock::new(DMSCConnectionPool::new(
179 config.max_concurrent_allocations,
180 Duration::from_secs(config.allocation_timeout_secs),
181 Duration::from_secs(config.health_check_interval_secs),
182 )));
183
184 Self {
185 name: config.name,
186 device_type: config.device_type,
187 devices: HashMap::with_capacity(16),
188 total_capacity: 0,
189 available_capacity: 0,
190 allocated_capacity: 0,
191 pending_requests: 0,
192 total_compute_units: 0,
193 total_memory_gb: 0.0,
194 total_storage_gb: 0.0,
195 total_bandwidth_gbps: 0.0,
196 available_compute_units: 0,
197 available_memory_gb: 0.0,
198 available_storage_gb: 0.0,
199 available_bandwidth_gbps: 0.0,
200 connection_pool,
201 }
202 }
203
204 pub fn add_device(&mut self, device: Arc<DMSCDevice>) -> bool {
217 if device.device_type() != self.device_type {
219 return false;
220 }
221
222 let device_id = device.id().to_string();
223 if self.devices.contains_key(&device_id) {
225 return false;
226 }
227
228 let compute_units = device.capabilities().compute_units.unwrap_or(0);
230 let memory_gb = device.capabilities().memory_gb.unwrap_or(0.0);
231 let storage_gb = device.capabilities().storage_gb.unwrap_or(0.0);
232 let bandwidth_gbps = device.capabilities().bandwidth_gbps.unwrap_or(0.0);
233
234 self.devices.insert(device_id, device);
236
237 self.total_capacity += 1;
239 self.available_capacity += 1;
240
241 self.total_compute_units += compute_units;
243 self.total_memory_gb += memory_gb;
244 self.total_storage_gb += storage_gb;
245 self.total_bandwidth_gbps += bandwidth_gbps;
246
247 self.available_compute_units += compute_units;
249 self.available_memory_gb += memory_gb;
250 self.available_storage_gb += storage_gb;
251 self.available_bandwidth_gbps += bandwidth_gbps;
252
253 true
254 }
255
256 pub fn remove_device(&mut self, device_id: &str) -> bool {
269 if let Some(device) = self.devices.remove(device_id) {
270 let capabilities = device.capabilities();
272
273 self.total_capacity -= 1;
275
276 if device.is_available() {
278 self.available_capacity -= 1;
279
280 self.available_compute_units -= capabilities.compute_units.unwrap_or(0);
282 self.available_memory_gb -= capabilities.memory_gb.unwrap_or(0.0);
283 self.available_storage_gb -= capabilities.storage_gb.unwrap_or(0.0);
284 self.available_bandwidth_gbps -= capabilities.bandwidth_gbps.unwrap_or(0.0);
285 } else if device.is_allocated() {
286 self.allocated_capacity -= 1;
287
288 }
291
292 self.total_compute_units -= capabilities.compute_units.unwrap_or(0);
294 self.total_memory_gb -= capabilities.memory_gb.unwrap_or(0.0);
295 self.total_storage_gb -= capabilities.storage_gb.unwrap_or(0.0);
296 self.total_bandwidth_gbps -= capabilities.bandwidth_gbps.unwrap_or(0.0);
297
298 true
299 } else {
300 false
301 }
302 }
303
304 pub fn allocate(&mut self, _allocation_id: &str) -> Option<Arc<DMSCDevice>> {
316 if self.available_capacity == 0 {
318 return None;
319 }
320
321 for device in self.devices.values() {
323 if device.is_available() {
326 let capabilities = device.capabilities();
328
329 self.available_capacity -= 1;
332 self.allocated_capacity += 1;
333
334 self.available_compute_units -= capabilities.compute_units.unwrap_or(0);
336 self.available_memory_gb -= capabilities.memory_gb.unwrap_or(0.0);
337 self.available_storage_gb -= capabilities.storage_gb.unwrap_or(0.0);
338 self.available_bandwidth_gbps -= capabilities.bandwidth_gbps.unwrap_or(0.0);
339
340 let mut pool = match self.connection_pool.write() {
342 Ok(pool) => pool,
343 Err(e) => {
344 log::error!("Failed to acquire connection pool lock: {}", e);
345 return None;
346 }
347 };
348 pool.add_connection(device.id().to_string(), device.id().to_string());
349
350 return Some(device.clone());
351 }
352 }
353
354 None
355 }
356
357 pub fn release(&mut self, allocation_id: &str) -> bool {
369 for device in self.devices.values() {
371 if let Some(current_allocation) = device.get_allocation_id() {
372 if current_allocation == allocation_id {
373 let capabilities = device.capabilities();
375
376 self.allocated_capacity -= 1;
379 self.available_capacity += 1;
380
381 self.available_compute_units += capabilities.compute_units.unwrap_or(0);
383 self.available_memory_gb += capabilities.memory_gb.unwrap_or(0.0);
384 self.available_storage_gb += capabilities.storage_gb.unwrap_or(0.0);
385 self.available_bandwidth_gbps += capabilities.bandwidth_gbps.unwrap_or(0.0);
386
387 match self.connection_pool.write() {
389 Ok(mut pool) => {
390 pool.remove_connection(device.id());
391 }
392 Err(e) => {
393 log::error!("Failed to acquire connection pool lock for removal: {}", e);
394 }
396 }
397
398 return true;
399 }
400 }
401 }
402
403 false
404 }
405
406 pub fn get_status(&self) -> super::DMSCResourcePoolStatus {
415 super::DMSCResourcePoolStatus {
416 total_capacity: self.total_capacity,
417 available_capacity: self.available_capacity,
418 allocated_capacity: self.allocated_capacity,
419 pending_requests: self.pending_requests,
420 utilization_rate: if self.total_capacity > 0 {
421 (self.allocated_capacity as f64 / self.total_capacity as f64) * 100.0
422 } else {
423 0.0
424 },
425 }
426 }
427
428 #[inline]
434 pub fn name(&self) -> &str {
435 &self.name
436 }
437
438 #[inline]
444 pub fn device_type(&self) -> DMSCDeviceType {
445 self.device_type
446 }
447
448 #[inline]
454 pub fn get_devices(&self) -> Vec<Arc<DMSCDevice>> {
455 self.devices.values().cloned().collect()
456 }
457
458 pub fn get_available_devices(&self) -> Vec<Arc<DMSCDevice>> {
464 self.devices.values()
465 .filter(|device| device.is_available())
466 .cloned()
467 .collect()
468 }
469
470 pub fn get_allocated_devices(&self) -> Vec<Arc<DMSCDevice>> {
476 self.devices.values()
477 .filter(|device| device.is_allocated())
478 .cloned()
479 .collect()
480 }
481
482 #[inline]
488 pub fn has_available_capacity(&self) -> bool {
489 self.available_capacity > 0
490 }
491
492 #[inline]
498 pub fn utilization_rate(&self) -> f64 {
499 if self.total_capacity > 0 {
500 self.allocated_capacity as f64 / self.total_capacity as f64
501 } else {
502 0.0
503 }
504 }
505
506 pub fn is_healthy(&self) -> bool {
514 self.available_capacity > 0 || self.allocated_capacity > 0
515 }
516
517 pub fn get_statistics(&self) -> DMSCResourcePoolStatistics {
526 let devices = self.get_devices();
527 let available_devices = self.get_available_devices();
528 let allocated_devices = self.get_allocated_devices();
529
530 let total_compute_units: usize = devices.iter()
532 .filter_map(|d| d.capabilities().compute_units)
533 .sum();
534
535 let total_memory_gb: f64 = devices.iter()
537 .filter_map(|d| d.capabilities().memory_gb)
538 .sum();
539
540 let total_storage_gb: f64 = devices.iter()
542 .filter_map(|d| d.capabilities().storage_gb)
543 .sum();
544
545 let total_bandwidth_gbps: f64 = devices.iter()
547 .filter_map(|d| d.capabilities().bandwidth_gbps)
548 .sum();
549
550 let average_health_score: f64 = if !devices.is_empty() {
552 devices.iter()
553 .map(|d| d.health_score() as f64)
554 .sum::<f64>() / devices.len() as f64
555 } else {
556 0.0
557 };
558
559 let connection_pool_stats = match self.connection_pool.read() {
561 Ok(pool) => Some(pool.get_statistics()),
562 Err(e) => {
563 log::error!("Failed to acquire connection pool read lock: {}", e);
564 None
565 }
566 };
567
568 let mut status_distribution = HashMap::with_capacity(4);
570 for device in &devices {
571 *status_distribution.entry(device.status()).or_insert(0) += 1;
572 }
573
574 let mut total_response_time_ms = 0.0;
576 let mut total_network_latency_ms = 0.0;
577 let mut total_disk_iops = 0.0;
578 let mut total_battery_level_percent = 0.0;
579 let mut total_cpu_usage_percent = 0.0;
580 let mut total_memory_usage_percent = 0.0;
581 let mut total_temperature_celsius = 0.0;
582 let mut total_error_count = 0u32;
583 let mut total_throughput = 0.0;
584 let mut total_uptime_seconds = 0.0;
585
586 for device in &devices {
587 let health_metrics = device.health_metrics();
588 total_response_time_ms += health_metrics.response_time_ms;
589 total_network_latency_ms += health_metrics.network_latency_ms;
590 total_disk_iops += health_metrics.disk_iops as f64;
591 total_battery_level_percent += health_metrics.battery_level_percent;
592 total_cpu_usage_percent += health_metrics.cpu_usage_percent;
593 total_memory_usage_percent += health_metrics.memory_usage_percent;
594 total_temperature_celsius += health_metrics.temperature_celsius;
595 total_error_count += health_metrics.error_count;
596 total_throughput += health_metrics.throughput as f64;
597 total_uptime_seconds += health_metrics.uptime_seconds as f64;
598 }
599
600 let device_count = devices.len() as f64;
601
602 DMSCResourcePoolStatistics {
603 total_devices: devices.len(),
604 available_devices: available_devices.len(),
605 allocated_devices: allocated_devices.len(),
606 utilization_rate: self.utilization_rate(),
607 total_compute_units,
608 total_memory_gb,
609 total_storage_gb,
610 total_bandwidth_gbps,
611 average_health_score,
612 device_type: self.device_type,
613 connection_pool_stats,
614
615 status_distribution,
616 average_response_time_ms: if device_count > 0.0 { total_response_time_ms / device_count } else { 0.0 },
617 average_network_latency_ms: if device_count > 0.0 { total_network_latency_ms / device_count } else { 0.0 },
618 average_disk_iops: if device_count > 0.0 { total_disk_iops / device_count } else { 0.0 },
619 average_battery_level_percent: if device_count > 0.0 { total_battery_level_percent / device_count } else { 0.0 },
620 average_cpu_usage_percent: if device_count > 0.0 { total_cpu_usage_percent / device_count } else { 0.0 },
621 average_memory_usage_percent: if device_count > 0.0 { total_memory_usage_percent / device_count } else { 0.0 },
622 average_temperature_celsius: if device_count > 0.0 { total_temperature_celsius / device_count } else { 0.0 },
623 total_error_count,
624 average_throughput: if device_count > 0.0 { total_throughput / device_count } else { 0.0 },
625 average_uptime_seconds: if device_count > 0.0 { total_uptime_seconds / device_count } else { 0.0 },
626 }
627 }
628}
629
630#[derive(Debug, Clone)]
632#[allow(dead_code)]
633pub struct DMSCConnectionPool {
634 connections: HashMap<String, DMSCConnectionInfo>,
636 max_connections: usize,
638 connection_timeout: Duration,
640 health_check_interval: Duration,
642 last_health_check_secs: u64,
644 pub active_connections: usize,
646 pub failed_connections: usize,
648 pub total_errors: usize,
650}
651
652#[derive(Debug, Clone, Serialize, Deserialize)]
654pub struct DMSCConnectionInfo {
655 pub connection_id: String,
657 pub device_id: String,
659 pub address: String,
661 pub established_at_secs: u64,
663 pub last_activity_secs: u64,
665 pub state: DMSCConnectionState,
667 pub health_metrics: DMSCConnectionHealthMetrics,
669}
670
671#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
673pub enum DMSCConnectionState {
674 Connecting,
676 Active,
678 Idle,
680 Unhealthy,
682 Closing,
684 Closed,
686}
687
688#[derive(Debug, Clone, Default, Serialize, Deserialize)]
690pub struct DMSCConnectionHealthMetrics {
691 pub successful_operations: u64,
693 pub failed_operations: u64,
695 pub average_response_time_ms: f64,
697 pub last_error_secs: Option<u64>,
699 pub uptime_percentage: f64,
701}
702
703#[allow(dead_code)]
704impl DMSCConnectionPool {
705 pub fn new(max_connections: usize, connection_timeout: Duration, health_check_interval: Duration) -> Self {
707 Self {
708 connections: HashMap::with_capacity(max_connections),
709 max_connections,
710 connection_timeout,
711 health_check_interval,
712 last_health_check_secs: std::time::SystemTime::now()
713 .duration_since(std::time::UNIX_EPOCH)
714 .unwrap_or(Duration::from_secs(0))
715 .as_secs(),
716 active_connections: 0,
717 failed_connections: 0,
718 total_errors: 0,
719 }
720 }
721
722 pub fn add_connection(&mut self, device_id: String, address: String) {
724 let connection_info = DMSCConnectionInfo {
725 connection_id: device_id.clone(),
726 device_id: device_id.clone(),
727 address,
728 established_at_secs: std::time::SystemTime::now()
729 .duration_since(std::time::UNIX_EPOCH)
730 .unwrap_or_default()
731 .as_secs(),
732 last_activity_secs: std::time::SystemTime::now()
733 .duration_since(std::time::UNIX_EPOCH)
734 .unwrap_or_default()
735 .as_secs(),
736 state: DMSCConnectionState::Active,
737 health_metrics: DMSCConnectionHealthMetrics::default(),
738 };
739
740 self.connections.insert(device_id, connection_info);
741 self.active_connections += 1;
742 }
743
744 pub fn remove_connection(&mut self, connection_id: &str) -> bool {
746 self.connections.remove(connection_id).is_some()
747 }
748
749 pub fn get_connection(&self, connection_id: &str) -> Option<&DMSCConnectionInfo> {
751 self.connections.get(connection_id)
752 }
753
754 pub fn update_activity(&mut self, connection_id: &str) -> bool {
756 if let Some(connection) = self.connections.get_mut(connection_id) {
757 connection.last_activity_secs = std::time::SystemTime::now()
758 .duration_since(std::time::UNIX_EPOCH)
759 .unwrap_or(Duration::from_secs(0))
760 .as_secs();
761 if connection.state == DMSCConnectionState::Idle {
762 connection.state = DMSCConnectionState::Active;
763 }
764 true
765 } else {
766 false
767 }
768 }
769
770 pub fn update_health_metrics(&mut self, connection_id: &str, success: bool, response_time_ms: f64) -> bool {
772 if let Some(connection) = self.connections.get_mut(connection_id) {
773 if success {
774 connection.health_metrics.successful_operations += 1;
775 } else {
776 connection.health_metrics.failed_operations += 1;
777 connection.health_metrics.last_error_secs = Some(
778 std::time::SystemTime::now()
779 .duration_since(std::time::UNIX_EPOCH)
780 .unwrap_or(Duration::from_secs(0))
781 .as_secs()
782 );
783 }
784
785 let total_ops = connection.health_metrics.successful_operations + connection.health_metrics.failed_operations;
787 connection.health_metrics.average_response_time_ms =
788 (connection.health_metrics.average_response_time_ms * (total_ops - 1) as f64 + response_time_ms) / total_ops as f64;
789
790 let total_ops = connection.health_metrics.successful_operations + connection.health_metrics.failed_operations;
792 connection.health_metrics.uptime_percentage =
793 (connection.health_metrics.successful_operations as f64 / total_ops as f64) * 100.0;
794
795 true
796 } else {
797 false
798 }
799 }
800
801 pub fn perform_health_check(&mut self) {
803 self.last_health_check_secs = std::time::SystemTime::now()
804 .duration_since(std::time::UNIX_EPOCH)
805 .unwrap_or(Duration::from_secs(0))
806 .as_secs();
807
808 for connection in self.connections.values_mut() {
809 let current_time = std::time::SystemTime::now()
811 .duration_since(std::time::UNIX_EPOCH)
812 .unwrap_or_default()
813 .as_secs();
814 let elapsed_secs = current_time.saturating_sub(connection.last_activity_secs);
815
816 if connection.state == DMSCConnectionState::Active && elapsed_secs > self.connection_timeout.as_secs() {
817 connection.state = DMSCConnectionState::Idle;
818 }
819
820 if connection.health_metrics.uptime_percentage < 90.0 {
822 connection.state = DMSCConnectionState::Unhealthy;
823 } else if let Some(last_error_secs) = connection.health_metrics.last_error_secs {
824 let current_secs = std::time::SystemTime::now()
825 .duration_since(std::time::UNIX_EPOCH)
826 .unwrap_or(Duration::from_secs(0))
827 .as_secs();
828 if current_secs.saturating_sub(last_error_secs) < 60 {
829 connection.state = DMSCConnectionState::Unhealthy;
830 }
831 }
832
833 if connection.state == DMSCConnectionState::Unhealthy &&
835 connection.health_metrics.failed_operations > 10 {
836 connection.state = DMSCConnectionState::Closing;
837 }
838 }
839
840 self.connections.retain(|_, conn| conn.state != DMSCConnectionState::Closed);
842 }
843
844 pub fn active_connections(&self) -> usize {
846 self.connections.values()
847 .filter(|conn| conn.state == DMSCConnectionState::Active)
848 .count()
849 }
850
851 pub fn idle_connections(&self) -> usize {
853 self.connections.values()
854 .filter(|conn| conn.state == DMSCConnectionState::Idle)
855 .count()
856 }
857
858 pub fn unhealthy_connections(&self) -> usize {
860 self.connections.values()
861 .filter(|conn| conn.state == DMSCConnectionState::Unhealthy)
862 .count()
863 }
864
865 pub fn get_statistics(&self) -> DMSCConnectionPoolStatistics {
867 let total_connections = self.connections.len();
868 let active_connections = self.active_connections();
869 let idle_connections = self.idle_connections();
870 let unhealthy_connections = self.unhealthy_connections();
871
872 let total_successful_ops: u64 = self.connections.values()
873 .map(|conn| conn.health_metrics.successful_operations)
874 .sum();
875 let total_failed_ops: u64 = self.connections.values()
876 .map(|conn| conn.health_metrics.failed_operations)
877 .sum();
878
879 let avg_response_time = if !self.connections.is_empty() {
880 let total_response_time: f64 = self.connections.values()
881 .map(|conn| conn.health_metrics.average_response_time_ms)
882 .sum();
883 total_response_time / self.connections.len() as f64
884 } else {
885 0.0
886 };
887
888 let last_health_check_secs = self.last_health_check_secs;
889
890 DMSCConnectionPoolStatistics {
891 total_connections,
892 active_connections,
893 idle_connections,
894 unhealthy_connections,
895 available_slots: self.max_connections.saturating_sub(total_connections),
896 total_successful_operations: total_successful_ops,
897 total_failed_operations: total_failed_ops,
898 average_response_time_ms: avg_response_time,
899 health_check_interval_secs: self.health_check_interval.as_secs(),
900 last_health_check_secs,
901 }
902 }
903}
904
905#[derive(Debug, Clone, Serialize, Deserialize)]
907#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass(get_all, set_all))]
908pub struct DMSCConnectionPoolStatistics {
909 pub total_connections: usize,
911 pub active_connections: usize,
913 pub idle_connections: usize,
915 pub unhealthy_connections: usize,
917 pub available_slots: usize,
919 pub total_successful_operations: u64,
921 pub total_failed_operations: u64,
923 pub average_response_time_ms: f64,
925 pub health_check_interval_secs: u64,
927 pub last_health_check_secs: u64,
929}
930
931impl Default for DMSCConnectionPoolStatistics {
932 fn default() -> Self {
933 Self {
934 total_connections: 0,
935 active_connections: 0,
936 idle_connections: 0,
937 unhealthy_connections: 0,
938 available_slots: 0,
939 total_successful_operations: 0,
940 total_failed_operations: 0,
941 average_response_time_ms: 0.0,
942 health_check_interval_secs: 0,
943 last_health_check_secs: 0,
944 }
945 }
946}
947
948#[derive(Debug, Clone, Serialize, Deserialize)]
953#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass(get_all, set_all))]
954pub struct DMSCResourcePoolStatistics {
955 pub total_devices: usize,
957 pub available_devices: usize,
959 pub allocated_devices: usize,
961 pub utilization_rate: f64,
963 pub total_compute_units: usize,
965 pub total_memory_gb: f64,
967 pub total_storage_gb: f64,
969 pub total_bandwidth_gbps: f64,
971 pub average_health_score: f64,
973 pub device_type: DMSCDeviceType,
975 pub connection_pool_stats: Option<DMSCConnectionPoolStatistics>,
977
978 pub status_distribution: HashMap<DMSCDeviceStatus, usize>,
980 pub average_response_time_ms: f64,
982 pub average_network_latency_ms: f64,
984 pub average_disk_iops: f64,
986 pub average_battery_level_percent: f64,
988 pub average_cpu_usage_percent: f64,
990 pub average_memory_usage_percent: f64,
992 pub average_temperature_celsius: f64,
994 pub total_error_count: u32,
996 pub average_throughput: f64,
998 pub average_uptime_seconds: f64,
1000}
1001
1002impl Default for DMSCResourcePoolStatistics {
1003 fn default() -> Self {
1004 Self {
1005 total_devices: 0,
1006 available_devices: 0,
1007 allocated_devices: 0,
1008 utilization_rate: 0.0,
1009 total_compute_units: 0,
1010 total_memory_gb: 0.0,
1011 total_storage_gb: 0.0,
1012 total_bandwidth_gbps: 0.0,
1013 average_health_score: 0.0,
1014 device_type: DMSCDeviceType::CPU,
1015 connection_pool_stats: None,
1016 status_distribution: HashMap::with_capacity(4),
1017 average_response_time_ms: 0.0,
1018 average_network_latency_ms: 0.0,
1019 average_disk_iops: 0.0,
1020 average_battery_level_percent: 0.0,
1021 average_cpu_usage_percent: 0.0,
1022 average_memory_usage_percent: 0.0,
1023 average_temperature_celsius: 0.0,
1024 total_error_count: 0,
1025 average_throughput: 0.0,
1026 average_uptime_seconds: 0.0,
1027 }
1028 }
1029}
1030
1031#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
1036pub struct DMSCResourcePoolManager {
1037 pools: HashMap<String, Arc<DMSCResourcePool>>,
1039}
1040
1041impl Default for DMSCResourcePoolManager {
1042 fn default() -> Self {
1043 Self::new()
1044 }
1045}
1046
1047impl DMSCResourcePoolManager {
1048 pub fn new() -> Self {
1054 Self {
1055 pools: HashMap::with_capacity(8),
1056 }
1057 }
1058
1059 pub fn create_pool(&mut self, config: DMSCResourcePoolConfig) -> Arc<DMSCResourcePool> {
1071 let pool = Arc::new(DMSCResourcePool::new(config));
1072 self.pools.insert(pool.name().to_string(), pool.clone());
1073 pool
1074 }
1075
1076 pub fn get_pool(&self, name: &str) -> Option<Arc<DMSCResourcePool>> {
1086 self.pools.get(name).cloned()
1087 }
1088
1089 pub fn remove_pool(&mut self, name: &str) -> Option<Arc<DMSCResourcePool>> {
1099 self.pools.remove(name)
1100 }
1101
1102 pub fn get_all_pools(&self) -> Vec<Arc<DMSCResourcePool>> {
1108 self.pools.values().cloned().collect()
1109 }
1110
1111 pub fn get_pools_by_type(&self, device_type: DMSCDeviceType) -> Vec<Arc<DMSCResourcePool>> {
1121 self.pools.values()
1122 .filter(|pool| pool.device_type() == device_type)
1123 .cloned()
1124 .collect()
1125 }
1126
1127 pub fn get_overall_statistics(&self) -> DMSCResourcePoolStatistics {
1136 let pools = self.get_all_pools();
1137
1138 let total_devices: usize = pools.iter().map(|p| p.get_statistics().total_devices).sum();
1140 let allocated_devices: usize = pools.iter().map(|p| p.get_statistics().allocated_devices).sum();
1141
1142 let total_compute_units: usize = pools.iter()
1144 .flat_map(|p| p.get_devices())
1145 .filter_map(|d| d.capabilities().compute_units)
1146 .sum();
1147
1148 let total_memory_gb: f64 = pools.iter()
1150 .flat_map(|p| p.get_devices())
1151 .filter_map(|d| d.capabilities().memory_gb)
1152 .sum();
1153
1154 let total_storage_gb: f64 = pools.iter()
1156 .flat_map(|p| p.get_devices())
1157 .filter_map(|d| d.capabilities().storage_gb)
1158 .sum();
1159
1160 let total_bandwidth_gbps: f64 = pools.iter()
1162 .flat_map(|p| p.get_devices())
1163 .filter_map(|d| d.capabilities().bandwidth_gbps)
1164 .sum();
1165
1166 let overall_utilization = if total_devices > 0 {
1168 allocated_devices as f64 / total_devices as f64
1169 } else {
1170 0.0
1171 };
1172
1173 let total_health_score: f64 = pools.iter()
1175 .map(|p| p.get_statistics().average_health_score)
1176 .sum();
1177 let average_health_score = if !pools.is_empty() {
1178 total_health_score / pools.len() as f64
1179 } else {
1180 0.0
1181 };
1182
1183 DMSCResourcePoolStatistics {
1184 total_devices,
1185 available_devices: total_devices - allocated_devices,
1186 allocated_devices,
1187 utilization_rate: overall_utilization,
1188 total_compute_units,
1189 total_memory_gb,
1190 total_storage_gb,
1191 total_bandwidth_gbps,
1192 average_health_score,
1193 device_type: DMSCDeviceType::Custom, connection_pool_stats: None, status_distribution: HashMap::with_capacity(4),
1197 average_response_time_ms: 0.0,
1198 average_network_latency_ms: 0.0,
1199 average_disk_iops: 0.0,
1200 average_battery_level_percent: 0.0,
1201 average_cpu_usage_percent: 0.0,
1202 average_memory_usage_percent: 0.0,
1203 average_temperature_celsius: 0.0,
1204 total_error_count: 0,
1205 average_throughput: 0.0,
1206 average_uptime_seconds: 0.0,
1207 }
1208 }
1209}
1210
1211#[cfg(feature = "pyo3")]
1212#[pyo3::prelude::pymethods]
1213impl DMSCResourcePoolConfig {
1214 #[new]
1215 fn py_new() -> Self {
1216 Self::default()
1217 }
1218
1219 #[staticmethod]
1220 fn py_new_with_name(name: String, device_type: DMSCDeviceType) -> Self {
1221 Self {
1222 name,
1223 device_type,
1224 max_concurrent_allocations: 10,
1225 allocation_timeout_secs: 60,
1226 health_check_interval_secs: 30,
1227 }
1228 }
1229}
1230
1231#[cfg(feature = "pyo3")]
1232#[pyo3::prelude::pymethods]
1233impl DMSCResourcePoolStatistics {
1234 #[new]
1235 fn py_new() -> Self {
1236 Self::default()
1237 }
1238}
1239
1240#[cfg(feature = "pyo3")]
1241#[pyo3::prelude::pymethods]
1242impl DMSCResourcePoolManager {
1243 #[new]
1244 fn py_new() -> Self {
1245 Self::new()
1246 }
1247}