From: Lindsay Errington <lindsay.errington@gmail.com>
To: caml-list@inria.fr
Subject: [Caml-list] Possible ephemeron bug?
Date: Wed, 19 Dec 2018 16:29:48 -0800 [thread overview]
Message-ID: <CAPeKkNi9P2_vGxeYgybpffz7W2S5tMV2oeTsPHv5jOes=_gbGA@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 2566 bytes --]
I'm trying to implement weak functional maps with ephemerons. Within the
repl, things work fine. When I use the native or bytecode compilers, it
looks like some things are not being collected.
To illustrate, I'll use maps implemented as association lists. Complete
source at https://gist.github.com/dlindsaye/66afcdef6f381e955d8c66773365d4d6
Keys are boxed integers:
> type key = Key of int
Values are elements of an algebraic type with references to keys:
> type value =
> | Str of string
> | Link of key
Elements of the association list are key/value pairs wrapped in an
ephemeron:
> module Eph = Ephemeron.K1
> type pair = (key,value) Eph.t
> let mk_pair key value =
> let eph = Eph.create () in
> Eph.set_key eph key;
> Eph.set_data eph value;
> eph
The following adds a new key/value pair to the assoc list:
> let intern idx value map =
> let key = Key idx in
> let eph = mk_pair key value in
> let map = eph::map in
> (key,map)
Next a function to update a key/value pair:
> let rec upd key new_value map =
> match map with
> | [] -> raise Not_found
> | pair::rest ->
> begin
> match Eph.get_key pair with
> | Some other_key when eq_key key other_key ->
> let eph = mk_pair key new_value in
> eph::rest
> | _ -> pair::(upd key new_value rest)
> end
Next, create a list of pairs:
> let str n = Str (String.make n '#');; (* Ensure value is boxed *)
> let (root,map) =
> let map = [] in
> let (k0,map) = intern 0 (str 1) map in
> let (k1,map) = intern 1 (Link k0) map in
> let (k2,map) = intern 2 (Link k1) map in
> (k2,map);;
Printing this yields:
> root=(Key 2), map=(Eph ((Key 2),(Link (Key 1))))
> (Eph ((Key 1),(Link (Key 0))))
> (Eph ((Key 0),(Str #)))
Next, update the root of the tree:
> let map = upd root (str 2) map;;
Which correctly binds (Key 2) to a string of length 2:
> root=(Key 2) map1=(Eph ((Key 2),(Str ##)))
> (Eph ((Key 1),(Link (Key 0))))
> (Eph ((Key 0),(Str #)))
Invoking gc from within the repl and printing again yields:
> Gc.full_major ();;
> root=(Key 2) map1=(Eph ((Key 2),(Str ##)))
> (Eph (None,None))
> (Eph (None,None))
which is exactly what one would expect. If however, I use the standalone
bytecode compiler or the native compiler (4.07.1), then the entries are not
nullified. Is this a bug or is there another way to persuade the garbage
collector to clobber the entries?
Thanks
Lindsay
[-- Attachment #2: Type: text/html, Size: 5492 bytes --]
next reply other threads:[~2018-12-20 0:30 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-20 0:29 Lindsay Errington [this message]
2018-12-20 9:46 ` Stephen Dolan
2018-12-20 17:40 ` Lindsay Errington
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAPeKkNi9P2_vGxeYgybpffz7W2S5tMV2oeTsPHv5jOes=_gbGA@mail.gmail.com' \
--to=lindsay.errington@gmail.com \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox