-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
69d2e65
commit 6a0ccbb
Showing
6 changed files
with
142 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
iter_cache.rs | ||
============= | ||
|
||
View source code :source:`rust/src/include/iter_cache.rs` | ||
|
||
Includes | ||
-------- | ||
|
||
- :external:rust:struct:`std::any::TypeId` | ||
- :external:rust:struct:`std::collections::HashMap` | ||
- :external:rust:trait:`std::sync::Mutex` | ||
- :external:rust:struct:`std::sync::RwLock` | ||
- :external:rust:fn:`std::sync::Once` | ||
|
||
.. rust:struct:: pub struct iter_cache::CachingIterator<I, T> where I: Iterator<Item = T> + 'static, T: Clone + 'static | ||
This struct implements a global cache that maps an iterator-iterated pair to a cache of values. It is mostly | ||
intended for use with the prime function generator. | ||
|
||
.. rust:fn:: pub fn iter_cache::CachingIterator::new() -> CachingIterator<I, T> where I: Iterator<Item = T> + 'static, T: Clone + 'static | ||
.. rust:fn:: pub fn iter_cache::CachingIterator::default() -> CachingIterator<I, T> where I: Iterator<Item = T> + 'static, T: Clone + 'static | ||
.. rust:fn:: pub fn iter_cache::CachingIterator::next() -> Option<T> where T: Clone + 'static | ||
.. literalinclude:: ../../../../rust/src/include/iter_cache.rs | ||
:language: rust | ||
:linenos: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
use std::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<RwLock<HashMap<(TypeId, TypeId), Mutex<Vec<Box<dyn std::any::Any>>>>>> = None; | ||
|
||
pub struct CachingIterator<I, T> | ||
where | ||
I: Iterator<Item = T> + 'static, | ||
T: Copy + 'static | ||
{ | ||
inner: I, | ||
index: usize, | ||
inner_index: usize, | ||
type_id: (TypeId, TypeId), | ||
} | ||
|
||
impl<I, T> CachingIterator<I, T> | ||
where | ||
I: Iterator<Item = T> + 'static, | ||
T: Copy + '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, | ||
inner_index: 0, | ||
type_id: (TypeId::of::<I>(), TypeId::of::<T>()) | ||
} | ||
} | ||
|
||
// 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())); | ||
} | ||
} | ||
} | ||
|
||
impl<I, T> Iterator for CachingIterator<I, T> | ||
where | ||
I: Iterator<Item = T> + 'static, | ||
T: Copy + 'static | ||
{ | ||
type Item = T; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
// 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(); | ||
|
||
if self.index < cache.len() { | ||
// Return the cached result | ||
let boxed_item = &cache[self.index]; | ||
let result = boxed_item.downcast_ref::<T>().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(); | ||
self.inner_index += 1; | ||
} | ||
match self.inner.next() { | ||
Some(value) => { | ||
cache.push(Box::new(value)); | ||
self.index += 1; | ||
self.inner_index += 1; | ||
Some(value) | ||
} | ||
None => None, | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod iter_cache; | ||
pub mod factors; | ||
pub mod math; | ||
pub mod primes; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters