Skip to content

Commit

Permalink
wip: clear view cache on server update
Browse files Browse the repository at this point in the history
  • Loading branch information
voodoos committed Aug 19, 2024
1 parent 2dbefb8 commit 39012da
Showing 1 changed file with 61 additions and 59 deletions.
120 changes: 61 additions & 59 deletions bin/db_worker/db_worker.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,19 @@ let fut_of_array (fs : 'a Fut.t array) : 'a array Fut.t =
Obj.magic @@ fut @@ Jv.Promise.bind all to_array

module Worker () = struct
let view_memo :
( string Db.View.selection * Db.View.Sort.t,
IS.Content.Key.t array )
Hashtbl.t =
Hashtbl.create 64

let last_view : (int * IS.Content.Key.t array) ref = ref (-1, [||])

let check_db idb source =
let server_id, source = source in
let report status =
Hashtbl.clear view_memo;
last_view := (-1, [||]);
dispatch_event Servers_status_update (server_id, status)
in
Db.Sync.check_and_sync ~report ~source idb
Expand All @@ -44,66 +54,58 @@ module Worker () = struct
IDB.Database.transaction [ (module Db.I) ] ~mode:Readonly idb
|> IDB.Transaction.object_store (module Db.I)

let get_view_keys =
let view_memo :
( string Db.View.selection * Db.View.Sort.t,
IS.Content.Key.t array )
Hashtbl.t =
Hashtbl.create 64
in
let last_view : (int * IS.Content.Key.t array) ref = ref (-1, [||]) in
fun store { Db.View.kind = _; src_views; sort; filters } ->
(* todo: staged memoization + specialized queries using indexes *)
let open Fut.Result_syntax in
let hash = Hashtbl.hash (src_views, sort, filters) in
if Int.equal (fst !last_view) hash then Fut.ok (snd !last_view)
else
let+ keys =
try Fut.ok @@ Hashtbl.find view_memo (src_views, sort)
with Not_found ->
let+ all_keys =
let lower = Jv.of_array Jv.of_string [| "Audio" |] in
let upper = Jv.of_array Jv.of_string [| "Audio\u{0}" |] in
let query =
IDB.Key_range.bound ~lower ~upper ~lower_open:true
~upper_open:false ()
in
let idx = IS.index (module IS.Index.Kind_View) store in
IS.Index.Kind_View.get_all_keys ~query idx |> as_fut
in
let keys =
match src_views with
| All -> all_keys
| Only src_views ->
Array.filter all_keys
~f:(fun { Db.Stores.Items.Key.views; _ } ->
List.exists views ~f:(fun v -> List.memq v ~set:src_views))
let get_view_keys store { Db.View.kind = _; src_views; sort; filters } =
(* todo: staged memoization + specialized queries using indexes *)
let open Fut.Result_syntax in
let hash = Hashtbl.hash (src_views, sort, filters) in
if Int.equal (fst !last_view) hash then Fut.ok (snd !last_view)
else
let+ keys =
try Fut.ok @@ Hashtbl.find view_memo (src_views, sort)
with Not_found ->
let+ all_keys =
let lower = Jv.of_array Jv.of_string [| "Audio" |] in
let upper = Jv.of_array Jv.of_string [| "Audio\u{0}" |] in
let query =
IDB.Key_range.bound ~lower ~upper ~lower_open:true
~upper_open:false ()
in
Hashtbl.add view_memo (src_views, sort) keys;
keys
in
let keys =
match filters with
| [ Search sub ] when not (String.is_empty sub) ->
let sub = String.lowercase_ascii sub in
Array.filter keys ~f:(fun { Db.Stores.Items.Key.sort_name; _ } ->
let sort_name = String.lowercase_ascii sort_name in
let pattern = String.Find.compile (Printf.sprintf "%s" sub) in
String.Find.find ~pattern sort_name >= 0)
| _ -> keys
in
let () =
match sort with
| Name ->
Array.sort keys
~cmp:(fun
{ Db.Stores.Items.Key.sort_name = sna; _ }
{ Db.Stores.Items.Key.sort_name = snb; _ }
-> String.compare sna snb)
| _ -> ()
in
last_view := (hash, keys);
keys
let idx = IS.index (module IS.Index.Kind_View) store in
IS.Index.Kind_View.get_all_keys ~query idx |> as_fut
in
let keys =
match src_views with
| All -> all_keys
| Only src_views ->
Array.filter all_keys
~f:(fun { Db.Stores.Items.Key.views; _ } ->
List.exists views ~f:(fun v -> List.memq v ~set:src_views))
in
Hashtbl.add view_memo (src_views, sort) keys;
keys
in
let keys =
match filters with
| [ Search sub ] when not (String.is_empty sub) ->
let sub = String.lowercase_ascii sub in
Array.filter keys ~f:(fun { Db.Stores.Items.Key.sort_name; _ } ->
let sort_name = String.lowercase_ascii sort_name in
let pattern = String.Find.compile (Printf.sprintf "%s" sub) in
String.Find.find ~pattern sort_name >= 0)
| _ -> keys
in
let () =
match sort with
| Name ->
Array.sort keys
~cmp:(fun
{ Db.Stores.Items.Key.sort_name = sna; _ }
{ Db.Stores.Items.Key.sort_name = snb; _ }
-> String.compare sna snb)
| _ -> ()
in
last_view := (hash, keys);
keys

let on_query (type a) (q : a query) : (a, error) Fut.result =
let open Fut.Result_syntax in
Expand Down

0 comments on commit 39012da

Please sign in to comment.