 (def float-size 4)
 (def bin-size 100)
 (def score-size (* float-size bin-size))
-
-(declare normalize-meta) ; XXX need to organize this file
+; Add 30 for gzip header
+;( def score-size (+ 30 (* float-size bin-size)))
+
+;
+; Utility functions
+;
+
+(defn- chunked-pmap [f coll]
+  (->> coll
+       (partition-all 250)
+       (pmap (fn [chunk] (doall (map f chunk))))
+       (apply concat)))
+
+(defn memoize-key
+  "Memoize with the given function of the arguments"
+  [kf f]
+  (let [mem (atom {})]
+    (fn [& args]
+      (let [k (kf args)]
+        (if-let [e (find @mem k)]
+          (val e)
+          (let [ret (apply f args)]
+            (swap! mem assoc k ret)
+            ret))))))
 
 ;
 ; Table models

;       (hash-by-key :SAMPLE)
;       (in-order sample-list)
;       (select-val :ID)))

(defn- insert-exp-sample [eid sample i]
  (insert exp_samples (values {:experiments_id eid :name sample :i i})))

(defn- load-exp-samples [exp samples]
  (dorun (map #(apply (partial insert-exp-sample exp) %)
              (map vector samples (range)))))

(let [fmtr (formatter "yyyy-MM-dd hh:mm:ss")]
  (defn- format-timestamp [timestamp]


  ([files metadata matrix-fn features force]
   (kdb/transaction
     (let [exp (merge-m-ent experiments-meta metadata)
           files (map fmt-time files)]
       (when (or force
                 (not (= (set files) (set (related-sources experiments exp)))))
         (clear-by-exp exp)
         (load-related-sources
           experiment_sources :experiments_id exp files)
         (table-writer "/dev/shm" ; XXX use db dir? root dir? tmp dir?
                       (partial load-exp-matrix exp matrix-fn)))))))

; XXX factor out common parts with merge, above?
(defn del-exp [file]
