xssbook/src/cache.js

277 lines
6.5 KiB
JavaScript
Raw Normal View History

2023-01-24 02:40:41 +00:00
const e = require('express')
const database = require('./database.js')
const con = require('./console')
const NO_VALUE = null
const NO_CACHE = undefined
const users = {}
const email_links = {}
const password_links = {}
const session_links = {}
var newest_user = database.getNewestUserId();
const getUserByEmail = (email) => {
const fast = email_links[email]
if (fast === NO_VALUE) {
return undefined
}
if (fast === NO_CACHE) {
const slow = database.getUserByEmail(email)
if (slow === undefined) {
email_links[email] = NO_VALUE
} else {
email_links[email] = slow.id
if (users[slow.id] === NO_CACHE) {
users[slow.id] = slow
}
}
return slow
}
return users[fast]
}
const getUserByPassword = (password) => {
const fast = password_links[password]
if (fast === NO_VALUE) {
return undefined
}
if (fast === NO_CACHE) {
const slow = database.getUserByPassword(password)
if (slow === undefined) {
password_links[password] = NO_VALUE
} else {
password_links[password] = slow.id
if (users[slow.id] === NO_CACHE) {
users[slow.id] = slow
}
}
return slow
}
return users[fast]
}
const getUsers = (ids) => {
const fast = {}
const batch = []
for (const id of ids) {
if (users[id] === NO_CACHE) {
batch.push(id)
} else {
fast[id] = users[id]
}
}
if (batch.length > 0) {
const slow = database.getUsers(batch)
for(const [id, user] of Object.entries(slow)) {
fast[id] = user
}
}
return fast
}
const getUsersPage = (page) => {
const COUNT = 10
const INDEX = newest_user - page * COUNT
const batch = []
for (let i = INDEX; i > INDEX - COUNT && i >= 0; i--) {
batch.push(i)
}
const users = getUsers(batch)
return batch.map(i => users[i]).filter(u => u !== undefined)
}
const register = (first, last, email, password, gender, month, day, year) => {
const data = database.register(first, last, email, password, gender, month, day, year)
if (data === undefined) {
return undefined
}
newest_user = data.user.id
session_links[data.key] = data.user.id
users[data.user.id] = data.user
return data.key
}
const login = (email, pass) => {
const data = database.login(email, pass)
if (data === undefined) {
return undefined
}
session_links[data.key] = data.user.id
users[data.user.id] = data.user
return data.key
}
const logout = (token) => {
if (session_links[token] === NO_VALUE) {
return false
}
if (!database.deleteSession(token)) {
return false
}
delete session_links[token]
return true
}
const auth = (token) => {
const fast = session_links[token]
if (fast === NO_VALUE) {
return undefined
}
if (fast === NO_CACHE) {
const slow = database.auth(token)
if (slow === undefined) {
session_links[token] = NO_VALUE
} else {
session_links[token] = slow.id
if (users[slow.id] === NO_CACHE) {
users[slow.id] = slow
}
}
return slow
}
return users[fast]
}
const posts = {}
const users_posts = {}
const updated_posts = {}
var newest_post = database.getNewestPostId();
const addPost = (user, content) => {
const id = database.addPost(user, content)
if (id === undefined) {
return -1
}
newest_post = id
if (users_posts[user] === NO_VALUE) {
users[posts] = [id]
} else if (users_posts[user] === NO_CACHE) {
getUsersPosts(user)
} else {
users_posts[user].unshift(id)
}
return id
}
const getPosts = (ids) => {
const fast = {}
const batch = []
for (const id of ids) {
if (posts[id] === NO_CACHE) {
batch.push(id)
} else {
fast[id] = posts[id]
}
}
if (batch.length > 0) {
const slow = database.getPosts(batch)
for(const [id, post] of Object.entries(slow)) {
fast[id] = post
}
}
return fast
}
const getUsersPosts = (user) => {
const fast = users_posts[user]
if (fast === NO_CACHE) {
const posts = database.getUsersPosts(user)
if (posts === undefined) {
users_posts[user] = NO_VALUE
} else {
const slow = []
for (const post in posts) {
slow.push[post.id]
if (posts[post.id] === NO_CACHE) {
posts[post.id] = post
}
}
users_posts[user] = slow
}
return posts
} else {
return getPosts(fast)
}
}
const getPostsPage = (page) => {
const COUNT = 10
const INDEX = newest_post - page * COUNT
const batch = []
for (let i = INDEX; i > INDEX - COUNT && i >= 0; i--) {
batch.push(i)
}
const posts = getPosts(batch)
return batch.map(i => posts[i]).filter(p => p !== undefined)
}
const comment = (id, user, content) => {
var fast = posts[id]
if (fast === NO_VALUE) {
return false
} else if (fast === NO_CACHE) {
const slow = getPosts([id])
if (slow[id] === undefined) {
return false
} else {
fast = slow[id]
}
}
fast.comments.push({user, content})
posts[id] = fast
updated_posts[id] = true
return true
}
const like = (id, user, state) => {
var fast = posts[id]
if (fast === NO_VALUE) {
return false
} else if (fast === NO_CACHE) {
const slow = getPosts([id])
if (slow[id] === undefined) {
return false
} else {
fast = slow[id]
}
}
fast.likes[user] = state
posts[id] = fast
updated_posts[id] = true
return true
}
const dump = () => {
for (id in updated_posts) {
const post = posts[id]
if (post === NO_CACHE || post === NO_VALUE) continue;
if (!database.updatePost(post.id, JSON.stringify(post.likes), JSON.stringify(post.comments))) {
con.error(`Failed to saved cached post id ${id}`)
} else {
delete updated_posts.id
}
}
con.msg('Saved cache successfully')
}
module.exports = {
getUserByEmail,
getUserByPassword,
getUsers,
getUsersPage,
register,
login,
logout,
auth,
addPost,
getPosts,
getUsersPosts,
getPostsPage,
comment,
like,
dump
}