package base
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Full standard library replacement for OCaml
Install
dune-project
Dependency
Authors
Maintainers
Sources
v0.17.3.tar.gz
md5=2100b0ed13fecf43be86ed45c5b2cc4d
sha512=628610caff7e124631870fa1e29661caac28bdfdb18750ee43b868037da3d65d6dd9023b4be7c4c52405679efb5e865a6632d95606a22b28a36636a6bf706ef3
doc/src/base/hash_intf.ml.html
Source file hash_intf.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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195(** [Hash_intf.S] is the interface which a hash function must support. The functions of [Hash_intf.S] are only allowed to be used in specific sequence: [alloc], [reset ?seed], [fold_..*], [get_hash_value], [reset ?seed], [fold_..*], [get_hash_value], ... (The optional [seed]s passed to each reset may differ.) The chain of applications from [reset] to [get_hash_value] must be done in a single-threaded manner (you can't use [fold_*] on a state that's been used before). More precisely, [alloc ()] creates a new family of states. All functions that take [t] and produce [t] return a new state from the same family. At any point in time, at most one state in the family is "valid". The other states are "invalid". - The state returned by [alloc] is invalid. - The state returned by [reset] is valid (all of the other states become invalid). - The [fold_*] family of functions requires a valid state and produces a valid state (thereby making the input state invalid). - [get_hash_value] requires a valid state and makes it invalid. These requirements are currently formally encoded in the [Check_initialized_correctly] module in bench/bench.ml. *) open! Import0 module type S = sig (** Name of the hash-function, e.g., "internalhash", "siphash" *) val description : string (** [state] is the internal hash-state used by the hash function. *) type state (** [fold_<T> state v] incorporates a value [v] of type <T> into the hash-state, returning a modified hash-state. Implementations of the [fold_<T>] functions may mutate the [state] argument in place, and return a reference to it. Implementations of the fold_<T> functions should not allocate. *) val fold_int : state -> int -> state val fold_int64 : state -> int64 -> state val fold_float : state -> float -> state val fold_string : state -> string -> state (** [seed] is the type used to seed the initial hash-state. *) type seed (** [alloc ()] returns a fresh uninitialized hash-state. May allocate. *) val alloc : unit -> state (** [reset ?seed state] initializes/resets a hash-state with the given [seed], or else a default-seed. Argument [state] may be mutated. Should not allocate. *) val reset : ?seed:seed -> state -> state (** [hash_value] The type of hash values, returned by [get_hash_value]. *) type hash_value (** [get_hash_value] extracts a hash-value from the hash-state. *) val get_hash_value : state -> hash_value module For_tests : sig val compare_state : state -> state -> int val state_to_string : state -> string end end module type Builtin_hash_fold_intf = sig type state type 'a folder = state -> 'a -> state val hash_fold_nativeint : nativeint folder val hash_fold_int64 : int64 folder val hash_fold_int32 : int32 folder val hash_fold_char : char folder val hash_fold_int : int folder val hash_fold_bool : bool folder val hash_fold_string : string folder val hash_fold_float : float folder val hash_fold_unit : unit folder val hash_fold_option : 'a folder -> 'a option folder val hash_fold_list : 'a folder -> 'a list folder val hash_fold_lazy_t : 'a folder -> 'a lazy_t folder (** Hash support for [array] and [ref] is provided, but is potentially DANGEROUS, since it incorporates the current contents of the array/ref into the hash value. Because of this we add a [_frozen] suffix to the function name. Hash support for [string] is also potentially DANGEROUS, but strings are mutated less often, so we don't append [_frozen] to it. Also note that we don't support [bytes]. *) val hash_fold_ref_frozen : 'a folder -> 'a ref folder val hash_fold_array_frozen : 'a folder -> 'a array folder end module type Builtin_hash_intf = sig type hash_value val hash_nativeint : nativeint -> hash_value val hash_int64 : int64 -> hash_value val hash_int32 : int32 -> hash_value val hash_char : char -> hash_value val hash_int : int -> hash_value val hash_bool : bool -> hash_value val hash_string : string -> hash_value val hash_float : float -> hash_value val hash_unit : unit -> hash_value end module type Builtin_intf = sig include Builtin_hash_fold_intf include Builtin_hash_intf end module type Full = sig include S (** @inline *) type 'a folder = state -> 'a -> state (** [create ?seed ()] is a convenience. Equivalent to [reset ?seed (alloc ())]. *) val create : ?seed:seed -> unit -> state (** [of_fold fold] constructs a standard hash function from an existing fold function. *) val of_fold : (state -> 'a -> state) -> 'a -> hash_value module Builtin : Builtin_intf with type state := state and type 'a folder := 'a folder and type hash_value := hash_value (** [run ?seed folder x] runs [folder] on [x] in a newly allocated hash-state, initialized using optional [seed] or a default-seed. The following identity exists: [run [%hash_fold: T]] == [[%hash: T]] [run] can be used if we wish to run a hash-folder with a non-default seed. *) val run : ?seed:seed -> 'a folder -> 'a -> hash_value end module type Hash = sig module type Full = Full module type S = S module F (Hash : S) : Full with type hash_value = Hash.hash_value and type state = Hash.state and type seed = Hash.seed (** The code of [ppx_hash] is agnostic to the choice of hash algorithm that is used. However, it is not currently possible to mix various choices of hash algorithms in a given code base. We experimented with: - (a) custom hash algorithms implemented in OCaml and - (b) in C; - (c) OCaml's internal hash function (which is a custom version of Murmur3, implemented in C); - (d) siphash, a modern hash function implemented in C. Our findings were as follows: - Implementing our own custom hash algorithms in OCaml and C yielded very little performance improvement over the (c) proposal, without providing the benefit of being a peer-reviewed, widely used hash function. - Siphash (a modern hash function with an internal state of 32 bytes) has a worse performance profile than (a,b,c) above (hashing takes more time). Since its internal state is bigger than an OCaml immediate value, one must either manage allocation of such state explicitly, or paying the cost of allocation each time a hash is computed. While being a supposedly good hash function (with good hash quality), this quality was not translated in measurable improvements in our macro benchmarks. (Also, based on the data available at the time of writing, it's unclear that other hash algorithms in this class would be more than marginally faster.) - By contrast, using the internal combinators of OCaml hash function means that we do not allocate (the internal state of this hash function is 32 bit) and have the same quality and performance as Hashtbl.hash. Hence, we are here making the choice of using this Internalhash (that is, Murmur3, the OCaml hash algorithm as of 4.03) as our hash algorithm. It means that the state of the hash function does not need to be preallocated, and makes for simpler use in hash tables and other structures. *) (** @open *) include Full with type state = Base_internalhash_types.state and type seed = Base_internalhash_types.seed and type hash_value = Base_internalhash_types.hash_value end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>