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
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))