Skip to content

Commit 7fa6b52

Browse files
committed
Improve context query performance
1 parent 05a7c4e commit 7fa6b52

File tree

4 files changed

+49
-36
lines changed

4 files changed

+49
-36
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Improve context query performance.
6+
57
## 0.4.2
68

79
- Fix output of errored tool calls.

src/eca/features/chat.clj

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@
253253
:model chosen-model
254254
:status :success}))
255255

256+
(defn ^:private contexts-for [root-filename query config]
257+
(let [all-files (fs/glob root-filename (str "**" (or query "") "**"))
258+
allowed-files (f.index/filter-allowed all-files root-filename config)]
259+
allowed-files))
260+
256261
(defn query-context
257262
[{:keys [query contexts chat-id]}
258263
db*
@@ -261,14 +266,7 @@
261266
(comp
262267
(map :uri)
263268
(map shared/uri->filename)
264-
(mapcat (fn [root-filename]
265-
(let [all-files (fs/glob root-filename (str "**" (or query "") "**"))
266-
all-dirs (filter fs/directory? all-files)
267-
excluded-dirs (filter #(f.index/ignore? (str %) root-filename config) all-dirs)]
268-
(->> all-files
269-
(remove (fn [path]
270-
(or (some #(fs/starts-with? (str path) %) excluded-dirs)
271-
(f.index/ignore? (str path) root-filename config))))))))
269+
(mapcat #(contexts-for % query config))
272270
(take 200) ;; for performance, user can always make query specific for better results.
273271
(map (fn [file-or-dir]
274272
{:type (if (fs/directory? file-or-dir)

src/eca/features/index.clj

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
11
(ns eca.features.index
22
(:require
3-
[clojure.java.shell :as shell]))
3+
[babashka.fs :as fs]
4+
[clojure.java.shell :as shell]
5+
[clojure.string :as string]))
46

57
(set! *warn-on-reflection* true)
68

7-
(defn ignore? [filename root-filename config]
8-
(boolean
9-
(some
10-
(fn [{:keys [type]}]
11-
(case type
12-
:gitignore (= 0 (:exit
13-
(try (shell/sh "git" "check-ignore" filename "--quiet"
14-
:dir root-filename)
15-
(catch Exception _ nil))))
16-
nil))
17-
(get-in config [:index :ignoreFiles]))))
9+
(defn filter-allowed [file-paths root-filename config]
10+
(reduce
11+
(fn [files {:keys [type]}]
12+
(case type
13+
:gitignore (let [git-files (try (some->> (some-> (shell/sh "git" "ls-files"
14+
:dir root-filename)
15+
:out
16+
(string/split #"\n"))
17+
(mapv (comp str fs/canonicalize #(fs/file root-filename %)))
18+
set)
19+
(catch Exception _ nil))]
20+
(println git-files (str (last files)))
21+
(if (seq git-files)
22+
(filter (fn [file]
23+
(contains? git-files (str file)))
24+
files)
25+
files))
26+
files))
27+
file-paths
28+
(get-in config [:index :ignoreFiles])))

test/eca/features/index_test.clj

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
11
(ns eca.features.index-test
22
(:require
3+
[babashka.fs :as fs]
34
[clojure.java.shell :as shell]
45
[clojure.test :refer [deftest is testing]]
5-
[eca.features.index :refer [ignore?]]))
6+
[eca.features.index :refer [filter-allowed]]
7+
[matcher-combinators.test :refer [match?]]))
68

7-
;; a helper config that only looks at :gitignore entries
89
(def gitignore-config
910
{:index {:ignoreFiles [{:type :gitignore}]}})
1011

1112
(deftest ignore?-test
1213
(testing "gitignore type"
1314
(let [root "/fake/repo"
14-
file1 "ignored.txt"
15-
file2 "not-ignored.txt"]
16-
(testing "returns true when `git check-ignore` exits 0"
17-
(with-redefs [shell/sh (fn [& _args] {:exit 0})]
18-
(is (true? (ignore? file1 root gitignore-config)))
19-
;; even a different filename still is seen as ignored
20-
(is (true? (ignore? file2 root gitignore-config)))))
15+
file1 (fs/path root "ignored.txt")
16+
file2 (fs/path root "not-ignored.txt")]
17+
(testing "returns filtered files when `git ls-files` works"
18+
(with-redefs [shell/sh (fn [& _args] {:exit 0 :out "not-ignored.txt"})
19+
fs/canonicalize #(fs/path root %)]
20+
(is
21+
(match?
22+
[file2]
23+
(filter-allowed [file1 file2] root gitignore-config)))))
2124

22-
(testing "returns false when `git check-ignore` exits non-zero"
23-
(with-redefs [shell/sh (fn [& _] {:exit 1})]
24-
(is (false? (ignore? file1 root gitignore-config)))))
25-
26-
(testing "returns false when `git check-ignore` throws an exception"
27-
(with-redefs [shell/sh (fn [& _] (throw (Exception. "boom")))]
28-
(is (false? (ignore? file1 root gitignore-config))))))))
25+
(testing "returns all files when `git ls-files` exits non-zero"
26+
(with-redefs [shell/sh (fn [& _args] {:exit 1})]
27+
(is
28+
(match?
29+
[file1 file2]
30+
(filter-allowed [file1 file2] root gitignore-config))))))))

0 commit comments

Comments
 (0)