                                     (magic-iterator tree #js [nil 0 nil nil 1 nil])
                                     (magic-iterator tree #js [nil nil 0 nil nil 1])]))
         ]
-    (assert
-     (= (map vec (time (all-join-results j)))
-        (map vec #js [#js [0 0 0 0 0 0] #js [0 0 1 0 0 1] #js [0 1 0 0 1 0] #js [0 1 1 0 1 1] #js [1 0 0 1 0 0] #js [1 0 1 1 0 1] #js [1 1 0 1 1 0] #js [1 1 1 1 1 1]])))
+     (assert
+      (= (map vec (time (all-join-results j)))
+         (map vec #js [#js [0 0 0 0 0 0] #js [0 0 1 0 0 1] #js [0 1 0 0 1 0] #js [0 1 1 0 1 1] #js [1 0 0 1 0 0] #js [1 0 1 1 0 1] #js [1 1 0 1 1 0] #js [1 1 1 1 1 1]])))
   )
 
   (let [tree (tree 10)

         (aset marked-nodes ix (.-node itr))
         (aset marked-ixs ix (.-ix itr))))
     (.set-key magic)
     (ainto (.-prev-seek magic) (.key magic))
     magic)))

(deftype JoinIterator [iterators ^:mutable cur-key ^:mutable next-key ^:mutable end? len tuple-len keys min-fill]
  Object
  (key [this]
       cur-key)

  (fillkeys [this]
          (dotimes [x len]
            (aset keys x (.key (aget iterators x)))))

  (find-least [this]
              (loop [ix 1
                     col 0
                     least (-> (aget keys 0)
                               (aget 0))]
                (if (>= ix len)
                  (do
                    (aset min-fill col least)
                    (let [next (+ 1 col)]
                      (if (< next tuple-len)
                        (recur 0 next nil))))
                  (let [cur (-> (aget keys ix)
                                (aget col))]
                    (recur (+ 1 ix) col (if (nilless-lt cur least)
                                          cur
                                          least))))))
  (iters-next [this]
              (let [last (aget iterators (- len 1))]
                (.next last)
                (if-not (.-end? last)
                  (reverse-fill! (.key last) min-fill)
                  (loop [ix (- len 2)]
                    (when (>= ix 0)
                      (let [cur (aget iterators ix)]
                        (.next cur)
                        (if (.-end? cur)
                          (recur (- ix 1))
                          (reverse-fill-with! (.key cur) min-fill false))))))))
  (find-greatest ^:boolean [this]
                 ;(println keys)
                 (loop [ix 1
                        greatest (aget keys 0)
                        found? true]
                   (if (>= ix len)
                     (if found?
                       (let [greatest (fill! (.slice greatest 0) min-fill)]
                        ;(println "    ***setting greatest: " greatest)
                         (.iters-next this)
                         (set! cur-key greatest)
                         (ainto next-key min-fill)
                         false)
                       (do
                         (ainto next-key (reverse-fill! greatest min-fill))
                         true))
                     (let [comped (filled-key-compare greatest (aget keys ix) min-fill)
                           comped-v (or comped greatest)]
                      ;(println "g: " comped (and found? (not comped)) min-fill)
                       (recur (+ 1 ix) comped-v (and found? (not comped))))))
                )
  (seek-all [this]
            (loop [ix 0]
              (if (< ix len)
                (let [cur (aget iterators ix)
                      cur-key (.key cur)]
                 ;(println "searching for: " next-key)
                 ;(println "    iterator " ix ": " cur-key)
                  (.seek cur next-key)
                 ;(println "    post iterator " ix ": " (.key cur))
                  (if-not (.-iterator.end? cur)
                    (do
                      (reverse-fill! (.key cur) next-key)
                      (recur (+ 1 ix)))
                    (do
                      (set! end? true)
                      false)))
                (do
                 ;(println "    final search key: " okey)
                  true)))
            )
  (init-join [this]
             (.fillkeys this)
             (.find-least this)
             (when (identical? true (.find-greatest this))
               (.seek-join this)))

  (seek-join [this]
             (loop [continue? true]
               (when (identical? true continue?)
                 (when (.seek-all this)
                   (.fillkeys this)
                   (.find-least this)
                  ;(println "MIN FILL: " min-fill)
                   (recur (.find-greatest this))
                   )))
             )

  (next [this]
        (if end?
          (set! cur-key nil)
          (.seek-join this)
          ))

  (seek [this key]
        (when (key-lt cur-key key)
          (ainto next-key key)
          (.next this))))

(defn join-iterator [iterators]
  ;(println iterators)
  (let [len (alength iterators)
        results (array)
        keys (array)
        min-fill (array)
        root (aget iterators 0)
        tuple-len (alength (.-map root))]
    (if (or (== tuple-len 0)
            (not (.key root))
            (== 0 (alength (.key root))))
      (do
        (.next root)
        root)
      (let [itr (JoinIterator. iterators (array) (array) false len tuple-len keys min-fill)]
        (.init-join itr)
        itr
        ))))


                (> a b))
           (> (typeof a) (typeof b)))))

