Skip to content

Commit da146a8

Browse files
committed
allow to enable/disable history cache per project
fixes #4745
1 parent 7b5f14f commit da146a8

File tree

6 files changed

+103
-50
lines changed

6 files changed

+103
-50
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/Project.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,15 @@ public class Project implements Comparable<Project>, Nameable, Serializable {
8484
private Boolean handleRenamedFiles = null;
8585

8686
/**
87-
* This flag enables/disables per-project history cache.
87+
* This flag enables/disables per-project history queries.
8888
*/
8989
private Boolean historyEnabled = null;
9090

91+
/**
92+
* This flag enables/disables per-project history cache.
93+
*/
94+
private Boolean historyCacheEnabled = null;
95+
9196
/**
9297
* This flag enables/disables per-project annotation cache.
9398
*/
@@ -301,6 +306,20 @@ public void setHistoryEnabled(boolean flag) {
301306
this.historyEnabled = flag;
302307
}
303308

309+
/**
310+
* @return true if this project should have history cache.
311+
*/
312+
public boolean isHistoryCacheEnabled() {
313+
return historyCacheEnabled != null && historyCacheEnabled;
314+
}
315+
316+
/**
317+
* @param flag true if project should have history cache, false otherwise.
318+
*/
319+
public void setHistoryCacheEnabled(boolean flag) {
320+
this.historyCacheEnabled = flag;
321+
}
322+
304323
/**
305324
* @return true if this project should have annotation cache.
306325
*/
@@ -494,11 +513,16 @@ public final void completeWithDefaults() {
494513
setHandleRenamedFiles(env.isHandleHistoryOfRenamedFiles());
495514
}
496515

497-
// Allow project to override global setting of history cache generation.
516+
// Allow project to override global setting of history queries.
498517
if (historyEnabled == null) {
499518
setHistoryEnabled(env.isHistoryEnabled());
500519
}
501520

521+
// Allow project to override global setting of history cache generation.
522+
if (historyCacheEnabled == null) {
523+
setHistoryCacheEnabled(env.useHistoryCache());
524+
}
525+
502526
// Allow project to override global setting of annotation cache generation.
503527
if (annotationCacheEnabled == null) {
504528
setAnnotationCacheEnabled(env.isAnnotationCacheEnabled());

opengrok-indexer/src/main/java/org/opengrok/indexer/history/HistoryGuru.java

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,16 @@ static AnnotationCache initializeAnnotationCache() {
164164
* @return {@link HistoryCache} instance
165165
*/
166166
private HistoryCache initializeHistoryCache() {
167-
HistoryCache historyCacheResult = null;
168-
if (env.useHistoryCache()) {
169-
historyCacheResult = new FileHistoryCache();
167+
HistoryCache historyCacheResult = new FileHistoryCache();
170168

171-
try {
172-
historyCacheResult.initialize();
173-
} catch (CacheException he) {
174-
LOGGER.log(Level.WARNING, "Failed to initialize the history cache", he);
175-
// Failed to initialize, run without a history cache.
176-
historyCacheResult = null;
177-
}
169+
try {
170+
historyCacheResult.initialize();
171+
} catch (CacheException he) {
172+
LOGGER.log(Level.WARNING, "Failed to initialize the history cache", he);
173+
// Failed to initialize, run without a history cache.
174+
historyCacheResult = null;
178175
}
176+
179177
return historyCacheResult;
180178
}
181179

@@ -188,13 +186,26 @@ public static HistoryGuru getInstance() {
188186
return INSTANCE;
189187
}
190188

191-
/**
192-
* Return whether cache should be used for the history log.
193-
*
194-
* @return {@code true} if the history cache has been enabled and initialized, {@code false} otherwise
195-
*/
196-
private boolean useHistoryCache() {
197-
return historyCache != null;
189+
private boolean useHistoryCache(File file) {
190+
if (historyCache == null) {
191+
return false;
192+
}
193+
194+
// file = new File(env.getSourceRootPath(), file.getPath());
195+
196+
return useHistoryCache(getRepository(file));
197+
}
198+
199+
private boolean useHistoryCache(@Nullable Repository repository) {
200+
if (historyCache == null || repository == null) {
201+
return false;
202+
}
203+
204+
if (!historyCache.supportsRepository(repository)) {
205+
return false;
206+
}
207+
208+
return repository.isHistoryCacheEnabled();
198209
}
199210

200211
/**
@@ -418,7 +429,7 @@ boolean isRepoHistoryEligible(Repository repo, File file, boolean ui) {
418429
private History getHistoryFromCache(File file, Repository repository, boolean withFiles)
419430
throws CacheException {
420431

421-
if (useHistoryCache() && historyCache.supportsRepository(repository)) {
432+
if (useHistoryCache(repository)) {
422433
return historyCache.get(file, repository, withFiles);
423434
}
424435

@@ -428,7 +439,7 @@ private History getHistoryFromCache(File file, Repository repository, boolean wi
428439
@Nullable
429440
private HistoryEntry getLastHistoryEntryFromCache(File file, Repository repository) throws CacheException {
430441

431-
if (useHistoryCache() && historyCache.supportsRepository(repository)) {
442+
if (useHistoryCache(repository)) {
432443
return historyCache.getLastHistoryEntry(file);
433444
}
434445

@@ -451,6 +462,9 @@ public HistoryEntry getLastHistoryEntry(File file, boolean ui, boolean fallback)
451462
launderLog(file.toString())));
452463
final File dir = file.isDirectory() ? file : file.getParentFile();
453464
final Repository repository = getRepository(dir);
465+
if (repository == null) {
466+
return null;
467+
}
454468
final String meterName = "history.entry.latest";
455469

456470
try {
@@ -479,7 +493,7 @@ public HistoryEntry getLastHistoryEntry(File file, boolean ui, boolean fallback)
479493
if (!isRepoHistoryEligible(repository, file, ui)) {
480494
statistics.report(LOGGER, Level.FINEST,
481495
String.format("cannot retrieve the last history entry for ''%s'' in %s because of settings",
482-
launderLog(file.toString()), repository), meterName);
496+
launderLog(file.toString()), repository), meterName);
483497
return null;
484498
}
485499

@@ -691,7 +705,7 @@ private static boolean repositoryHasHistory(File file, Repository repo) {
691705
* @return if there is history cache entry for the file
692706
*/
693707
public boolean hasHistoryCacheForFile(File file) {
694-
if (!useHistoryCache()) {
708+
if (!useHistoryCache(file)) {
695709
LOGGER.finest(() -> String.format("history cache is off for '%s' to check history cache presence",
696710
launderLog(file.toString())));
697711
return false;
@@ -823,15 +837,15 @@ public boolean fillLastHistoryEntries(File directory, List<DirectoryEntry> entri
823837
return true;
824838
}
825839

826-
if (!useHistoryCache()) {
827-
LOGGER.finest(() -> String.format("history cache is disabled for '%s' to retrieve last modified times",
840+
Repository repository = getRepository(directory);
841+
if (repository == null) {
842+
LOGGER.finest(() -> String.format("cannot find repository for '%s' to retrieve last modified times",
828843
launderLog(directory.toString())));
829844
return true;
830845
}
831846

832-
Repository repository = getRepository(directory);
833-
if (repository == null) {
834-
LOGGER.finest(() -> String.format("cannot find repository for '%s' to retrieve last modified times",
847+
if (!useHistoryCache(repository)) {
848+
LOGGER.finest(() -> String.format("history cache is disabled for '%s' to retrieve last modified times",
835849
launderLog(directory.toString())));
836850
return true;
837851
}
@@ -1139,9 +1153,14 @@ private Map<Repository, Optional<Exception>> createHistoryCacheReal(Collection<R
11391153
* @return map of repository to optional exception
11401154
*/
11411155
public Map<Repository, Optional<Exception>> createHistoryCache(Collection<String> repositories) {
1142-
if (!useHistoryCache()) {
1156+
if (repositories.stream().
1157+
map(e -> new File(env.getSourceRootPath(), e)).
1158+
map(this::getRepository).
1159+
filter(Objects::nonNull).
1160+
noneMatch(RepositoryInfo::isHistoryCacheEnabled)) {
11431161
return Collections.emptyMap();
11441162
}
1163+
11451164
return createHistoryCacheReal(getReposFromString(repositories));
11461165
}
11471166

@@ -1151,12 +1170,12 @@ public Map<Repository, Optional<Exception>> createHistoryCache(Collection<String
11511170
* @param removeHistory whether to remove history cache entry for the path
11521171
*/
11531172
public void clearHistoryCacheFile(String path, boolean removeHistory) {
1154-
if (!useHistoryCache()) {
1173+
Repository repository = getRepository(new File(env.getSourceRootFile(), path));
1174+
if (repository == null) {
11551175
return;
11561176
}
11571177

1158-
Repository repository = getRepository(new File(env.getSourceRootFile(), path));
1159-
if (repository == null) {
1178+
if (!useHistoryCache(repository)) {
11601179
return;
11611180
}
11621181

@@ -1230,7 +1249,7 @@ public void clearAnnotationCacheFile(String path) {
12301249
* @return list of repository names
12311250
*/
12321251
public List<String> removeHistoryCache(Collection<RepositoryInfo> repositories) {
1233-
if (!useHistoryCache()) {
1252+
if (repositories.stream().noneMatch(RepositoryInfo::isHistoryCacheEnabled)) {
12341253
return List.of();
12351254
}
12361255

@@ -1258,7 +1277,7 @@ public List<String> removeAnnotationCache(Collection<RepositoryInfo> repositorie
12581277
* @return map of repository to optional exception
12591278
*/
12601279
public Map<Repository, Optional<Exception>> createHistoryCache() {
1261-
if (!useHistoryCache()) {
1280+
if (repositories.values().stream().noneMatch(RepositoryInfo::isHistoryCacheEnabled)) {
12621281
return Collections.emptyMap();
12631282
}
12641283

opengrok-indexer/src/main/java/org/opengrok/indexer/history/RepositoryInfo.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ public class RepositoryInfo implements Serializable {
7878
@DTOElement
7979
private boolean historyEnabled;
8080
@DTOElement
81+
private boolean historyCacheEnabled;
82+
@DTOElement
8183
private boolean annotationCacheEnabled;
8284
@DTOElement
8385
private boolean mergeCommitsEnabled;
@@ -105,6 +107,7 @@ public RepositoryInfo(RepositoryInfo orig) {
105107
this.branch = orig.branch;
106108
this.currentVersion = orig.currentVersion;
107109
this.historyEnabled = orig.historyEnabled;
110+
this.historyCacheEnabled = orig.historyCacheEnabled;
108111
this.annotationCacheEnabled = orig.annotationCacheEnabled;
109112
this.handleRenamedFiles = orig.handleRenamedFiles;
110113
this.mergeCommitsEnabled = orig.mergeCommitsEnabled;
@@ -164,7 +167,7 @@ public void setHistoryBasedReindex(boolean flag) {
164167
}
165168

166169
/**
167-
* @return true if the repository should have history cache.
170+
* @return true if the repository should support history queries.
168171
*/
169172
public boolean isHistoryEnabled() {
170173
return this.historyEnabled;
@@ -174,6 +177,17 @@ public void setHistoryEnabled(boolean flag) {
174177
this.historyEnabled = flag;
175178
}
176179

180+
/**
181+
* @return true if the history for this repository should be stored in history cache.
182+
*/
183+
public boolean isHistoryCacheEnabled() {
184+
return this.historyCacheEnabled;
185+
}
186+
187+
public void setHistoryCacheEnabled(boolean flag) {
188+
this.historyCacheEnabled = flag;
189+
}
190+
177191
public boolean isAnnotationCacheEnabled() {
178192
return annotationCacheEnabled;
179193
}
@@ -381,6 +395,7 @@ public void fillFromProject() {
381395
Project proj = Project.getProject(getDirectoryNameRelative());
382396
if (proj != null) {
383397
setHistoryEnabled(proj.isHistoryEnabled());
398+
setHistoryCacheEnabled(proj.isHistoryCacheEnabled());
384399
setAnnotationCacheEnabled(proj.isAnnotationCacheEnabled());
385400
setHandleRenamedFiles(proj.isHandleRenamedFiles());
386401
setMergeCommitsEnabled(proj.isMergeCommitsEnabled());
@@ -391,6 +406,7 @@ public void fillFromProject() {
391406
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
392407

393408
setHistoryEnabled(env.isHistoryEnabled());
409+
setHistoryCacheEnabled(env.useHistoryCache());
394410
setAnnotationCacheEnabled(env.isAnnotationCacheEnabled());
395411
setHandleRenamedFiles(env.isHandleHistoryOfRenamedFiles());
396412
setMergeCommitsEnabled(env.isMergeCommitsEnabled());

opengrok-indexer/src/main/java/org/opengrok/indexer/index/Indexer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,13 +1123,12 @@ public Map<Repository, Optional<Exception>> prepareIndexer(RuntimeEnvironment en
11231123
* @param repositories list of repository paths relative to source root
11241124
* @return map of repository to exception
11251125
* @throws IndexerException indexer exception
1126-
* @throws IOException I/O exception
11271126
*/
11281127
public Map<Repository, Optional<Exception>> prepareIndexer(RuntimeEnvironment env,
11291128
Set<String> searchPaths,
11301129
boolean addProjects,
11311130
boolean createHistoryCache,
1132-
List<String> repositories) throws IndexerException, IOException {
1131+
List<String> repositories) throws IndexerException {
11331132

11341133
if (!env.validateUniversalCtags()) {
11351134
throw new IndexerException("Could not find working Universal ctags. " +

opengrok-indexer/src/test/java/org/opengrok/indexer/history/HistoryGuruTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.io.File;
3939
import java.io.IOException;
4040
import java.io.InputStream;
41+
import java.net.URL;
4142
import java.nio.file.Files;
4243
import java.nio.file.Path;
4344
import java.nio.file.Paths;
@@ -95,7 +96,9 @@ static void setUpClass() throws Exception {
9596
savedNestingMaximum = env.getNestingMaximum();
9697

9798
repository = new TestRepository();
98-
repository.create(HistoryGuru.class.getResource("/repositories"));
99+
URL resourceURL = HistoryGuru.class.getResource("/repositories");
100+
assertNotNull(resourceURL);
101+
repository.create(resourceURL);
99102
RepositoryFactory.initializeIgnoredNames(env);
100103
FileUtilities.getAllFiles(new File(repository.getSourceRoot()), FILES, true);
101104
assertNotEquals(0, FILES.size());

opengrok-indexer/src/test/java/org/opengrok/indexer/index/IndexDatabaseTest.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ void testGetDefinitions() throws Exception {
215215
* <li>the directory names used</li>
216216
* <li>the way file paths are constructed ({@link TandemPath})</li>
217217
* </ul>
218-
* @param fileName file name to check
218+
* @param fileName path relative to source root
219219
* @param shouldExist whether the data file should exist
220220
*/
221221
private void checkDataExistence(String fileName, boolean shouldExist) {
@@ -224,20 +224,12 @@ private void checkDataExistence(String fileName, boolean shouldExist) {
224224

225225
for (String dirName : new String[] {"historycache", "annotationcache", IndexDatabase.XREF_DIR}) {
226226
File dataDir = new File(env.getDataRootFile(), dirName);
227-
File file = new File(env.getServerName(), fileName);
227+
File file = new File(env.getSourceRootFile(), fileName);
228228
String cacheFile;
229229
if (dirName.equals("annotationcache")) {
230-
if (shouldExist) {
231-
assertTrue(historyGuru.hasAnnotationCacheForFile(file));
232-
} else {
233-
assertFalse(historyGuru.hasAnnotationCacheForFile(file));
234-
}
230+
assertEquals(shouldExist, historyGuru.hasAnnotationCacheForFile(file));
235231
} else if (dirName.equals("historycache")) {
236-
if (shouldExist) {
237-
assertTrue(historyGuru.hasHistoryCacheForFile(file));
238-
} else {
239-
assertFalse(historyGuru.hasHistoryCacheForFile(file));
240-
}
232+
assertEquals(shouldExist, historyGuru.hasHistoryCacheForFile(file));
241233
} else {
242234
cacheFile = TandemPath.join(fileName, ".gz");
243235
File dataFile = new File(dataDir, cacheFile);

0 commit comments

Comments
 (0)