|
|
|
@ -1,32 +1,37 @@
|
|
|
|
|
use super::*;
|
|
|
|
|
use std::collections::{HashMap, HashSet};
|
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
use tokio::sync::{
|
|
|
|
|
RwLock,
|
|
|
|
|
RwLockReadGuard,
|
|
|
|
|
use tokio::sync::RwLock;
|
|
|
|
|
use generational_arena::{
|
|
|
|
|
Arena,Index,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use user::{User, UserID};
|
|
|
|
|
use post::Post;
|
|
|
|
|
use post::{Post, PostID};
|
|
|
|
|
|
|
|
|
|
mod freeze;
|
|
|
|
|
pub use freeze::*;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
struct Posts
|
|
|
|
|
struct Oneesan
|
|
|
|
|
{
|
|
|
|
|
users: HashMap<UserID, RwLock<User>>,
|
|
|
|
|
posts: HashMap<UserID, MaybeVec<RwLock<Post>>>,
|
|
|
|
|
}
|
|
|
|
|
users: Arena<Arc<RwLock<User>>>,
|
|
|
|
|
posts: Arena<Arc<RwLock<Post>>>,
|
|
|
|
|
|
|
|
|
|
/// A read lock over all posts and users
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct PostsLock<'a>(RwLockReadGuard<'a, Posts>);
|
|
|
|
|
/// Maps `UserID`s to indexes in the `users` arena.
|
|
|
|
|
users_map: HashMap<UserID, Index>,
|
|
|
|
|
/// Maps `PostID`s to indexies in the `posts` arena.
|
|
|
|
|
posts_map: HashMap<PostID, Index>,
|
|
|
|
|
|
|
|
|
|
/// Maps `UserID`s to the user's owned posts in the `posts` arena.
|
|
|
|
|
posts_user_map: HashMap<UserID, MaybeVec<Index>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
struct Inner
|
|
|
|
|
{
|
|
|
|
|
posts: RwLock<Posts>,
|
|
|
|
|
/// The posts and user state.
|
|
|
|
|
oneesan: RwLock<Oneesan>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Contains all posts and users
|
|
|
|
@ -40,42 +45,16 @@ impl State
|
|
|
|
|
{
|
|
|
|
|
Self(Arc::new(
|
|
|
|
|
Inner {
|
|
|
|
|
posts: RwLock::new(Posts {
|
|
|
|
|
users: HashMap::new(),
|
|
|
|
|
posts: HashMap::new(),
|
|
|
|
|
oneesan: RwLock::new(Oneesan {
|
|
|
|
|
users: Arena::new(),
|
|
|
|
|
posts: Arena::new(),
|
|
|
|
|
|
|
|
|
|
users_map: HashMap::new(),
|
|
|
|
|
posts_map: HashMap::new(),
|
|
|
|
|
|
|
|
|
|
posts_user_map: HashMap::new(),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Read lock over all posts and users
|
|
|
|
|
pub async fn posts(&self) -> PostsLock<'_>
|
|
|
|
|
{
|
|
|
|
|
PostsLock(self.0.posts.read().await)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> PostsLock<'a>
|
|
|
|
|
{
|
|
|
|
|
/// An iterator over all users in this state
|
|
|
|
|
pub fn users<'b>(&'b self) -> impl Iterator<Item = &'b RwLock<User>> + ExactSizeIterator + 'b
|
|
|
|
|
{
|
|
|
|
|
self.0.users.iter().map(|(_, u)| u)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// An iterator over all posts for this user
|
|
|
|
|
///
|
|
|
|
|
/// # Notes
|
|
|
|
|
/// If this user does not exist, the returned iterator will yield 0 items.
|
|
|
|
|
pub fn posts_for<'b>(&'b self, user: &UserID) -> impl Iterator<Item= &'b RwLock<Post>> + ExactSizeIterator + 'b
|
|
|
|
|
where 'a: 'b
|
|
|
|
|
{
|
|
|
|
|
MaybeIter::from(self.0.posts.get(user).map(|x| x.iter()))
|
|
|
|
|
}
|
|
|
|
|
/// An iterator over all posts in the state
|
|
|
|
|
pub fn all_posts<'b>(&'b self) -> impl Iterator<Item= &'b RwLock<Post>> + 'b
|
|
|
|
|
where 'a: 'b
|
|
|
|
|
{
|
|
|
|
|
self.0.posts.iter().map(|(_, p)| p.iter()).flatten()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|