   (nth (.state this) 2))
 
 (defn -find [^org.dada.core.JoinModel this key]
-  (if-let [^LHSEntry entry ((second @(first (.state this))) key)]
+  (if-let [^LHSEntry entry (map-get (second @(first (.state this))) key)]
     (if (.extant entry)
       (.datum entry))))
 

   ;; instance state [atom(mutable) immutable]
   (let [lhs-metadata (.getMetadata lhs-model)
	 views nil
	 lhs-mutable {}
	 rhs-mutables (apply vector (repeatedly (count (invert-map rhses)) hash-map))]
     [(atom [views lhs-mutable rhs-mutables]) model-name model-metadata])])

;;--------------------------------------------------------------------------------

   :post-init post-init)
  )

(do

  ;; let's use persistant maps - slower, bigger footprint, lock-free

  (def map-new hash-map)

  (defmacro map-put [map key val]
    `(assoc ~map ~key ~val))

  (defmacro map-get [map key]
    `(~map ~key))

  (defmacro map-count [map]
    `(count ~map))

  (defmacro map-locking [lockee & body]
    `(do ~@body))
  )

;; (do

;;   ;; let's use hashmaps - faster, smaller footprint with locking

;;   (defn map-new [] (HashMap.))

;;   (defmacro map-put [map key val]
;;     `(do (.put ~(with-meta map {:tag 'HashMap}) ~key ~val) ~map))

;;   (defmacro map-get [map key]
;;     `(.get ~(with-meta map {:tag 'HashMap}) ~key))

;;   (defmacro map-count [map]
;;     `(.size ~(with-meta map {:tag 'HashMap})))
  
;;   (defmacro map-locking [lockee & body]
;;     `(locking ~lockee ~@body))

;;   )

;; these types should really be created on-the-fly to match lhs/rhs relationships
(defrecord LHSEntry [extant version lhs rhs-refs datum]) ;; rhs-refs - resolution of lhs fks to rhs references
(defrecord RHSEntry [rhs lhs-pks]) ;; lhs-pks - {lhs-pk : [lhs-fk-i, ...], ...}