(deftype MagicIterator [iterator map nil-ixs map-len ^:mutable cur-key ^:mutable cur-seek ^:mutable prev-seek ^:mutable marked-nodes ^:mutable marked-ixs ^:mutable end?]
  Object
  (mark [this i]
        (aset marked-nodes i (.-node iterator))
        (aset marked-ixs i (.-ix iterator)))

  (rewind [this i]
          (set! (.-node iterator) (aget marked-nodes i))
          (set! (.-ix iterator) (aget marked-ixs i))
          (set! (.-end? iterator) false)
          (set! end? false)
          (.set-key this)
          ;(println "rewinding: " i (.-cur-key this))
          )

  (key [this]
       (when (identical? end? false)
         (.-cur-key this)))

  (val [this]
       (.val iterator))

  (next [this]
        (.next iterator)
        (set! end? (.-end? iterator))
        (.set-key this))

  (make-min [this]
            (when cur-key
              ;;fill the unknown values with least
              (dotimes [ix (alength nil-ixs)]
                (aset cur-key (aget nil-ixs ix) least))
              cur-key))

  (set-key [this]
           (if-let [found (.key iterator)]
             (dotimes [ix map-len]
               (let [map-ix (aget map ix)]
                   (if-not (nil? map-ix)
                     (aset cur-key ix (aget found map-ix))
                     (aset cur-key ix (aget prev-seek ix)))))
             (set! end? true)))

  (seek-and-mark [this ix key]
                 (let [prev-key (- ix 1)
                       key-value (aget key prev-key)
                       cur-value (aget cur-key prev-key)]
                   ;;when the value previous to the placeholder has increased
                   ;;we need to seek to the first value that matches it and
                   ;;store that
                   (when (gt key-value cur-value)
                     (dotimes [x (alength cur-seek)]
                       (aset cur-seek x false))
                     (aset cur-seek (aget map prev-key) key-value)
                     ;(println "        storing seek: " cur-seek)
                     (.seek iterator cur-seek)
                     ;(println "        STORING: " (.key iterator))
                     (.set-key this))
                   (.mark this cur)))

  (check-rewind [this key]
                (let [len (alength nil-ixs)]
                  (loop [ix 0]
                    (if (< ix len)
                      (let [cur (aget nil-ixs ix)
                            rewind? (not (identical? (aget key cur) (aget prev-seek cur)))]
                        (cond
                         ;; we can't store anything if we're at the root value, so just rewind if we need
                         (and (identical? cur 0) rewind?) (.rewind this cur)
                         ;; check if we need to store based on a new value before our placeholder
                         (> cur 0) (let [store? (not (identical? (aget key (- cur 1)) (aget prev-seek (- cur 1))))]
                                     (if store?
                                       (.seek-and-mark this cur key)
                                       ;;if we need to rewind and we're not looking at the last index
                                       ;;because it doesn't make sense to rewind if there's no value to be rewound
                                       (if (and rewind? (not (== (+ cur 1) map-len)))
                                         (.rewind this cur)
                                         (recur (+ 1 ix)))))
                         :else (recur (+ 1 ix)))))))
                )
  (seek [this key]
        ;;see if our placeholders have changed such that we need to rewind
        (.check-rewind this key)
        (ainto prev-seek key)
        (when (key-lt cur-key key)
          (loop [ix 0]
            (when (< ix map-len)
              (let [map-ix (aget map ix)]
                (when-not (== map-ix nil)
                  (aset cur-seek map-ix (aget key ix))))
              (recur (+ 1 ix))))
          (.seek iterator cur-seek))
        (.set-key this)
        ))

(deftype MagicIteratorWrapper [iterator map ^:mutable end?]
  Object
  (key [this]
       (.key iterator))

  (val [this]
       (.val iterator))
  (make-min [this]
            (.key this))
  (next [this]
        (.next iterator)
        (set! end? (.-end? iterator)))
