            (when (> (alength keys) max-keys)
              (.split! this max-keys)))
   (split! [this max-keys]
+          ;; TODO try using push/pop instead of splice/slice
           (let [median (js/Math.floor (/ max-keys 2))
                 right-node (Node. parent (+ parent-ix 1) nil nil nil)]
             (.insert! parent parent-ix (aget keys median) (aget vals median) right-node)

  ;; TODO worth doing binary search here when nodes are large
  (seek [this key ix]
        (let [len (alength keys)]
          (loop [ix ix]
            (if (and (< ix len) (> key (aget keys ix)))
              (recur (+ ix 1))
              ix))))
  (assoc! [this key val max-keys]
          (let [ix (.seek this key 0)]
            (if (nil? children)
              (if (= key (aget keys ix))
                (do
                  (aset vals ix val)
                  true)

                  (let [child (aget right-children ix)]
                    (set (.-parent child) right-node)
                    (set (.-parent-ix child) ix)))))
            #_(assert (= (alength keys) (alength vals) (if children (dec (alength children)) (alength keys))))
            #_(assert (= (alength (.-keys right-node)) (alength (.-vals right-node)) (if (.-children right-node) (dec (alength (.-children right-node))) (alength (.-keys right-node))))))))

(deftype Iterator [max-keys ^:mutable node ^:mutable ix]
  ;; always points to before a valid key or to the tree wrapper
  Object
  (next [this]
        (when (instance? Node node)
