start major state rework

new-idea
Avril 4 years ago
parent a057022d48
commit f8efb25c30
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -77,6 +77,9 @@ pub struct Post
/// Unique ID for each post
id: PostID,
/// Who created the post, (if specified)
owner: Option<user::UserID>,
/// Identifiers for this post
ident: Ident,
@ -220,6 +223,7 @@ mod tests
{
use std::convert::TryInto;
let post = super::Post {
owner: None,
id: super::PostID::id_new(),
ident: super::Ident {
name: Some("Some name".to_owned().try_into().unwrap()),

@ -1,17 +1,19 @@
//! Frozen, serialisable state
use super::*;
use futures::prelude::*;
use std::io;
use tokio::prelude::*;
//use futures::prelude::*;
//use std::io;
//use tokio::prelude::*;
/// An immutable image of `State`.
//TODO: Implement this when `State` is solidified and working
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Freeze
{
users: HashSet<User>,
posts: Vec<(UserID, Post)>,
posts: HashSet<Post>,
}
/*
/// Reading and writing state
//TODO: Compression
impl Freeze
@ -203,3 +205,4 @@ impl TryFrom<State> for Freeze
from.try_into_freeze()
}
}
*/

@ -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()
}
}

Loading…
Cancel
Save