Skip to content

Commit 783075e

Browse files
committed
added a ring buffer similarity hashes
vscode extension (and others) can manage hash cache from outside making sure cache doesn't grow indefinitely
1 parent 4cdbfca commit 783075e

File tree

1 file changed

+59
-2
lines changed

1 file changed

+59
-2
lines changed

src/checkstyle/checks/coding/CodeSimilarityCheck.hx

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ class CodeSimilarityCheck extends Check {
2121
static var SIMILAR_HASHES:Map<String, HashedCodeBlock> = new Map<String, HashedCodeBlock>();
2222
static var IDENTICAL_HASHES:Map<String, HashedCodeBlock> = new Map<String, HashedCodeBlock>();
2323
static var LOCK:Mutex = new Mutex();
24+
#if use_similarity_ringbuffer
25+
static var FILE_RINGBUFFER:Array<String> = [];
26+
static var FILE_HASHES:Map<String, Array<CodeHashes>> = new Map<String, Array<CodeHashes>>();
27+
#end
2428

2529
/**
2630
severity level for identical code blocks
@@ -92,6 +96,9 @@ class CodeSimilarityCheck extends Check {
9296
startColumn: offsetToColumn(lineStart),
9397
endColumn: offsetToColumn(lineEnd)
9498
}
99+
#if use_similarity_ringbuffer
100+
recordFileHashes(hashes, codeBlock);
101+
#end
95102

96103
if (hashes.tokenCount > thresholdIdentical) {
97104
var existing:Null<HashedCodeBlock> = checkOrAddHash(hashes.identicalHash, codeBlock, IDENTICAL_HASHES);
@@ -117,11 +124,58 @@ class CodeSimilarityCheck extends Check {
117124
function checkOrAddHash(hash:String, codeBlock:HashedCodeBlock, hashTable:Map<String, HashedCodeBlock>):Null<HashedCodeBlock> {
118125
LOCK.acquire();
119126
var existing:Null<HashedCodeBlock> = hashTable.get(hash);
120-
if (existing == null) hashTable.set(hash, codeBlock);
127+
if (existing == null) {
128+
hashTable.set(hash, codeBlock);
129+
}
121130
LOCK.release();
122131
return existing;
123132
}
124133

134+
#if use_similarity_ringbuffer
135+
function recordFileHashes(hashes:CodeHashes, codeBlock:HashedCodeBlock) {
136+
LOCK.acquire();
137+
if (!FILE_RINGBUFFER.contains(codeBlock.fileName)) FILE_RINGBUFFER.push(codeBlock.fileName);
138+
var fileHashes:Null<Array<CodeHashes>> = FILE_HASHES.get(codeBlock.fileName);
139+
if (fileHashes == null) {
140+
fileHashes = [];
141+
FILE_HASHES.set(codeBlock.fileName, fileHashes);
142+
}
143+
fileHashes.push(hashes);
144+
LOCK.release();
145+
}
146+
147+
static function cleanupRingBuffer(maxFileCount:Int) {
148+
LOCK.acquire();
149+
while (FILE_RINGBUFFER.length > maxFileCount) {
150+
var fileName:String = FILE_RINGBUFFER.shift();
151+
var fileHashes:Null<Array<CodeHashes>> = FILE_HASHES.get(fileName);
152+
if (fileHashes == null) {
153+
continue;
154+
}
155+
for (hash in fileHashes) {
156+
SIMILAR_HASHES.remove(hash.similarHash);
157+
IDENTICAL_HASHES.remove(hash.identicalHash);
158+
}
159+
FILE_HASHES.remove(fileName);
160+
}
161+
LOCK.release();
162+
}
163+
164+
static function cleanupFile(fileName:String) {
165+
LOCK.acquire();
166+
FILE_RINGBUFFER.remove(fileName);
167+
var fileHashes:Null<Array<CodeHashes>> = FILE_HASHES.get(fileName);
168+
if (fileHashes != null) {
169+
for (hash in fileHashes) {
170+
SIMILAR_HASHES.remove(hash.similarHash);
171+
IDENTICAL_HASHES.remove(hash.identicalHash);
172+
}
173+
FILE_HASHES.remove(fileName);
174+
}
175+
LOCK.release();
176+
}
177+
#end
178+
125179
function makeCodeHashes(token:TokenTree):CodeHashes {
126180
var similar:StringBuf = new StringBuf();
127181
var identical:StringBuf = new StringBuf();
@@ -151,7 +205,10 @@ class CodeSimilarityCheck extends Check {
151205
switch (token.tok) {
152206
case Const(CFloat(_)):
153207
return "const_float";
154-
case Const(CString(_)):
208+
case Const(CString(s)):
209+
if (StringUtils.isStringInterpolation(s, checker.file.content, token.pos)) {
210+
return "const_string_interpol";
211+
}
155212
return "const_string";
156213
case Const(CIdent(_)):
157214
return "identifier";

0 commit comments

Comments
 (0)