package server-reason-react

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

Source file Belt_internalSetBuckets.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
module C = Belt_internalBucketsType

include (
  struct
    type 'a bucket = { mutable key : 'a; mutable next : 'a bucket C.opt }
    and ('hash, 'eq, 'a) t = ('hash, 'eq, 'a bucket) C.container

    let bucket : key:'a -> next:'a bucket C.opt -> 'a bucket =
     fun ~key ~next -> { key; next }

    let keySet : 'a bucket -> 'a -> unit = fun o v -> o.key <- v
    let key : 'a bucket -> 'a = fun o -> o.key
    let nextSet : 'a bucket -> 'a bucket C.opt -> unit = fun o v -> o.next <- v
    let next : 'a bucket -> 'a bucket C.opt = fun o -> o.next
  end :
    sig
      type 'a bucket
      and ('hash, 'eq, 'a) t = ('hash, 'eq, 'a bucket) C.container

      val bucket : key:'a -> next:'a bucket C.opt -> 'a bucket
      val keySet : 'a bucket -> 'a -> unit
      val key : 'a bucket -> 'a
      val nextSet : 'a bucket -> 'a bucket C.opt -> unit
      val next : 'a bucket -> 'a bucket C.opt
    end)

module A = Belt_Array

let rec copy (x : _ t) : _ t =
  C.container ~hash:(C.hash x) ~eq:(C.eq x) ~size:(C.size x)
    ~buckets:(copyBuckets (C.buckets x))

and copyBuckets (buckets : _ bucket C.opt array) =
  let len = A.length buckets in
  let newBuckets =
    if len > 0 then A.makeUninitializedUnsafe len (A.getUnsafe buckets 0)
    else [||]
  in
  for i = 0 to len - 1 do
    A.setUnsafe newBuckets i (copyBucket (A.getUnsafe buckets i))
  done;
  newBuckets

and copyBucket c =
  match C.toOpt c with
  | None -> c
  | Some c ->
      let head = bucket ~key:(key c) ~next:C.emptyOpt in
      copyAuxCont (next c) head;
      C.return head

and copyAuxCont c prec =
  match C.toOpt c with
  | None -> ()
  | Some nc ->
      let ncopy = bucket ~key:(key nc) ~next:C.emptyOpt in
      nextSet prec (C.return ncopy);
      copyAuxCont (next nc) ncopy

let rec bucketLength accu buckets =
  match C.toOpt buckets with
  | None -> accu
  | Some cell -> bucketLength (accu + 1) (next cell)

let rec doBucketIter ~f buckets =
  match C.toOpt buckets with
  | None -> ()
  | Some cell ->
      f (key cell);
      doBucketIter ~f (next cell)

let forEachU h f =
  let d = C.buckets h in
  for i = 0 to A.length d - 1 do
    doBucketIter f (A.getUnsafe d i)
  done

let forEach h f = forEachU h (fun a -> f a)

let rec fillArray i arr cell =
  A.setUnsafe arr i (key cell);
  match C.toOpt (next cell) with
  | None -> i + 1
  | Some v -> fillArray (i + 1) arr v

let toArray h =
  let d = C.buckets h in
  let current = ref 0 in
  let arr = ref None in
  for i = 0 to A.length d - 1 do
    let cell = A.getUnsafe d i in
    match C.toOpt cell with
    | None -> ()
    | Some cell ->
        let arr =
          match !arr with
          | None ->
              let a = A.makeUninitializedUnsafe (C.size h) (key cell) in
              arr := Some a;
              a
          | Some arr -> arr
        in
        current := fillArray !current arr cell
  done;
  match !arr with None -> [||] | Some arr -> arr

let rec doBucketFold ~f b accu =
  match C.toOpt b with
  | None -> accu
  | Some cell -> doBucketFold ~f (next cell) (f accu (key cell))

let reduceU h init f =
  let d = C.buckets h in
  let accu = ref init in
  for i = 0 to A.length d - 1 do
    accu := doBucketFold ~f (A.getUnsafe d i) !accu
  done;
  !accu

let reduce h init f = reduceU h init (fun a b -> f a b)

let getMaxBucketLength h =
  A.reduceU (C.buckets h) 0 (fun m b ->
      let len = bucketLength 0 b in
      Stdlib.max m len)

let getBucketHistogram h =
  let mbl = getMaxBucketLength h in
  let histo = A.makeByU (mbl + 1) (fun _ -> 0) in
  A.forEachU (C.buckets h) (fun b ->
      let l = bucketLength 0 b in
      A.setUnsafe histo l (A.getUnsafe histo l + 1));
  histo

let logStats h =
  let histogram = getBucketHistogram h in
  Printf.printf "{\n\tbindings: %d,\n\tbuckets: %d\n\thistogram: %s\n}"
    (C.size h)
    (A.length (C.buckets h))
    (A.reduceU histogram "" (fun acc x -> acc ^ string_of_int x))
OCaml

Innovation. Community. Security.