diff --git a/README.org b/README.org index 90cab62..39b7746 100644 --- a/README.org +++ b/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. diff --git a/weakref.scm b/weakref.scm index 51c3507..e553345 100644 --- a/weakref.scm +++ b/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 - (_make-weakref id tombstone) - weakref? - (id weakref-id) - (tombstone weakref-tombstone set-weakref-tombstone!)) - -(set-record-type-printer! - - (lambda (ref port) - (format port "#" (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))