diff src/rlm/function_utils.clj @ 4:12d1367cf1aa

updating various utilities
author Robert McIntyre <rlm@mit.edu>
date Thu, 01 Mar 2012 05:47:23 -0700
parents c8e35134bf8e
children b8bbb0dbda7b
line wrap: on
line diff
     1.1 --- a/src/rlm/function_utils.clj	Wed Jan 18 05:18:57 2012 -0700
     1.2 +++ b/src/rlm/function_utils.clj	Thu Mar 01 05:47:23 2012 -0700
     1.3 @@ -65,7 +65,7 @@
     1.4  )
     1.5  
     1.6  
     1.7 -(defn mix 
     1.8 +(defn race 
     1.9    "Takes any number of mathematically equal functions with
    1.10     possibly different run-times and returns a function that
    1.11     runs each in a separate thread, returns the result from
    1.12 @@ -80,19 +80,30 @@
    1.13  	 (dorun (map future-cancel futures))
    1.14  	 answer))))
    1.15  
    1.16 -(defn mix-pred
    1.17 -  "Takes any number of mathematically equal functions with
    1.18 -   possibly different run-times and returns a function that
    1.19 -   runs each in a separate thread, returns the result from
    1.20 -   the first thread which finishes, and cancels the other threads."
    1.21 +(defn race-pred
    1.22 +  "Takes any number of mathematically equal functions with possibly
    1.23 +   different run-times and returns a function that runs each in a
    1.24 +   separate thread, and returns the first available result x for
    1.25 +   which (pred x) returns true (or not-valid, if (pred x) returns
    1.26 +   false on all the results).  Cancels the other threads upon
    1.27 +   returning early."
    1.28    {:author "Robert McIntyre"}
    1.29 -  ([pred & functions]
    1.30 +  ([pred not-valid & functions]
    1.31       (fn [& args]
    1.32         (let [result (promise)
    1.33 -	     futures (doall (for [fun functions]
    1.34 -                              (let [answer (apply fun args)]
    1.35 -                                (if (pred answer)
    1.36 -                                  (future (deliver result (apply fun args)))))))
    1.37 +             latch (java.util.concurrent.CountDownLatch.
    1.38 +                    (count functions))
    1.39 +             failure-case (future (.await latch)
    1.40 +                                  (deliver result not-valid))
    1.41 +	     futures
    1.42 +             (doall
    1.43 +              (cons failure-case
    1.44 +                    (for [fun functions]
    1.45 +                      (future
    1.46 +                        (let [answer? (apply fun args)]
    1.47 +                          (if (pred answer?)
    1.48 +                            (deliver result answer?)
    1.49 +                            (.countDown latch)))))))
    1.50  	     answer @result]
    1.51  	 (dorun (map future-cancel futures))
    1.52  	 answer))))