@@ -135,6 +135,36 @@ def workspace(self):
135135 project_workspace = current_app .ws_handler .get (self .workspace_id )
136136 return project_workspace
137137
138+ def get_latest_files_cache (self ) -> List [int ]:
139+ """Get latest file history ids either from cached table or calculate them on the fly"""
140+ if self .latest_project_files .file_history_ids is not None :
141+ return self .latest_project_files .file_history_ids
142+
143+ query = f"""
144+ WITH latest_changes AS (
145+ SELECT
146+ fp.id,
147+ pv.project_id,
148+ max(pv.name) AS version
149+ FROM
150+ project_version pv
151+ LEFT OUTER JOIN file_history fh ON fh.version_id = pv.id
152+ LEFT OUTER JOIN project_file_path fp ON fp.id = fh.file_path_id
153+ WHERE
154+ pv.project_id = :project_id
155+ AND pv.name <= :latest_version
156+ GROUP BY
157+ fp.id, pv.project_id
158+ )
159+ SELECT
160+ fh.id
161+ FROM latest_changes ch
162+ LEFT OUTER JOIN file_history fh ON (fh.file_path_id = ch.id AND fh.project_version_name = ch.version AND fh.change != 'delete')
163+ WHERE fh.id IS NOT NULL;
164+ """
165+ params = {"project_id" : self .id , "latest_version" : self .latest_version }
166+ return [row .id for row in db .session .execute (text (query ), params ).fetchall ()]
167+
138168 def cache_latest_files (self ) -> None :
139169 """Get project files from changes (FileHistory) and save them for later use."""
140170 if self .latest_version is None :
@@ -514,7 +544,11 @@ def generate_diff_name(self):
514544
515545
516546class LatestProjectFiles (db .Model ):
517- """Store project latest version files history ids"""
547+ """Store project latest version files history ids.
548+
549+ This is a caching table to store the latest relevant files history ids for further use in
550+ Project.files and ProjectVersion.files. It is updated when ProjectVersion itself is created.
551+ """
518552
519553 project_id = db .Column (
520554 UUID (as_uuid = True ),
@@ -1447,7 +1481,7 @@ def __init__(
14471481 latest_files_map = {
14481482 fh .path : fh .id
14491483 for fh in FileHistory .query .filter (
1450- FileHistory .id .in_ (self .project .latest_project_files . file_history_ids )
1484+ FileHistory .id .in_ (self .project .get_latest_files_cache () )
14511485 ).all ()
14521486 }
14531487
@@ -1578,6 +1612,10 @@ def _files_from_end(self):
15781612 files that were delete after the version (and thus not necessarily present now). From these candidates
15791613 get the latest file change before or at the specific version. If that change was not 'delete', file is present.
15801614 """
1615+ # if we do not have cached file history ids use different strategy where it is not necessary
1616+ if self .project .latest_project_files .file_history_ids is None :
1617+ return self ._files_from_start ()
1618+
15811619 query = f"""
15821620 WITH files_changes_before_version AS (
15831621 WITH files_candidates AS (
0 commit comments