diff --git a/javascript/package.json b/javascript/package.json index 335903b1..9dc23834 100644 --- a/javascript/package.json +++ b/javascript/package.json @@ -23,7 +23,7 @@ "eslint": "^6.4.0", "eslint-config-google": "^0.14.0", "globals": "^15.6.0", - "webpack": "^5.93.0", + "webpack": "^5.94.0", "webpack-cli": "^5.1.4" } } diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 81554b74..d528728f 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -13,6 +13,7 @@ license = "GPL-3.0" [dependencies] chrono = "0.4.38" itertools = "0.13.0" +lazy_static = "1.5.0" num-traits = "0.2.19" seq-macro = "0.3.5" diff --git a/rust/src/include/fibonacci.rs b/rust/src/include/fibonacci.rs index c49480be..f4f71786 100644 --- a/rust/src/include/fibonacci.rs +++ b/rust/src/include/fibonacci.rs @@ -2,12 +2,14 @@ use std::ops::{Add,Mul}; use num_traits::{one,zero,One,Zero}; -pub fn fib() -> impl Iterator where I: Copy + Zero + One + Add + 'static { - return Fibonacci::::new(); +use crate::include::iter_cache::cache_iterator; + +pub fn fib() -> impl Iterator where I: Copy + Zero + One + Add + Send + 'static { + return cache_iterator(Fibonacci::::new()); } -pub fn fib_by_3() -> impl Iterator where I: Copy + Zero + One + Add + Mul + 'static { - return FibonacciBy3::::new(); +pub fn fib_by_3() -> impl Iterator where I: Copy + Zero + One + Add + Mul + Send + 'static { + return cache_iterator(FibonacciBy3::::new()); } #[derive(Clone, Copy, Debug, Hash)] diff --git a/rust/src/include/iter_cache.rs b/rust/src/include/iter_cache.rs index 75418726..a63b4763 100644 --- a/rust/src/include/iter_cache.rs +++ b/rust/src/include/iter_cache.rs @@ -1,15 +1,19 @@ -use std::any::TypeId; +use lazy_static::lazy_static; + +use std::any::{Any,TypeId}; use std::collections::HashMap; use std::sync::{Mutex, RwLock}; -use std::sync::Once; -static INIT: Once = Once::new(); -static mut CACHE_MAP: Option>>>>> = None; +type CacheVector = Vec>; +type CacheMap = HashMap<(TypeId, TypeId), Mutex>>; +lazy_static! { + static ref CACHE_MAP: RwLock> = RwLock::new(HashMap::new()); +} pub fn cache_iterator(iterator: I) -> impl Iterator where I: Iterator + 'static, - T: Copy + 'static + T: Copy + Send + 'static { return CachingIterator::new(iterator); } @@ -18,7 +22,7 @@ where pub struct CachingIterator where I: Iterator + 'static, - T: Copy + 'static + T: Copy + Send + 'static { inner: I, index: usize, @@ -29,15 +33,9 @@ where impl CachingIterator where I: Iterator + 'static, - T: Copy + 'static + T: Copy + Send + 'static { pub fn new(inner: I) -> Self { - // Initialize the global cache map if it hasn't been initialized yet - unsafe { - INIT.call_once(|| { - CACHE_MAP = Some(RwLock::new(HashMap::new())); - }); - } CachingIterator { inner, index: 0, @@ -46,56 +44,48 @@ where } } - // Initialize the cache for the given type fn initialize_cache(&self) { - unsafe { - let mut cache_map = CACHE_MAP.as_ref().unwrap().write().unwrap(); - cache_map.entry(self.type_id) - .or_insert_with(|| Mutex::new(Vec::new())); - } + let mut cache_map = CACHE_MAP.write().unwrap(); + cache_map.entry(self.type_id) + .or_insert_with(|| Mutex::new(Vec::new())); } } impl Iterator for CachingIterator where I: Iterator + 'static, - T: Copy + 'static + T: Copy + Send + 'static { type Item = T; fn next(&mut self) -> Option { - // Ensure the cache is initialized self.initialize_cache(); - - // Access the global cache map - let cache_map = unsafe { CACHE_MAP.as_ref().unwrap().read().unwrap() }; - - let mut cache = cache_map - .get(&self.type_id) - .expect("Cache for this type should be initialized") - .lock() - .unwrap(); + let mut cache = CACHE_MAP.read() + .unwrap() + .get(&self.type_id) + .expect("Cache for this type should be initialized") + .lock() + .unwrap(); if self.index < cache.len() { - // Return the cached result - let boxed_item = &cache[self.index]; + let boxed_item = &cache[self.index] let result = boxed_item.downcast_ref::().unwrap(); self.index += 1; - Some(*result) - } else { - // Fetch the next result from the inner iterator and cache it - while self.inner_index < self.index { - self.inner.next(); + return Some(*result); + } + while self.inner_index < self.index { + self.inner.next(); + self.inner_index += 1; + } + return match self.inner.next() { + Some(value) => { + cache.push(Box::new(value)); + self.index += 1; self.inner_index += 1; + return Some(value); } - match self.inner.next() { - Some(value) => { - cache.push(Box::new(value)); - self.index += 1; - self.inner_index += 1; - Some(value) - } - None => None, + None => { + return None; } } } diff --git a/rust/src/include/primes.rs b/rust/src/include/primes.rs index 32669cf2..4928d227 100644 --- a/rust/src/include/primes.rs +++ b/rust/src/include/primes.rs @@ -5,6 +5,8 @@ use std::ops::{Add,Div,Mul,Rem}; use num_traits::{one,zero,One,Zero}; +use crate::include::iter_cache::cache_iterator; + #[derive(Clone, Debug)] pub struct Eratosthenes where I: Hash { sieve: HashMap>, @@ -59,11 +61,13 @@ impl Iterator for Eratosthenes where I: Hash + One + Zero + Add + Mul + Or } } -pub fn primes() -> impl Iterator where I: Hash + One + Zero + Add + Mul + Ord + Copy + 'static { - return Eratosthenes::new(); +pub fn primes() -> impl Iterator where I: Hash + One + Zero + Add + Mul + Ord + Copy + Send + 'static { + return cache_iterator(Eratosthenes::new()); } -pub fn primes_until(x: I) -> impl Iterator where I: Hash + One + Zero + Add + Mul + Ord + Copy + 'static { +pub fn primes_until(x: I) -> impl Iterator +where I: Hash + One + Zero + Add + Mul + Ord + Copy + Send + 'static +{ return primes::().take_while(move |n| *n < x); } @@ -81,7 +85,7 @@ impl PrimeFactors { } impl Iterator for PrimeFactors -where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + 'static +where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + Send + 'static { type Item = I; @@ -100,13 +104,13 @@ where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + } pub fn prime_factors(x: I) -> impl Iterator -where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + 'static +where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + Send + 'static { return PrimeFactors::new(x); } pub fn is_composite(x: I) -> I -where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + 'static +where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + Send + 'static { match prime_factors(x).next() { None => { @@ -122,7 +126,7 @@ where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + } pub fn is_prime(x: I) -> bool -where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + 'static +where I: Hash + Zero + One + Add + Ord + Copy + Div + Rem + Send + 'static { let two = one::() + one::(); if x < two {