open Types let session : session option ref = ref None let update_session (v : session) = session := Some v; () let get_session () = match !session with | None -> Fmt.failwith "called get_session with uninitialized session" | Some v -> v let post_db : (post_id, post) Hashtbl.t = Hashtbl.create 0x1000 let add_post (v : post) = Hashtbl.replace post_db v.id v; () let find_post id = match Hashtbl.find_opt post_db id with None -> None | Some v -> Some v let post_db_404 : (post_id, unit) Hashtbl.t = Hashtbl.create 0x100 let post_is_404 id = Hashtbl.mem post_db_404 id let thread_is_404 id = Hashtbl.mem post_db_404 id let user_db_404 : (user_id, unit) Hashtbl.t = Hashtbl.create 0x100 let user_is_404 id = Hashtbl.mem user_db_404 id let catalog : thread list ref = ref [] let update_catalog (v : thread list) = catalog := v; () let get_catalog () = !catalog let thread_w_reply : Thread_w_reply.t option ref = ref None let update_thread_w_reply (o : Thread_w_reply.t option) = Hashtbl.clear post_db; thread_w_reply := o; Option.iter (fun v -> List.iter add_post v.Thread_w_reply.reply_l) o; () let find_thread_w_reply id = match !thread_w_reply with | None -> None | Some v -> ( match v.op.id = id with false -> None | true -> Some v ) let reports : report list ref = ref [] let update_reports (v : report list) = reports := v; () let get_reports () = !reports let user : user option ref = ref None let update_user (v : user option) = user := v; () let find_user id = match !user with | None -> None | Some v -> ( match String.equal v.user_id id with false -> None | true -> Some v ) let clear () = session := None; update_catalog []; update_thread_w_reply None; update_reports []; Hashtbl.clear post_db; Hashtbl.clear post_db_404; update_user None; () let add_post_404 id = (* in case post is a thread we have to remove id + potential reply_l *) let to_delete_l = match find_thread_w_reply id with | Some v -> List.map (fun p -> p.id) v.reply_l | None -> [ id ] in let filter get_id l = (* O(n^2) ~~ *) List.filter (fun v -> not @@ List.mem (get_id v) to_delete_l) l in update_catalog (get_catalog () |> filter (fun v -> v.op.id)); update_thread_w_reply ( match find_thread_w_reply id with | Some _ -> None | None -> ( match !thread_w_reply with | None -> None | Some v -> let v = { v with reply_l = filter (fun v -> v.id) v.reply_l } in Some v ) ); update_reports (!reports |> filter (fun r -> r.reported_post.id)); Hashtbl.remove post_db id; Hashtbl.add post_db_404 id (); () let add_thread_404 = add_post_404 let add_user_404 id = let session = get_session () in let session = match session.user_private with | Some u when String.equal u.user_id id -> (* dead session here *) { session with user_private = None } | _ -> session in update_session session; begin match find_user id with Some _ -> update_user None | None -> () end; ()