Imandrakit_twine.Encode
module Immediate = Immediate
type immediate = Immediate.t
val create : unit -> t
New encoder.
write_immediate enc i
writes down i
and returns an immediate pointer to it
write_or_deref_immediate enc i
looks at i
, and if i
is Pointer p
, it returns p
; otherwise it writes down i
and returns a pointer to it.
val finalize : t -> entrypoint:immediate -> Imandrakit_bytes.Byte_slice.t
Finalize by writing the entrypoint, and get the result as a byte slice
Finalize, and get a copy of the result. See finalize
val encode_to_string : 'a encoder -> 'a -> string
Full entrypoint
val to_string : 'a encoder -> 'a -> string
Caching is used to create/preserve sharing in the encoded slice, by actively storing, in a hashtable, the offset where a value was previously encoded.
val create_cache_key :
(module Stdlib.Hashtbl.HashedType with type t = 'a) ->
'a cache_key
Create a new (generative) cache key for a hashable + comparable type.
NOTE this should be called only at module toplevel, as a constant, not dynamically inside a function: let key = create_cache_key (module …);;
. Indeed, this is generative, so creating multiple keys for a type will result in sub-par or inexistant caching.
with_cache key enc
is the same encoder as enc
, but with caching. When encoding a value x:'a
, the cache key
is used to detect if x
was already encoded to some entry, and uses a pointer to this entry instead of re-serializing x
.
val add_cache :
?max_string_size:int ->
(module Stdlib.Hashtbl.HashedType with type t = 'a) ->
'a encoder ref ->
unit
add_cache (module …) enc_ref
modifies the given encoder so that it goes through a layer of caching. This is the same as:
let key = create_cache_key (module …)
let () = enc_ref := with_cache key !enc_ref