     iterator))
 
 ;; used only inside Join
-(deftype JoinIterator [iterator outer->inner inner->outer seek-key key-len]
+(deftype JoinIterator [iterator inner->outer inner-key outer-key key-len blocked?]
   Object
+  (maintain [this]
+            (if (.-end? iterator)
+              (set! blocked? true)
+              (let [new-key (.key iterator)]
+                (set! blocked? false)
+                (dotimes [inner-ix (alength inner->outer)]
+                  (aset outer-key (aget inner->outer inner-ix) (aget new-key inner-ix))))))
   (reset [this]
-         (.reset iterator))
-  (outer-key [this]
-             (when (false? (.-end? iterator))
-               (let [inner-key (.key iterator)
-                     outer-key (make-array key-len)]
-                 (dotimes [i (alength inner->outer)]
-                   (aset outer-key (aget inner->outer i) (aget inner-key i)))
-                 outer-key)))
-  (inner-key [this]
-             (.key iterator))
-  (key-at [this outer-ix]
-          (when (false? (.-end? iterator))
-            (let [inner-key (.key iterator)]
-              (aget inner-key (aget outer->inner outer-ix)))))
+         (.reset iterator)
+         (.maintain this))
+  (key [this]
+       outer-key)
   (next [this]
-        (.next iterator))
-  (seek [this outer-key]
+        (.next iterator)
+        (.maintain this))
+  (seek [this key]
         (dotimes [inner-ix (alength inner->outer)]
-          (aset seek-key inner-ix (aget outer-key (aget inner->outer inner-ix))))
-        (.seek iterator seek-key))
-  (undo [this]
-        (.undo iterator))
-  (push [this]
-        (.push iterator))
-  (pop [this]
-       (.pop iterator))
-  (end? [this]
-        (.-end? iterator)))
-
-(deftype Join [seek-key iterators var->iterators var->nextable var->iterator->push|pop? ^:mutable end?]
+          (aset inner-key inner-ix (aget outer-key (aget inner->outer inner-ix))))
+        (.seek iterator seek-key)
+        (dotimes [outer-ix (alength outer->inner)]
+          (aset outer-key outer-ix (aget key outer-ix)))
+        (.maintain this)))
+
+(deftype Join [current-key iterators ^:mutable end?]
   Object
   (reset [this]
          (debug)

       (when (false? end?)
         (aget (.-vals node) ix)))
  (next [this]
        (set! old-node node)
        (set! old-ix ix)
        (set! old-end? end?)
        (if (true? end?)
          false
          (if (nil? (.-children node))

                        (do
                          (set! node (aget (.-children node) ix))
                          (set! ix 0)
                          (recur))))))))))))

(defn iterator [tree]
  (let [iterator (Iterator. tree (.-root tree) 0 false nil nil nil #js [] #js [] #js [] (.-key-len tree))]
