lru manager

svn: r3483
This commit is contained in:
Jay McCarthy 2006-06-26 21:17:00 +00:00
parent b7b58486ec
commit 2bf8937e7b

View File

@ -0,0 +1,147 @@
(module lru mzscheme
(require (lib "plt-match.ss"))
(require "manager.ss")
(provide create-LRU-manager)
;; Utility
(define (make-counter)
(define i 0)
(lambda ()
(set! i (add1 i))
i))
(define-struct (LRU-manager manager) (instance-expiration-handler
; Private
instances
next-instance-id))
(define (create-LRU-manager
instance-expiration-handler
collect?)
;; Instances
(define instances (make-hash-table))
(define next-instance-id (make-counter))
(define-struct instance (data k-table))
(define (create-instance data expire-fn)
(define instance-id (next-instance-id))
(hash-table-put! instances
instance-id
(make-instance data (create-k-table)))
instance-id)
(define (adjust-timeout! instance-id secs)
(void))
(define (instance-lookup instance-id)
(define instance
(hash-table-get instances instance-id
(lambda ()
(raise (make-exn:fail:servlet-manager:no-instance
(string->immutable-string
(format "No instance for id: ~a" instance-id))
(current-continuation-marks)
instance-expiration-handler)))))
instance)
;; Continuation table
(define-struct k-table (next-id-fn htable))
(define (create-k-table)
(make-k-table (make-counter) (make-hash-table)))
;; Interface
(define (instance-lookup-data instance-id)
(instance-data (instance-lookup instance-id)))
(define (clear-continuations! instance-id)
(match (instance-lookup instance-id)
[(struct instance (data (and k-table (struct k-table (next-id-fn htable)))))
(hash-table-for-each
htable
(match-lambda*
[(list k-id (list salt k expiration-handler count))
(hash-table-put! htable k-id
(list salt #f expiration-handler count))]))]))
(define (continuation-store! instance-id k expiration-handler)
(match (instance-lookup instance-id)
[(struct instance (data (struct k-table (next-id-fn htable))))
(define k-id (next-id-fn))
(define salt (random 100000000))
(hash-table-put! htable
k-id
(list salt k expiration-handler 1))
(list k-id salt)]))
(define (continuation-lookup instance-id a-k-id a-salt)
(match (instance-lookup instance-id)
[(struct instance (data (struct k-table (next-id-fn htable))))
(match
(hash-table-get htable a-k-id
(lambda ()
(raise (make-exn:fail:servlet-manager:no-continuation
(string->immutable-string
(format "No continuation for id: ~a" a-k-id))
(current-continuation-marks)
instance-expiration-handler))))
[(list salt k expiration-handler count)
(hash-table-put! htable a-k-id
(list salt k expiration-handler (add1 count)))
(if (or (not (eq? salt a-salt))
(not k))
(raise (make-exn:fail:servlet-manager:no-continuation
(string->immutable-string
(format "No continuation for id: ~a" a-k-id))
(current-continuation-marks)
(if expiration-handler
expiration-handler
instance-expiration-handler)))
k)])]))
(define the-manager
(make-LRU-manager create-instance
adjust-timeout!
instance-lookup-data
clear-continuations!
continuation-store!
continuation-lookup
; Specific
instance-expiration-handler
; Private
instances
next-instance-id))
; Collector
(define (collect)
(define removed (box 0))
(when (collect?)
(hash-table-for-each
instances
(match-lambda*
[(list instance-id (struct instance (_ (struct k-table (next-id-fn htable)))))
(define empty? (box #t))
(hash-table-for-each
htable
(match-lambda*
[(list k-id (list s k eh count))
(if (zero? count)
(begin (set-box! removed (add1 (unbox removed)))
(hash-table-remove! htable k-id))
(begin (set-box! empty? #f)
(hash-table-put! htable k-id
(list s k eh (sub1 count)))))]))
(when (unbox empty?)
(set-box! removed (add1 (unbox removed)))
(hash-table-remove! instances instance-id))])))
(unless (zero? (unbox removed))
#;(printf "Collect: ~S ~S~n"
(unbox removed)
(round (/ (current-memory-use)
(* 1024 1024))))
(collect-garbage)
(collect-garbage)))
(define manager-thread
(thread
(lambda ()
(let loop ()
(collect)
(loop)))))
the-manager))