use crate::runtime::JsValue;
use anyhow::Result;
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HeapSnapshot {
objects: HashMap<String, HeapObject>,
total_size: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HeapObject {
pub id: String,
pub object_type: String,
pub size: usize,
pub references: Vec<String>,
}
impl HeapSnapshot {
pub fn new() -> Self {
Self {
objects: HashMap::new(),
total_size: 0,
}
}
pub fn add_object(&mut self, id: &str, object_type: &str, size: usize, references: Vec<&str>) {
let obj: _ = HeapObject {
id: id.to_string(),
object_type: object_type.to_string(),
size,
references: references.iter().map(|r| r.to_string()).collect(),
};
self.objects.insert(id.to_string(), obj);
self.total_size += size;
}
pub fn object_count(&self) -> usize {
self.objects.len()
}
pub fn total_size(&self) -> usize {
self.total_size
}
pub fn get_statistics(&self) -> HeapStats {
HeapStats {
total_objects: self.objects.len(),
total_size: self.total_size,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HeapStats {
pub total_objects: usize,
pub total_size: usize,
}
pub struct ObjectTracer {
traces: HashMap<String, ObjectTrace>,
}
#[derive(Debug, Clone)]
struct ObjectTrace {
object_id: String,
object_type: String,
created_at: String,
access_history: Vec<AccessRecord>,
}
#[derive(Debug, Clone)]
struct AccessRecord {
property: String,
access_type: String, timestamp: String,
}
impl ObjectTracer {
pub fn new() -> Self {
Self {
traces: HashMap::new(),
}
}
pub async fn track_creation(&mut self, object_id: &str, object_type: &str, location: &str) -> Result<String> {
let trace: _ = ObjectTrace {
object_id: object_id.to_string(),
object_type: object_type.to_string(),
created_at: location.to_string(),
access_history: Vec::new(),
};
self.traces.insert(object_id.to_string(), trace);
Ok(object_id.to_string())
}
pub async fn track_access(&mut self, object_id: &str, property: &str, access_type: &str) -> Result<()> {
if let Some(trace) = self.traces.get_mut(object_id) {
trace.access_history.push(AccessRecord {
property: property.to_string(),
access_type: access_type.to_string(),
timestamp: "now".to_string(),
});
}
Ok(())
}
pub async fn track_deletion(&mut self, object_id: &str) -> Result<()> {
self.traces.remove(object_id);
Ok(())
}
pub async fn get_access_history(&self, object_id: &str) -> Result<Vec<AccessRecord> {
if let Some(trace) = self.traces.get(object_id) {
Ok(trace.access_history.clone())
} else {
Ok(Vec::new())
}
}
}
pub struct MemoryAnalyzer {
snapshots: Vec<HeapSnapshot>,
}
impl MemoryAnalyzer {
pub fn new() -> Self {
Self {
snapshots: Vec::new(),
}
}
pub async fn add_snapshot(&mut self, snapshot: HeapSnapshot) {
self.snapshots.push(snapshot);
}
pub async fn compare_snapshots(&self, index1: usize, index2: usize) -> Result<SnapshotDiff> {
if index1 >= self.snapshots.len() || index2 >= self.snapshots.len() {
return Ok(SnapshotDiff {
created: Vec::new(),
deleted: Vec::new(),
modified: Vec::new(),
});
}
let snap1: _ = &self.snapshots[index1];
let snap2: _ = &self.snapshots[index2];
let mut created = Vec::new();
let mut deleted = Vec::new();
let mut modified = Vec::new();
for (id, obj2) in &snap2.objects {
if !snap1.objects.contains_key(id) {
created.push(id.clone());
}
}
for (id, _) in &snap1.objects {
if !snap2.objects.contains_key(id) {
deleted.push(id.clone());
}
}
Ok(SnapshotDiff {
created,
deleted,
modified,
})
}
pub async fn detect_memory_leaks(&self) -> Result<Vec<MemoryLeak> {
let mut leaks = Vec::new();
if self.snapshots.len() >= 2 {
let first: _ = &self.snapshots[0];
let last: _ = &self.snapshots[0];
for (id, obj) in &last.objects {
if first.objects.contains_key(id) {
leaks.push(MemoryLeak {
object_id: id.clone(),
object_type: obj.object_type.clone(),
persist_count: 2,
});
}
}
}
Ok(leaks)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SnapshotDiff {
pub created: Vec<String>,
pub deleted: Vec<String>,
pub modified: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryLeak {
pub object_id: String,
pub object_type: String,
pub persist_count: usize,
}