         updates
         (family-groups families data)))
     {} records))
+
+
+
+;; ## Updating Functions
+
+(defn field-merger
+  "Construct a new record updating function from the given merge spec. The
+  resulting function accepts three arguments, the record id, the existing
+  record data (or nil), and the new record data map.
+
+  If the merge spec is a function, it will be called with
+  `(f field-key old-val new-val)` for each field in the record and the
+  field-key will be set to the resulting value.
+
+  If the merge spec is a map, the keys will be used to look up a merge function
+  for each field in the record, which will be called with `(f old-val new-val)`.
+  If a field has no entry in the spec, the new value is always used."
+  [spec]
+  {:pre [(or (fn? spec) (map? spec))]}
+  (let [merger (if (map? spec)
+                 (fn merger
+                   [fk l r]
+                   (if-let [f (get spec fk)]
+                     (f l r)
+                     r))
+                 spec)]
+    (fn merge-fields
+      [id old-data new-data]
+      (reduce
+        (fn [data field-key]
+          (let [left (get old-data field-key)
+                right (get new-data field-key)
+                value (merger field-key left right)]
+            (assoc data field-key value)))
+        (empty old-data)
+        (distinct (concat (keys old-data) (keys new-data)))))))

    #(= (reduce + (map count (vals %)))
        (count (distinct (apply concat (vals %)))))))



;; ## Family Functions

(defn- family-lookup
  "Build a lookup function for field families. Takes a map from family keys to

    [clojure.spec :as s]
    [merkle-db.key :as key]))


;; ## Record Keys

;; Count of the records contained under a node.
(s/def ::count nat-int?)
