Skip to content

Commit

Permalink
[dev] add id_generator and object_pool
Browse files Browse the repository at this point in the history
  • Loading branch information
capric8416 committed Jul 12, 2024
1 parent b88adff commit bd86d9d
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 4 deletions.
39 changes: 39 additions & 0 deletions src/id_generator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::collections::VecDeque;
use std::sync::atomic::{AtomicUsize, Ordering};



pub struct IdGenerator {
name: String,
counter: AtomicUsize,
max_count: usize,
cache: VecDeque<usize>,
}

impl IdGenerator {
fn new(name: &str, max_count: usize) -> Self {
IdGenerator {
name: String::from(name),
counter: AtomicUsize::new(0),
max_count,
cache: VecDeque::new(),
}
}

fn name(&self) -> &String {
&self.name
}

fn poll(&mut self) -> usize {
if self.cache.is_empty() {
self.fill();
}
self.cache.pop_front().unwrap()
}

fn fill(&mut self) {
let current = self.counter.fetch_add(self.max_count, Ordering::Relaxed);
let new_ids = (current..(current + self.max_count)).collect::<Vec<usize>>();
self.cache.extend(new_ids);
}
}
4 changes: 0 additions & 4 deletions src/my_rpc_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,9 @@ pub mod bidirectional {
}

// my service
pub mod id_generator;
pub mod my_rpc_service;
pub mod object_pool;
pub mod quick_rpc_service;
use id_generator::IdGenerator;
use my_rpc_service::MyRpcService;
use object_pool::ObjectPool;



Expand Down
49 changes: 49 additions & 0 deletions src/object_pool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::collections::HashMap;
use std::sync::atomic::{AtomicPtr, Ordering};



pub struct ObjectPool<T> {
objects: AtomicPtr<HashMap<String, T>>,
}

impl<T> ObjectPool<T> {
fn new() -> Self {
ObjectPool {
objects: AtomicPtr::new(std::ptr::null_mut()),
}
}

pub fn invoke<F1, F2, R>(&mut self, name: String, new_fn: F1, invoke_fn: F2) -> R
where
F1: FnOnce() -> T,
F2: FnOnce(&mut T) -> R,
{
let objects_map_ptr = self.objects.load(Ordering::Acquire);
let mut objects_map = unsafe { &mut *objects_map_ptr };

if objects_map_ptr.is_null() {
let new_map = Box::new(HashMap::new());
let new_map_ptr = Box::into_raw(new_map);
if self
.objects
.compare_exchange(objects_map_ptr, new_map_ptr, Ordering::Release, Ordering::Relaxed)
.is_ok()
{
objects_map = unsafe { &mut *new_map_ptr };
}
}

match objects_map.entry(name.clone()) {
std::collections::hash_map::Entry::Occupied(mut occupied_entry) => {
return invoke_fn(occupied_entry.get_mut());
}
std::collections::hash_map::Entry::Vacant(vacant_entry) => {
let mut new_object = new_fn();
let result = invoke_fn(&mut new_object);
vacant_entry.insert(new_object);
return result;
}
}
}
}

0 comments on commit bd86d9d

Please sign in to comment.