Well that's a lot simpler
This commit is contained in:
parent
78a5d3577c
commit
7924fd14d9
2 changed files with 10 additions and 41 deletions
15
README.org
15
README.org
|
@ -1,7 +1,7 @@
|
||||||
* Guile Weak References
|
* Guile Weak References
|
||||||
|
|
||||||
This is a simple little library that makes use of the weak hash table functionality in core Guile
|
This is a simple little library that makes use of the weak vector functionality in core Guile
|
||||||
to hackily implement weak references, objects which weakly point to other objects.
|
to implement weak references, objects which weakly point to other objects.
|
||||||
|
|
||||||
The interface is very simple:
|
The interface is very simple:
|
||||||
|
|
||||||
|
@ -12,11 +12,6 @@ The interface is very simple:
|
||||||
- Get the object associated with the reference, or #f if it has been garbage collected.
|
- Get the object associated with the reference, or #f if it has been garbage collected.
|
||||||
|
|
||||||
** Implementation
|
** Implementation
|
||||||
This is a very simple implementation. There's a globally incremented ID associated with each object, and
|
This is a very simple implementation (thanks David Thompson for a simpler idea). It simply calls a single-
|
||||||
the object is stored in two global weak hash tables, one id-to-object and another object-to-id. The weak
|
element weak vector a weak reference. Initially this used the weak hash table support but using a weak
|
||||||
reference is a record type that stores the ID and also a tombstone property to cache whether the object
|
vector is far simpler and uses less memory.
|
||||||
has been collected to avoid the need to look it up after that point.
|
|
||||||
|
|
||||||
I created this because I needed an interface outside of the hash tables to refer to single objects instead
|
|
||||||
of creating a bunch of weak dictionaries. Also, Guile Hoot does not yet support iteration through weak key
|
|
||||||
hash tables, so this will allow me to create a list of weak refs to iterate over instead.
|
|
||||||
|
|
36
weakref.scm
36
weakref.scm
|
@ -1,40 +1,14 @@
|
||||||
(define-module (weakref)
|
(define-module (weakref)
|
||||||
#:use-module (srfi srfi-9)
|
#:use-module (ice-9 weak-vector)
|
||||||
#:use-module (srfi srfi-9 gnu)
|
|
||||||
#:use-module (srfi srfi-64)
|
|
||||||
#:export (make-weakref
|
#:export (make-weakref
|
||||||
weakref?
|
weakref?
|
||||||
weakref-object))
|
weakref-object))
|
||||||
|
|
||||||
(define *next-id* 0)
|
(define (weakref? obj)
|
||||||
(define *ids-to-objects* (make-weak-value-hash-table))
|
(and (weak-vector? obj) (= 1 (vector-length obj))))
|
||||||
(define *objects-to-ids* (make-weak-key-hash-table))
|
|
||||||
|
|
||||||
(define-record-type <weakref>
|
|
||||||
(_make-weakref id tombstone)
|
|
||||||
weakref?
|
|
||||||
(id weakref-id)
|
|
||||||
(tombstone weakref-tombstone set-weakref-tombstone!))
|
|
||||||
|
|
||||||
(set-record-type-printer!
|
|
||||||
<weakref>
|
|
||||||
(lambda (ref port)
|
|
||||||
(format port "#<weakref: ~a id=~a>" (or (weakref-object ref) "[gone]") (weakref-id ref))))
|
|
||||||
|
|
||||||
(define (make-weakref obj)
|
(define (make-weakref obj)
|
||||||
(_make-weakref
|
(make-weak-vector 1 obj))
|
||||||
(or (hashq-ref *objects-to-ids* obj)
|
|
||||||
(let ((id *next-id*))
|
|
||||||
(set! *next-id* (1+ *next-id*))
|
|
||||||
(hashq-set! *ids-to-objects* id obj)
|
|
||||||
(hashq-set! *objects-to-ids* obj id)
|
|
||||||
id))
|
|
||||||
#f))
|
|
||||||
|
|
||||||
(define (weakref-object ref)
|
(define (weakref-object ref)
|
||||||
(if (weakref-tombstone ref)
|
(weak-vector-ref ref 0))
|
||||||
#f
|
|
||||||
(or (hashq-ref *ids-to-objects* (weakref-id ref))
|
|
||||||
(begin
|
|
||||||
(set-weakref-tombstone! ref #t)
|
|
||||||
#f))))
|
|
||||||
|
|
Loading…
Reference in a new issue