/
SearchEngineIOGitGrepImpl.java
178 lines (157 loc) · 7.6 KB
/
SearchEngineIOGitGrepImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package com.zer0s2m.fugitivedarkness.provider.git.impl;
import com.zer0s2m.fugitivedarkness.provider.git.*;
import com.zer0s2m.fugitivedarkness.provider.git.helpers.FileReader;
import com.zer0s2m.fugitivedarkness.provider.git.helpers.RepositoryBranch;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
/**
* Service for providing search in git repositories. Similar to the
* <a href="https://git-scm.com/docs/git-grep">grep</a> command in git.
*/
class SearchEngineIOGitGrepImpl extends SearchEngineIOGitGrepAbstract implements SearchEngineIOGitGrep {
private final RepositoryBranch repositoryBranch = new RepositoryBranch();
/**
* @param pattern A pattern for finding matches in files.
* @param source Source path to the git repository.
* @param containerGitRepoMeta Additional Information.
*/
protected SearchEngineIOGitGrepImpl(Pattern pattern, Path source, ContainerGitRepoMeta containerGitRepoMeta) {
super(pattern, source, containerGitRepoMeta);
}
/**
* Start search.
* <p>The search is based on the following criteria:</p>
* <ul>
* <li>Including files in the search that have the specified
* extensions {@link SearchEngineGrep#getIncludeExtensionFilesForSearchGrep}.</li>
* <li>Excluding files from the search that have the specified
* extensions {@link SearchEngineGrep#getExcludeExtensionFilesForSearchGrep}.</li>
* <li>Match pattern {@link SearchEngineGrep#getPattern}.</li>
* <li>Include files by pattern {@link SearchEngineGrep#getPatternForIncludeFile} in the search.</li>
* <li>Exclude files from the search by pattern {@link SearchEngineGrep#getPatternForExcludeFile}.</li>
* <li>Maximum search depth {@link SearchEngineGrep#getMaxDepth()}.</li>
* <li>Maximum number of matches in one file {@link SearchEngineGrep#getMaxCount()}.</li>
* </ul>
*
* @return Search results.
* @throws IOException IO exception.
*/
@Override
public List<ContainerInfoSearchFileGitRepo> callGrep() throws IOException {
final Set<String> blobs;
if (getContainerGitRepoMeta().group().equals("LOCAL")) {
final Collection<Path> gitignoreFiles = GitIgnoreIndexer.find(getDirectory(), 1);
Collection<String> gitignoreLines = FileReader.read(gitignoreFiles);
blobs = GitIgnoreParser.parse(gitignoreLines);
} else {
blobs = new HashSet<>();
}
final List<ContainerInfoSearchFileGitRepo> containerInfoSearchFileGitRepos = new ArrayList<>();
final Set<Path> files;
if (getAreaIsDirectory()) {
files = SearchEngineIOGitWalkingDirectory
.walkDirectory(
Path.of(
getDirectory().toString(), getAreaFile()),
getMaxDepth(),
getIncludeExtensionFilesForSearchGrep(),
getExcludeExtensionFilesForSearchGrep(),
getPatternForIncludeFile(),
getPatternForExcludeFile(),
blobs);
} else if (getAreaIsFile()) {
files = new HashSet<>();
files.add(Path.of(
getDirectory().toString(), getAreaFile()));
} else {
files = SearchEngineIOGitWalkingDirectory
.walkDirectory(
getDirectory(),
getMaxDepth(),
getIncludeExtensionFilesForSearchGrep(),
getExcludeExtensionFilesForSearchGrep(),
getPatternForIncludeFile(),
getPatternForExcludeFile(),
blobs);
}
final List<SearchInFileMatchFilterCallableAbstract<ContainerInfoSearchFileGitRepo>> searchIOFileCallables =
collectVirtualThreads(files);
try (final ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
List<Future<ContainerInfoSearchFileGitRepo>> futures =
executor.invokeAll(searchIOFileCallables);
futures.forEach(future -> {
try {
final ContainerInfoSearchFileGitRepo containerInfoSearchFileGitRepo = future.get();
if (containerInfoSearchFileGitRepo != null) {
containerInfoSearchFileGitRepos.add(containerInfoSearchFileGitRepo);
addExtensionFilesGrep(containerInfoSearchFileGitRepo.extension());
}
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
});
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return containerInfoSearchFileGitRepos;
}
private List<SearchInFileMatchFilterCallableAbstract<ContainerInfoSearchFileGitRepo>> collectVirtualThreads(
Set<Path> files) {
final List<SearchInFileMatchFilterCallableAbstract<ContainerInfoSearchFileGitRepo>> searchIOFileCallables =
new ArrayList<>();
files.forEach(file -> {
SearchInFileMatchFilterCallableAbstract<ContainerInfoSearchFileGitRepo> searchFilterCallableAbstract =
new SearchIOFileCallable(file);
searchFilterCallableAbstract.setContainerGitRepoMeta(getContainerGitRepoMeta());
searchFilterCallableAbstract.setFile(file.toString());
searchFilterCallableAbstract.setCurrentBranch(getCurrentBranch());
searchFilterCallableAbstract.setIsUseMatcherCounterInFile(getMaxCount() != -1);
searchFilterCallableAbstract.setMaxCount(getMaxCount());
searchFilterCallableAbstract.setPattern(getPattern());
searchFilterCallableAbstract.setContextBeforeReal(getContextBefore() == -1 ? 1 : getContextBefore());
searchFilterCallableAbstract.setContextAfterReal(getContextAfter() == -1 ? 1 : getContextAfter());
searchIOFileCallables.add(searchFilterCallableAbstract);
});
return searchIOFileCallables;
}
/**
* Get the number of files in the project.
*
* @return Count files.
*/
@Override
public int getCountFiles() {
final int countFiles = SearchEngineIOGitWalkingDirectory.COUNT_FILES.get();
SearchEngineIOGitWalkingDirectory.COUNT_FILES.set(0);
return countFiles;
}
/**
* Get the average file processing time.
*
* @return Average file processing time.
*/
@Override
public long getAverageFileProcessingTime() {
final int countFiles = SearchEngineIOGitWalkingDirectory.COUNT_FILES.get();
final long totalProcessingTimeFile = StateEngineIOGitStatistics.TOTAL_PROCESSING_FILE.get();
StateEngineIOGitStatistics.TOTAL_PROCESSING_FILE.set(0);
if (totalProcessingTimeFile > 0) {
return countFiles / totalProcessingTimeFile;
} else {
return 0;
}
}
private String getCurrentBranch() {
repositoryBranch.setSourceHeadFile(
Path.of(getDirectory().toString(),
GitEquipment.FOLDER.value(),
GitEquipment.HEAD_FILE.value()));
return repositoryBranch.getCurrentBranch();
}
}