 
 (defrecord Context [rels sources])
 ;; attrs:
-;;    [?e ?v ?e2 ?age]
+;;    {?e 0, ?v 1} or {?e2 "a", ?age "v"}
 ;; tuples:
-;;   [ #js [1 "Ivan" 5 14]
-;;     #js [2 "Oleg" 1 55]
-;;     ... ]
+;;    [ #js [1 "Ivan" 5 14] ... ]
+;; or [ (Datom. 2 "Oleg" 1 55) ... ]
 (defrecord Relation [attrs tuples])
 
-(defn intersect-keys [a1 a2]
-  (set/intersection (set a1)) (set a2))
+(defn intersect-keys [attrs1 attrs2]
+  (set/intersection (set (keys attrs1)) 
+                    (set (keys attrs2))))
 
 (defn concatv [& xs]
   (vec (apply concat xs)))
 
-(defn index [coll]
-  (map vector coll (range)))
-
-(defn index-map [coll]
-  (into {} (index coll)))
-
 (defn tuple-key-fn [idxs]
-  (if (== (alength idxs) 1)
+  (if (== (count idxs) 1)
     (let [idx (first idxs)]
       (fn [tuple]
         (aget tuple idx)))
-    (fn [tuple]
-      (list* (.map idxs #(aget tuple %))))))
+    (let [idxs (to-array idxs)]
+      (fn [tuple]
+        (list* (.map idxs #(aget tuple %))))))) ;; FIXME aget
 
 (defn hash-attrs [idxs tuples]
   (let [key-fn (tuple-key-fn idxs)]

;;        _             (.timeEnd js/console "new-tuples")
        ]
;;    (.timeEnd js/console "hash-join")
    (Relation. (concatv (:attrs rel1) keep-attrs2)
               new-tuples)))


(hash-join (Relation. '[?e ?a ?v]
                      [#js [1 :name "Ivan"]
                       #js [2 :name "Igor"]
                       #js [3 :name "Petr"]])
           (Relation. '[?e ?a2 ?v2]
                      [#js [1 :age 15]
                       #js [3 :age 25]]))


;;    (.timeEnd js/console "search/-q")
    res))

(defn -collect
  ([context symbols]
    ;;  (.time js/console "search/-collect")
    (let [symbols-map (into {} (map vector symbols (range)))
          rels        (:rels context)
          data        (-collect [(make-array (count symbols))] rels symbols-map)
          res         (set (map vec data))]
      ;;      (.timeEnd js/console "search/-collect")
      res))
  ([acc rels symbols-map]
    (if-let [rel (first rels)]
      (let [keep-attrs (vec (intersect-keys (:attrs rel) symbols-map))]
        (if (empty? keep-attrs)
          (recur acc (next rels) symbols-map)
          (let [idxs-map (mapv #(array ((:attrs rel) %) (symbols-map %)) keep-attrs)]
            (recur (for [t1 acc
                         t2 (:tuples rel)]
                     (let [res (.slice t1 0)] ;; clone
                       (doseq [idxs idxs-map
                               :let [from (aget idxs 0)
                                     to   (aget idxs 1)]]
                         (aset res to (aget t2 from)))
                       res))
                   (next rels)
                   symbols-map))))
      acc)))

#_(-q {'$ [[1 :name "Ivan" 42]
         [1 :age  15 34]
