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
|
||||
|
||||
This is a simple little library that makes use of the weak hash table functionality in core Guile
|
||||
to hackily implement weak references, objects which weakly point to other objects.
|
||||
This is a simple little library that makes use of the weak vector functionality in core Guile
|
||||
to implement weak references, objects which weakly point to other objects.
|
||||
|
||||
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.
|
||||
|
||||
** Implementation
|
||||
This is a very simple implementation. There's a globally incremented ID associated with each object, and
|
||||
the object is stored in two global weak hash tables, one id-to-object and another object-to-id. The weak
|
||||
reference is a record type that stores the ID and also a tombstone property to cache whether the object
|
||||
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.
|
||||
This is a very simple implementation (thanks David Thompson for a simpler idea). It simply calls a single-
|
||||
element weak vector a weak reference. Initially this used the weak hash table support but using a weak
|
||||
vector is far simpler and uses less memory.
|
||||
|
|
36
weakref.scm
36
weakref.scm
|
@ -1,40 +1,14 @@
|
|||
(define-module (weakref)
|
||||
#:use-module (srfi srfi-9)
|
||||
#:use-module (srfi srfi-9 gnu)
|
||||
#:use-module (srfi srfi-64)
|
||||
#:use-module (ice-9 weak-vector)
|
||||
#:export (make-weakref
|
||||
weakref?
|
||||
weakref-object))
|
||||
|
||||
(define *next-id* 0)
|
||||
(define *ids-to-objects* (make-weak-value-hash-table))
|
||||
(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 (weakref? obj)
|
||||
(and (weak-vector? obj) (= 1 (vector-length obj))))
|
||||
|
||||
(define (make-weakref obj)
|
||||
(_make-weakref
|
||||
(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))
|
||||
(make-weak-vector 1 obj))
|
||||
|
||||
(define (weakref-object ref)
|
||||
(if (weakref-tombstone ref)
|
||||
#f
|
||||
(or (hashq-ref *ids-to-objects* (weakref-id ref))
|
||||
(begin
|
||||
(set-weakref-tombstone! ref #t)
|
||||
#f))))
|
||||
(weak-vector-ref ref 0))
|
||||
|
|
Loading…
Reference in a new issue