Database Reference
In-Depth Information
[sum-hu sum-fams] (sum-items
mzero fields items)]
(dosync
(alter total-hu #(+ sum-hu %))
(alter total-fams #(+ sum-fams %)))))
5.
In order to call this function with
future-call
, we'll write a function to create
a thunk (a function created to assist in calling another function). It will just call
update-totals
with the parameters we give:
(defn thunk-update-totals-for [fields data-chunk]
(fn [] (update-totals fields data-chunk)))
6. With all this in place, we can deine a main function that controls the entire process
and returns the ratio of families to housing units:
(defn main
([data-file] (main data-file [:HU100 :P035001] 5))
([data-file fields chunk-count]
(doall
(->>
(lazy-read-csv data-file)
with-header
(partition-all chunk-count)
(map (partial thunk-update-totals-for fields))
(map future-call)
(map deref)))
(float (/ @total-fams @total-hu))))
How it works…
In general, the way the STM works is as follows. First, we mark memory locations to be
controlled by the STM using the
ref
function. We can then dereference them anywhere using
the
deref
function or the
@
macro, but we can only change the values of a reference inside
a
dosync
block. Then, when the point of execution gets to the end of a transaction, the STM
performs a check. If any of the references that the transaction altered have been changed by
another transaction, the current transaction fails and it's queued to be tried again. However, if
none of the references have changed, then the transaction succeeds and is committed.