 (declare use-searcher)
 (declare use-writer)
 (declare bootstrap-indexes)
-(declare get-smanager-taxo)
-(declare try-close-manager-taxo)
+(declare get-manager)
+(declare try-close-manager)
 (declare try-create-prefix)
 (declare read-alias-file)
 (declare refresh-searcher-locked)

          (log-close-err (.getDirectory taxo) e)
          (DirectoryTaxonomyWriter/unlock (.getDirectory taxo)))))))

(defn try-close-manager-taxo [^SearcherManager manager ^DirectoryTaxonomyReader taxo]
  (try
    (do
      (try
        (.close taxo)
        (catch Exception e
          (log/warn (as-str e))))
      (.close manager))
    (catch Exception e
      (log/warn (as-str e)))))


  (try
    (doseq [dir (sub-directories)]
      (try
        (get-manager (.getName ^File dir) false)
        (catch Exception e
          (log/warn (ex-str e)))))
    (catch Exception e
      (log/warn (ex-str e)))))

(defn get-manager [index refresh]
  (when (nil? (@name->manager* index))
    (locking name->manager*
      (when (nil? (@name->manager* index))
        ;; to avoid a race in case multiple threads
        ;; decide to use the index (including creating it) in the very beginning
        ;; before the statistic keys are ready, so we just create them under the lock here
        ;; not doing the same for writers, because of the exclusive write lock there
        (use-writer index nil 0 (fn [^IndexWriter writer ^DirectoryTaxonomyWriter taxo]))
        (swap! name->manager* assoc index (new-searcher-manager index))
        (stat/get-statistics index))))
  (let [manager (@name->manager* index)]
    (when refresh
      (refresh-searcher-locked index manager))
    manager))

(defn refresh-searcher-locked [index ^SearcherTaxonomyManager manager]
  (log/debug "refreshing: " index " " manager)
  (let [t0 (time-ms)]
    (try
      (do
        (.maybeRefresh manager)
        (stat/update-took-count index "refresh-search-managers" (time-took t0)))
      (catch Throwable e
        (do
          (log/info (str index " refresh exception, closing it. Exception: " (ex-str e)))
          (try-close-manager manager)
          (swap! name->manager* dissoc index))))))

(defn refresh-search-managers []
  (let [t0 (time-ms)]
    (bootstrap-indexes)
    (locking name->manager*
      (doseq [[index ^SearcherTaxonomyManager manager] @name->manager*]
        (refresh-searcher-locked index manager)))
    (stat/update-took-count stat/total "refresh-search-managers" (time-took t0))
    (log/debug "refreshing took" (time-took t0))))

(defn shutdown []
  (locking name->manager*
    (log/info "executing shutdown hook, current mapping: " @name->manager*)
    (reset-search-managers)
    (log/info "mapping after cleanup: " @name->manager*)))

(defn index-stat []
  (into {} (for [[name manager] @name->manager*]
             [name (use-searcher name
                                 false
                                 (fn [^IndexSearcher searcher ^DirectoryTaxonomyReader taxo-reader]
