package incremental

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file incr_memoize.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
open Core

module Store_params = struct
  type 'a t =
    | None : _ t
    | Map : { comparator : ('a, _) Comparator.Module.t } -> 'a t
    | Alist_lru :
        { equal : 'a -> 'a -> bool
        ; max_size : int
        }
        -> 'a t
    | Hashmap_lru :
        { lru : (module Lru_cache.S with type key = 'a)
        ; max_size : int
        }
        -> 'a t
    | With_hooks :
        { inner : 'a t
        ; if_found : 'a -> unit
        ; if_added : 'a -> unit
        }
        -> 'a t

  let map_based__store_forever comparator = Map { comparator }

  let alist_based__lru ~equal ~max_size =
    assert (max_size > 0);
    Alist_lru { equal; max_size }
  ;;

  let with_hooks inner ~if_found ~if_added = With_hooks { inner; if_found; if_added }

  let hash_based__lru
    (type key)
    ~max_size
    (module Key : Hashtbl.Key_plain with type t = key)
    : key t
    =
    let module Key : Lru_cache.H with type t = Key.t = struct
      include Key

      let invariant (_ : t) = ()
    end
    in
    let lru = (module Lru_cache.Make (Key) : Lru_cache.S with type key = Key.t) in
    Hashmap_lru { lru; max_size }
  ;;

  let none = None
end

module Store = struct
  type ('k, 'v) t =
    { find : 'k -> 'v option
    ; add : key:'k -> value:'v -> unit
    }

  let find_or_add t ~key ~default =
    match t.find key with
    | Some value -> `Found, value
    | None ->
      let value = default () in
      t.add ~key ~value;
      `Added, value
  ;;

  let find t key = t.find key
  let add t ~key ~value = t.add ~key ~value

  let rec create : type k. k Store_params.t -> (k, _) t =
    fun params ->
    match params with
    | None ->
      let find _ = None in
      let add ~key:_ ~value:_ = () in
      { find; add }
    | Map { comparator } ->
      let cache = ref (Map.empty comparator) in
      let find key = Map.find !cache key in
      let add ~key ~value = cache := Map.set !cache ~key ~data:value in
      { find; add }
    | Alist_lru { equal; max_size } ->
      let cache = ref [] in
      let find key =
        match List.Assoc.find !cache ~equal key with
        | Some value ->
          cache := (key, value) :: List.Assoc.remove !cache ~equal key;
          Some value
        | None -> None
      in
      let add ~key ~value = cache := (key, value) :: List.take !cache (max_size - 1) in
      { find; add }
    | Hashmap_lru { lru; max_size } ->
      let (module Lru : Lru_cache.S with type key = k) = lru in
      let cache = Lru.create ~max_size () in
      let find key = Lru.find cache key in
      let add ~key ~value = Lru.set cache ~key ~data:value in
      { find; add }
    | With_hooks { inner; if_found; if_added } ->
      let inner = create inner in
      let find key =
        let res = inner.find key in
        if Option.is_some res then if_found key;
        res
      in
      let add ~key ~value =
        inner.add ~key ~value;
        if_added key
      in
      { find; add }
  ;;
end

module Make (Incr : Incremental.S) = struct
  module Incr_with_store_params = struct
    type 'a t = 'a Incr.t * 'a Store_params.t
  end

  let with_params = Tuple2.create

  let bind (type a) ((x, store_params) : a Incr_with_store_params.t) ~(f : a -> 'b Incr.t)
    : 'b Incr.t
    =
    let scope = Incr.Scope.current () in
    let store = Store.create store_params in
    let%bind.Incr x = x in
    let default () = Incr.Scope.within scope ~f:(fun () -> f x) in
    let (`Found | `Added), graph = Store.find_or_add store ~key:x ~default in
    graph
  ;;

  let ( >>= ) = bind

  module Let_syntax = struct
    module Let_syntax = struct
      let bind = bind
    end
  end

  module Store_params = Store_params
  module Store = Store
end
OCaml

Innovation. Community. Security.