use std::collections::{BTreeMap, HashMap};
use std::sync::{Arc, Mutex, RwLock};
use std::time::{Duration, Instant};
use std::hash::Hash;
pub fn fast_hash(input: &str) -> u64 {
let mut hash: u64 = 0xcbf29ce484222325; let prime: u64 = 0x100000001b3; for byte in input.as_bytes() {
hash ^= *byte as u64;
hash = hash.wrapping_mul(prime);
}
hash
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Hash)]
pub enum OptimizationLevel {
None = 0,
Basic = 1,
Aggressive = 2,
Maximum = 3,
}
impl Default for OptimizationLevel {
fn default() -> Self {
OptimizationLevel::None
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum CacheType {
Property {
object_type: String,
property_name: String,
},
Function {
function_name: String,
receiver_type: String,
},
Operator {
operator: String,
left_type: String,
right_type: String,
},
}
#[derive(Eq, Hash, PartialEq, Debug, Clone)]
pub struct CacheKey {
pub cache_type: CacheType,
pub receiver_hash: u64,
}
#[derive(Debug, Clone)]
pub struct CacheEntry {
pub cached_value: String, #[allow(dead_code)]
pub type_version: u64,
pub access_count: usize,
pub last_accessed: Instant,
}
#[derive(Debug, Clone)]
pub struct CacheConfig {
pub max_entries: usize,
pub max_age: Duration,
pub min_access_count: usize,
#[allow(dead_code)]
pub cleanup_interval: Duration,
}
impl Default for CacheConfig {
fn default() -> Self {
Self {
max_entries: 5000,
max_age: Duration::from_secs(1800), min_access_count: 3,
cleanup_interval: Duration::from_secs(60), }
}
}
#[derive(Debug, Clone)]
pub struct CacheStats {
pub hits: usize,
pub misses: usize,
pub evictions: usize,
pub total_cached: usize,
pub hit_rate: f64,
pub total_ops: usize,
pub avg_access_time_ns: u64,
pub last_optimization: Instant,
}
impl Default for CacheStats {
fn default() -> Self {
Self {
hits: 0,
misses: 0,
evictions: 0,
total_cached: 0,
hit_rate: 0.0,
total_ops: 0,
avg_access_time_ns: 0,
last_optimization: Instant::now(),
}
}
}
impl CacheStats {
pub fn update_hit_rate(&mut self) {
let total: _ = self.hits + self.misses;
if total > 0 {
self.hit_rate = (self.hits as f64 / total as f64) * 100.0;
}
self.total_ops = total;
}
}
pub struct InlineCache {
entries: Arc<Mutex<HashMap<CacheKey, CacheEntry>>>,
config: CacheConfig,
stats: Arc<Mutex<CacheStats>>,
}
#[allow(dead_code)]
impl InlineCache {
pub fn new() -> Self {
Self::new_with_config(CacheConfig::default())
}
pub fn new_with_config(config: CacheConfig) -> Self {
Self {
entries: Arc::new(Mutex::new(HashMap::new())),
config,
stats: Arc::new(Mutex::new(CacheStats::default())),
}
}
pub fn calculate_receiver_hash(receiver: &str) -> u64 {
fast_hash(receiver)
}
pub fn get(&self, cache_type: &CacheType, receiver_hash: u64) -> Option<String> {
let key: _ = CacheKey {
cache_type: cache_type.clone(),
receiver_hash,
};
let mut entries = self.entries.lock().unwrap();
let mut stats = self.stats.lock().unwrap();
if let Some(entry) = entries.get_mut(&key) {
entry.last_accessed = Instant::now();
entry.access_count += 1;
stats.hits += 1;
Some(entry.cached_value.clone())
} else {
stats.misses += 1;
None
}
}
pub fn put(
&self,
cache_type: CacheType,
receiver_hash: u64,
cached_value: String,
type_version: u64,
) {
let key: _ = CacheKey {
cache_type: cache_type.clone(),
receiver_hash,
};
let mut entries = self.entries.lock().unwrap();
let mut stats = self.stats.lock().unwrap();
entries.insert(
key,
CacheEntry {
cached_value,
type_version,
access_count: 1,
last_accessed: Instant::now(),
},
);
stats.total_cached += 1;
if entries.len() > self.config.max_entries {
self.evict_old_entries(&mut entries, &mut stats);
}
}
fn evict_old_entries(
&self,
entries: &mut HashMap<CacheKey, CacheEntry>,
stats: &mut CacheStats,
) {
let now: _ = Instant::now();
let max_age: _ = self.config.max_age;
let min_access: _ = self.config.min_access_count;
let _keys_to_remove: Vec<CacheKey> = entries
.iter()
.filter_map(|(key, _entry)| {
let is_old: _ = now.duration_since(_entry.last_accessed) > max_age;
let is_rarely_used: _ = _entry.access_count < min_access;
if is_old || is_rarely_used {
Some(key.clone())
} else {
None
}
})
.collect();
let keys_to_remove: Vec<CacheKey> = entries
.iter()
.filter_map(|(key, entry)| {
let is_old: _ = now.duration_since(entry.last_accessed) > max_age;
let is_rarely_used: _ = entry.access_count < min_access;
if is_old || is_rarely_used {
Some(key.clone())
} else {
None
}
})
.collect();
for key in keys_to_remove {
entries.remove(&key);
stats.evictions += 1;
stats.total_cached = stats.total_cached.saturating_sub(1);
}
}
pub fn invalidate_receiver(&self, receiver_hash: u64) {
let mut entries = self.entries.lock().unwrap();
let keys_to_remove: Vec<CacheKey> = entries
.iter()
.filter_map(|(key, _)| {
if key.receiver_hash == receiver_hash {
Some(key.clone())
} else {
None
}
})
.collect();
for key in keys_to_remove {
entries.remove(&key);
}
}
pub fn get_stats(&self) -> CacheStats {
self.stats.lock().unwrap().clone()
}
pub fn clear(&self) {
let mut entries = self.entries.lock().unwrap();
let mut stats = self.stats.lock().unwrap();
let _count: _ = entries.len();
entries.clear();
stats.total_cached = 0;
stats.hits = 0;
stats.misses = 0;
stats.evictions = 0;
stats.hit_rate = 0.0;
stats.total_ops = 0;
}
pub fn pre_warm_common_operators(&self, operators: Vec<(CacheType, u64, String, u64)>) {
let mut entries = self.entries.lock().unwrap();
let mut stats = self.stats.lock().unwrap();
for (cache_type, receiver_hash, cached_value, type_version) in operators {
let key: _ = CacheKey {
cache_type: cache_type.clone(),
receiver_hash,
};
if entries.len() < self.config.max_entries && !entries.contains_key(&key) {
entries.insert(
key,
CacheEntry {
cached_value,
type_version,
access_count: 0,
last_accessed: Instant::now(),
},
);
stats.total_cached += 1;
}
}
}
pub fn predictive_pre_cache(&self, common_properties: Vec<(CacheType, u64, String)>) {
let mut entries = self.entries.lock().unwrap();
let mut stats = self.stats.lock().unwrap();
for (cache_type, receiver_hash, cached_value) in common_properties {
let key: _ = CacheKey {
cache_type: cache_type.clone(),
receiver_hash,
};
if entries.len() < self.config.max_entries && !entries.contains_key(&key) {
entries.insert(
key,
CacheEntry {
cached_value,
type_version: 1,
access_count: 0, last_accessed: Instant::now(),
},
);
stats.total_cached += 1;
}
}
}
pub fn adaptive_optimize(&self) -> OptimizationResult {
let mut stats = self.stats.lock().unwrap();
stats.update_hit_rate();
let mut result = OptimizationResult::default();
if stats.hit_rate < 70.0 && stats.total_ops > 100 {
result.did_optimize = true;
result.reason = format!(
"Low hit rate: {:.2}%, operations: {}",
stats.hit_rate, stats.total_ops
);
let mut entries = self.entries.lock().unwrap();
let before_count: _ = entries.len();
let keys_to_remove: Vec<CacheKey> = entries
.iter()
.filter_map(|(key, entry)| {
if entry.access_count < self.config.min_access_count {
Some(key.clone())
} else {
None
}
})
.collect();
for key in keys_to_remove {
entries.remove(&key);
stats.evictions += 1;
stats.total_cached = stats.total_cached.saturating_sub(1);
}
result.evicted_entries = before_count - entries.len();
}
stats.last_optimization = Instant::now();
result
}
pub fn batch_get(&self, requests: &[(CacheType, u64)]) -> Vec<Option<String>> {
let entries: _ = self.entries.lock().unwrap();
let mut stats = self.stats.lock().unwrap();
let mut results = Vec::with_capacity(requests.len());
for (cache_type, receiver_hash) in requests {
let key: _ = CacheKey {
cache_type: cache_type.clone(),
receiver_hash: *receiver_hash,
};
if let Some(entry) = entries.get(&key) {
stats.hits += 1;
results.push(Some(entry.cached_value.clone()));
} else {
stats.misses += 1;
results.push(None);
}
}
stats.update_hit_rate();
results
}
pub fn batch_put(&self, items: Vec<(CacheType, u64, String, u64)>) {
let mut entries = self.entries.lock().unwrap();
let mut stats = self.stats.lock().unwrap();
for (cache_type, receiver_hash, cached_value, type_version) in items {
let key: _ = CacheKey {
cache_type: cache_type.clone(),
receiver_hash,
};
entries.insert(
key,
CacheEntry {
cached_value,
type_version,
access_count: 1,
last_accessed: Instant::now(),
},
);
stats.total_cached += 1;
}
if entries.len() > self.config.max_entries {
let mut temp_stats = stats.clone();
self.evict_old_entries(&mut entries, &mut temp_stats);
*stats = temp_stats;
}
}
pub fn get_usage_report(&self) -> CacheUsageReport {
let stats: _ = self.stats.lock().unwrap();
let entries: _ = self.entries.lock().unwrap();
CacheUsageReport {
total_entries: entries.len(),
max_entries: self.config.max_entries,
utilization: (entries.len() as f64 / self.config.max_entries as f64) * 100.0,
hit_rate: stats.hit_rate,
total_operations: stats.total_ops,
avg_access_time_ns: stats.avg_access_time_ns,
}
}
}
#[derive(Debug, Clone)]
pub struct OptimizationResult {
pub did_optimize: bool,
pub reason: String,
pub evicted_entries: usize,
}
impl Default for OptimizationResult {
fn default() -> Self {
Self {
did_optimize: false,
reason: "No optimization needed".to_string(),
evicted_entries: 0,
}
}
}
#[derive(Debug, Clone)]
pub struct CacheUsageReport {
#[allow(dead_code)]
pub total_entries: usize,
#[allow(dead_code)]
pub max_entries: usize,
#[allow(dead_code)]
pub utilization: f64,
#[allow(dead_code)]
pub hit_rate: f64,
#[allow(dead_code)]
pub total_operations: usize,
#[allow(dead_code)]
pub avg_access_time_ns: u64,
}
#[cfg(test)]
mod tests {
#[test]
fn test_cache_creation() {
let cache: _ = InlineCache::new();
let stats: _ = cache.get_stats();
assert_eq!(stats.total_cached, 0);
}
#[test]
fn test_cache_put_and_get() {
let cache: _ = InlineCache::new();
let cache_type: _ = CacheType::Property {
object_type: "Object".to_string(),
property_name: "foo".to_string(),
};
let receiver_hash: _ = InlineCache::calculate_receiver_hash("obj");
cache.put(
cache_type.clone(),
receiver_hash,
"cached_value".to_string(),
1,
);
let result: _ = cache.get(&cache_type, receiver_hash);
assert_eq!(result, Some("cached_value".to_string()));
let stats: _ = cache.get_stats();
assert_eq!(stats.hits, 1);
assert_eq!(stats.misses, 0);
}
#[test]
fn test_cache_miss() {
let cache: _ = InlineCache::new();
let cache_type: _ = CacheType::Property {
object_type: "Object".to_string(),
property_name: "bar".to_string(),
};
let receiver_hash: _ = InlineCache::calculate_receiver_hash("obj");
let result: _ = cache.get(&cache_type, receiver_hash);
assert_eq!(result, None);
let stats: _ = cache.get_stats();
assert_eq!(stats.hits, 0);
assert_eq!(stats.misses, 1);
}
#[test]
fn test_cache_invalidation() {
let cache: _ = InlineCache::new();
let cache_type: _ = CacheType::Property {
object_type: "Object".to_string(),
property_name: "baz".to_string(),
};
let receiver_hash: _ = InlineCache::calculate_receiver_hash("obj");
cache.put(
cache_type.clone(),
receiver_hash,
"cached_value".to_string(),
1,
);
cache.invalidate_receiver(receiver_hash);
let result: _ = cache.get(&cache_type, receiver_hash);
assert_eq!(result, None);
}
#[test]
fn test_adaptive_optimization() {
let cache: _ = InlineCache::new();
let _cache_type: _ = CacheType::Property {
object_type: "Object".to_string(),
property_name: "test".to_string(),
};
let receiver_hash: _ = InlineCache::calculate_receiver_hash("obj");
for i in 0..5 {
let temp_type: _ = CacheType::Property {
object_type: "Object".to_string(),
property_name: format!("prop{}", i),
};
cache.put(temp_type, receiver_hash, format!("value{}", i), 1);
}
let result: _ = cache.adaptive_optimize();
assert!(!result.reason.is_empty());
}
#[test]
fn test_batch_operations() {
let cache: _ = InlineCache::new();
let items: _ = vec![
(
CacheType::Property {
object_type: "Object".to_string(),
property_name: "a".to_string(),
},
1,
"value_a".to_string(),
1,
),
(
CacheType::Property {
object_type: "Object".to_string(),
property_name: "b".to_string(),
},
1,
"value_b".to_string(),
1,
),
];
cache.batch_put(items);
let requests: _ = vec![
(
CacheType::Property {
object_type: "Object".to_string(),
property_name: "a".to_string(),
},
1,
),
(
CacheType::Property {
object_type: "Object".to_string(),
property_name: "b".to_string(),
},
1,
),
];
let results: _ = cache.batch_get(&requests);
assert_eq!(results.len(), 2);
assert_eq!(results[0], Some("value_a".to_string()));
assert_eq!(results[1], Some("value_b".to_string()));
}
#[test]
fn test_predictive_pre_cache() {
let cache: _ = InlineCache::new();
let common_properties: _ = vec![
(
CacheType::Property {
object_type: "Object".to_string(),
property_name: "length".to_string(),
},
1,
"0".to_string(),
),
(
CacheType::Property {
object_type: "Array".to_string(),
property_name: "push".to_string(),
},
2,
"function".to_string(),
),
];
cache.predictive_pre_cache(common_properties);
let stats: _ = cache.get_stats();
assert_eq!(stats.total_cached, 2);
}
#[test]
fn test_usage_report() {
let cache: _ = InlineCache::new();
let cache_type: _ = CacheType::Property {
object_type: "Object".to_string(),
property_name: "test".to_string(),
};
let receiver_hash: _ = InlineCache::calculate_receiver_hash("obj");
cache.put(cache_type.clone(), receiver_hash, "value".to_string(), 1);
cache.get(&cache_type, receiver_hash);
let report: _ = cache.get_usage_report();
assert!(report.hit_rate >= 0.0);
assert!(report.utilization >= 0.0);
}
#[test]
fn test_fast_hash_consistency() {
let input1: _ = "test_object";
let input2: _ = "test_object";
let hash1: _ = fast_hash(input1);
let hash2: _ = fast_hash(input2);
assert_eq!(hash1, hash2); let input3: _ = "different_object";
let hash3: _ = fast_hash(input3);
assert_ne!(hash1, hash3); }
}
pub struct PolymorphicInlineCache {
caches: Arc<RwLock<HashMap<String, Box<dyn CacheStrategy + Send + Sync>>>>,
max_cache_size: usize,
stats: Arc<RwLock<HashMap<String, CacheStats>>>,
hot_code_tracker: Arc<RwLock<HotCodeTracker>>,
optimization_config: OptimizationConfig,
}
pub trait CacheStrategy {
fn lookup(&self, key: &str) -> Option<CacheEntry>;
fn insert(&mut self, key: String, entry: CacheEntry) -> Option<CacheEntry>;
fn remove(&mut self, key: &str) -> Option<CacheEntry>;
fn clear(&mut self);
fn len(&self) -> usize;
fn get_stats(&self) -> CacheStats;
}
#[derive(Debug)]
pub struct MonomorphicCache {
entries: HashMap<String, CacheEntry>,
config: CacheConfig,
stats: CacheStats,
}
impl MonomorphicCache {
pub fn new(config: CacheConfig) -> Self {
Self {
entries: HashMap::new(),
config,
stats: CacheStats::default(),
}
}
}
impl CacheStrategy for MonomorphicCache {
fn lookup(&self, key: &str) -> Option<CacheEntry> {
let entry: _ = self.entries.get(key).cloned();
if entry.is_some() {
}
entry
}
fn insert(&mut self, key: String, entry: CacheEntry) -> Option<CacheEntry> {
let result: _ = self.entries.insert(key, entry.clone());
result
}
fn remove(&mut self, key: &str) -> Option<CacheEntry> {
self.entries.remove(key)
}
fn clear(&mut self) {
self.entries.clear();
self.stats = CacheStats::default();
}
fn len(&self) -> usize {
self.entries.len()
}
fn get_stats(&self) -> CacheStats {
self.stats.clone()
}
}
#[derive(Debug)]
pub struct MegamorphicCache {
caches: HashMap<String, MonomorphicCache>,
config: CacheConfig,
stats: CacheStats,
}
impl MegamorphicCache {
pub fn new(config: CacheConfig) -> Self {
Self {
caches: HashMap::new(),
config,
stats: CacheStats::default(),
}
}
}
impl CacheStrategy for MegamorphicCache {
fn lookup(&self, key: &str) -> Option<CacheEntry> {
let type_name: _ = self.extract_type_from_key(key);
if let Some(cache) = self.caches.get(&type_name) {
cache.lookup(key)
} else {
None
}
}
fn insert(&mut self, key: String, entry: CacheEntry) -> Option<CacheEntry> {
let type_name: _ = self.extract_type_from_key(&key);
let cache: _ = self.caches.entry(type_name).or_insert_with(|| {
MonomorphicCache::new(self.config.clone())
});
cache.insert(key, entry)
}
fn remove(&mut self, key: &str) -> Option<CacheEntry> {
let type_name: _ = self.extract_type_from_key(key);
if let Some(cache) = self.caches.get_mut(&type_name) {
cache.remove(key)
} else {
None
}
}
fn clear(&mut self) {
self.caches.clear();
self.stats = CacheStats::default();
}
fn len(&self) -> usize {
self.caches.values().map(|c| c.len()).sum()
}
fn get_stats(&self) -> CacheStats {
self.stats.clone()
}
}
impl MegamorphicCache {
fn extract_type_from_key(&self, key: &str) -> String {
key.split(':').next().unwrap_or("unknown").to_string()
}
}
#[derive(Debug, Clone)]
pub struct HotCodeEntry {
pub code_location: String,
pub execution_count: u64,
pub last_executed: Instant,
pub avg_execution_time_ns: u64,
pub optimization_level: OptimizationLevel,
}
#[derive(Debug)]
pub struct HotCodeTracker {
entries: HashMap<String, HotCodeEntry>,
max_entries: usize,
hot_threshold: u64, }
impl HotCodeTracker {
pub fn new(max_entries: usize) -> Self {
Self {
entries: HashMap::new(),
max_entries,
hot_threshold: 100, }
}
pub fn record_execution(&mut self, location: &str, execution_time_ns: u64) {
let now: _ = Instant::now();
let entry: _ = self.entries.entry(location.to_string()).or_insert_with(|| {
HotCodeEntry {
code_location: location.to_string(),
execution_count: 0,
last_executed: now,
avg_execution_time_ns: execution_time_ns,
optimization_level: OptimizationLevel::None,
}
});
entry.execution_count += 1;
entry.last_executed = now;
entry.avg_execution_time_ns = (entry.avg_execution_time_ns * 9 + execution_time_ns) / 10;
if entry.execution_count >= self.hot_threshold * 10 {
entry.optimization_level = OptimizationLevel::Maximum;
} else if entry.execution_count >= self.hot_threshold * 5 {
entry.optimization_level = OptimizationLevel::Aggressive;
} else if entry.execution_count >= self.hot_threshold {
entry.optimization_level = OptimizationLevel::Basic;
}
}
pub fn get_hot_code(&self) -> Vec<&HotCodeEntry> {
let mut entries: Vec<_> = self.entries.values().collect();
entries.sort_by(|a, b| {
b.execution_count.cmp(&a.execution_count)
.then_with(|| a.avg_execution_time_ns.cmp(&b.avg_execution_time_ns))
});
entries
}
pub fn is_hot_code(&self, location: &str) -> bool {
if let Some(entry) = self.entries.get(location) {
entry.execution_count >= self.hot_threshold
} else {
false
}
}
}
#[derive(Debug, Clone)]
pub struct OptimizationConfig {
pub enable_polymorphic_cache: bool,
pub hot_code_threshold: u64,
pub max_cache_per_type: usize,
pub enable_predictive_optimization: bool,
}
impl Default for OptimizationConfig {
fn default() -> Self {
Self {
enable_polymorphic_cache: true,
hot_code_threshold: 100,
max_cache_per_type: 1000,
enable_predictive_optimization: true,
}
}
}
impl PolymorphicInlineCache {
pub fn new(max_cache_size: usize) -> Self {
Self {
caches: Arc::new(Mutex::new(HashMap::new())),
max_cache_size,
stats: Arc::new(Mutex::new(HashMap::new())),
hot_code_tracker: Arc::new(Mutex::new(HotCodeTracker::new(1000))),
optimization_config: OptimizationConfig::default(),
}
}
pub fn new_with_config(max_cache_size: usize, config: OptimizationConfig) -> Self {
Self {
caches: Arc::new(Mutex::new(HashMap::new())),
max_cache_size,
stats: Arc::new(Mutex::new(HashMap::new())),
hot_code_tracker: Arc::new(Mutex::new(HotCodeTracker::new(1000))),
optimization_config: config,
}
}
pub fn polymorphic_lookup(&self, type_name: &str, key: &str) -> Option<CacheEntry> {
let caches: _ = self.caches.read().unwrap();
if let Some(cache) = caches.get(type_name) {
let entry: _ = cache.lookup(key);
if entry.is_some() {
self.update_stats(type_name, true);
return entry;
}
}
self.update_stats(type_name, false);
None
}
pub fn polymorphic_insert(&self, type_name: &str, key: String, entry: CacheEntry) {
let mut caches = self.caches.write().unwrap();
let cache: _ = if self.optimization_config.enable_polymorphic_cache {
caches.entry(type_name.to_string()).or_insert_with(|| {
Box::new(MegamorphicCache::new(CacheConfig::default())) as Box<dyn CacheStrategy + Send + Sync>
})
} else {
caches.entry(type_name.to_string()).or_insert_with(|| {
Box::new(MonomorphicCache::new(CacheConfig::default())) as Box<dyn CacheStrategy + Send + Sync>
})
};
cache.insert(key, entry);
if cache.len() > self.optimization_config.max_cache_per_type {
self.evict_old_entries(type_name);
}
}
pub fn record_hot_code(&self, location: &str, execution_time_ns: u64) {
let mut tracker = self.hot_code_tracker.write().unwrap();
tracker.record_execution(location, execution_time_ns);
}
pub fn get_hot_code(&self) -> Vec<HotCodeEntry> {
let tracker: _ = self.hot_code_tracker.read().unwrap();
tracker.get_hot_code().into_iter().cloned().collect()
}
pub fn is_hot_code(&self, location: &str) -> bool {
let tracker: _ = self.hot_code_tracker.read().unwrap();
tracker.is_hot_code(location)
}
pub fn generate_optimized_code(&self, location: &str) -> Option<OptimizedCode> {
let tracker: _ = self.hot_code_tracker.read().unwrap();
if let Some(entry) = tracker.entries.get(location) {
if entry.execution_count >= self.optimization_config.hot_code_threshold {
Some(OptimizedCode {
location: location.to_string(),
optimization_level: entry.optimization_level,
estimated_speedup: self.calculate_speedup(entry),
generated_at: Instant::now(),
})
} else {
None
}
} else {
None
}
}
fn calculate_speedup(&self, entry: &HotCodeEntry) -> f64 {
match entry.optimization_level {
OptimizationLevel::None => 1.0,
OptimizationLevel::Basic => 1.5,
OptimizationLevel::Aggressive => 2.5,
OptimizationLevel::Maximum => 4.0,
}
}
pub fn batch_optimize_hot_code(&self) -> Vec<OptimizedCode> {
let tracker: _ = self.hot_code_tracker.read().unwrap();
let mut optimizations = Vec::new();
for entry in tracker.get_hot_code() {
if let Some(opt) = self.generate_optimized_code(&entry.code_location) {
optimizations.push(opt);
}
}
optimizations
}
fn update_stats(&self, type_name: &str, hit: bool) {
let mut stats = self.stats.write().unwrap();
let entry: _ = stats.entry(type_name.to_string()).or_insert_with(CacheStats::default);
if hit {
entry.hits += 1;
} else {
entry.misses += 1;
}
entry.update_hit_rate();
}
fn evict_old_entries(&self, type_name: &str) {
let mut caches = self.caches.write().unwrap();
if let Some(cache) = caches.get_mut(type_name) {
cache.clear();
}
}
pub fn get_all_stats(&self) -> HashMap<String, CacheStats> {
self.stats.read().unwrap().clone()
}
pub fn get_cache_report(&self) -> PolymorphicCacheReport {
let caches: _ = self.caches.read().unwrap();
let stats: _ = self.stats.read().unwrap();
let tracker: _ = self.hot_code_tracker.read().unwrap();
let total_entries: usize = caches.values().map(|c| c.len()).sum();
let total_hits: usize = stats.values().map(|s| s.hits).sum();
let total_misses: usize = stats.values().map(|s| s.misses).sum();
let hot_code_count: _ = tracker.entries.len();
PolymorphicCacheReport {
total_cache_types: caches.len(),
total_entries,
total_hits,
total_misses,
hit_rate: if total_hits + total_misses > 0 {
(total_hits as f64 / (total_hits + total_misses) as f64) * 100.0
} else {
0.0
},
hot_code_count,
max_cache_size: self.max_cache_size,
}
}
}
#[derive(Debug, Clone)]
pub struct OptimizedCode {
pub location: String,
pub optimization_level: OptimizationLevel,
pub estimated_speedup: f64,
pub generated_at: Instant,
}
#[derive(Debug, Clone)]
pub struct PolymorphicCacheReport {
pub total_cache_types: usize,
pub total_entries: usize,
pub total_hits: usize,
pub total_misses: usize,
pub hit_rate: f64,
pub hot_code_count: usize,
pub max_cache_size: usize,
}
#[cfg(test)]
mod polymorphic_tests {
#[test]
fn test_polymorphic_cache_creation() {
let cache: _ = PolymorphicInlineCache::new(1000);
let report: _ = cache.get_cache_report();
assert_eq!(report.total_cache_types, 0);
assert_eq!(report.total_entries, 0);
}
#[test]
fn test_polymorphic_cache_lookup_insert() {
let cache: _ = PolymorphicInlineCache::new(1000);
let entry: _ = CacheEntry {
cached_value: "test_value".to_string(),
type_version: 1,
access_count: 0,
last_accessed: Instant::now(),
};
cache.polymorphic_insert("Object", "key1".to_string(), entry.clone());
let result: _ = cache.polymorphic_lookup("Object", "key1");
assert!(result.is_some());
assert_eq!(result.unwrap().cached_value, "test_value");
let report: _ = cache.get_cache_report();
assert_eq!(report.total_entries, 1);
assert!(report.hit_rate >= 0.0);
}
#[test]
fn test_hot_code_detection() {
let cache: _ = PolymorphicInlineCache::new(1000);
for i in 0..150 {
cache.record_hot_code("function:loop", 1000 + i);
}
assert!(cache.is_hot_code("function:loop"));
assert!(!cache.is_hot_code("function:rare"));
let hot_code: _ = cache.get_hot_code();
assert!(!hot_code.is_empty());
assert_eq!(hot_code[0].code_location, "function:loop");
assert_eq!(hot_code[0].execution_count, 150);
}
#[test]
fn test_optimization_generation() {
let cache: _ = PolymorphicInlineCache::new(1000);
for i in 0..120 {
cache.record_hot_code("function:compute", 2000 + i);
}
let optimized: _ = cache.generate_optimized_code("function:compute");
assert!(optimized.is_some());
let opt: _ = optimized.unwrap();
assert_eq!(opt.location, "function:compute");
assert!(opt.estimated_speedup > 1.0);
assert_eq!(opt.optimization_level, OptimizationLevel::Basic);
}
#[test]
fn test_batch_optimization() {
let cache: _ = PolymorphicInlineCache::new(1000);
for i in 0..10 {
let location: _ = format!("function:hot{}", i);
for _ in 0..150 {
cache.record_hot_code(&location, 1000);
}
}
let optimizations: _ = cache.batch_optimize_hot_code();
assert!(optimizations.len() > 0);
for opt in optimizations {
assert!(opt.estimated_speedup >= 1.0);
assert!(!opt.location.is_empty());
}
}
#[test]
fn test_multiple_cache_types() {
let cache: _ = PolymorphicInlineCache::new(1000);
let entry1: _ = CacheEntry {
cached_value: "value1".to_string(),
type_version: 1,
access_count: 0,
last_accessed: Instant::now(),
};
let entry2: _ = CacheEntry {
cached_value: "value2".to_string(),
type_version: 1,
access_count: 0,
last_accessed: Instant::now(),
};
cache.polymorphic_insert("Array", "arr_key".to_string(), entry1);
cache.polymorphic_insert("Object", "obj_key".to_string(), entry2);
let result1: _ = cache.polymorphic_lookup("Array", "arr_key");
let result2: _ = cache.polymorphic_lookup("Object", "obj_key");
assert!(result1.is_some());
assert!(result2.is_some());
assert_eq!(result1.unwrap().cached_value, "value1");
assert_eq!(result2.unwrap().cached_value, "value2");
let report: _ = cache.get_cache_report();
assert_eq!(report.total_cache_types, 2);
assert_eq!(report.total_entries, 2);
}
#[test]
fn test_cache_stats() {
let cache: _ = PolymorphicInlineCache::new(1000);
let entry: _ = CacheEntry {
cached_value: "test".to_string(),
type_version: 1,
access_count: 0,
last_accessed: Instant::now(),
};
cache.polymorphic_insert("TestType", "key".to_string(), entry.clone());
cache.polymorphic_lookup("TestType", "key");
cache.polymorphic_lookup("TestType", "key");
cache.polymorphic_lookup("TestType", "missing");
let stats: _ = cache.get_all_stats();
assert!(stats.contains_key("TestType"));
let test_stats: _ = stats.get("TestType").unwrap();
assert_eq!(test_stats.hits, 2);
assert_eq!(test_stats.misses, 1);
assert!(test_stats.hit_rate > 0.0);
}
#[test]
fn test_optimization_level_progression() {
let cache: _ = PolymorphicInlineCache::new(1000);
let threshold: _ = cache.optimization_config.hot_code_threshold;
for _ in 0..threshold {
cache.record_hot_code("function:basic", 1000);
}
let optimized: _ = cache.generate_optimized_code("function:basic");
assert!(optimized.is_some());
assert_eq!(optimized.unwrap().optimization_level, OptimizationLevel::Basic);
for _ in 0..threshold * 5 {
cache.record_hot_code("function:aggressive", 1000);
}
let optimized: _ = cache.generate_optimized_code("function:aggressive");
assert!(optimized.is_some());
assert_eq!(optimized.unwrap().optimization_level, OptimizationLevel::Aggressive);
for _ in 0..threshold * 10 {
cache.record_hot_code("function:maximum", 1000);
}
let optimized: _ = cache.generate_optimized_code("function:maximum");
assert!(optimized.is_some());
assert_eq!(optimized.unwrap().optimization_level, OptimizationLevel::Maximum);
}
#[test]
fn test_cache_report_completeness() {
let cache: _ = PolymorphicInlineCache::new(1000);
for i in 0..5 {
let entry: _ = CacheEntry {
cached_value: format!("value{}", i),
type_version: 1,
access_count: 0,
last_accessed: Instant::now(),
};
cache.polymorphic_insert(&format!("Type{}", i), format!("key{}", i), entry);
}
let report: _ = cache.get_cache_report();
assert_eq!(report.total_cache_types, 5);
assert_eq!(report.total_entries, 5);
assert!(report.max_cache_size > 0);
assert!(report.hit_rate >= 0.0);
}
}