blob: 115a3cf5b5667c6da6a53dae9e689a2f0129b65b [file] [log] [blame]
package com.intellij.dupLocator.treeHash;
import com.intellij.dupLocator.NodeSpecificHasher;
import com.intellij.dupLocator.util.PsiFragment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.tree.LeafElement;
import java.util.List;
/**
* Created by Maxim.Mossienko on 2/17/14.
*/
public class TreeHashingUtils {
protected static TreeHashResult hashCodeBlockForIndexing(AbstractTreeHasher treeHasher, FragmentsCollector callBack,
List<? extends PsiElement> statements,
PsiFragment upper,
NodeSpecificHasher hasher) {
final int statementsSize = statements.size();
if (statementsSize > 0) {
final PsiFragment fragment = treeHasher.buildFragment(hasher, statements, 0, statementsSize - 1);
fragment.setParent(upper);
int cost = 0;
int hash = 0;
for (PsiElement statement : statements) {
final TreeHashResult res = treeHasher.hash(statement, null, hasher);
hash = hash* 31 + res.getHash();
cost += res.getCost();
}
TreeHashResult result = new TreeHashResult(hash, cost, treeHasher.buildFragment(hasher, statements, 0, statementsSize - 1));
if (callBack != null && statementsSize > 1) callBack.add(hash, cost, fragment);
return result;
}
return new TreeHashResult(1, 0, treeHasher.buildFragment(hasher, statements, 0, statementsSize - 1));
}
static TreeHashResult computeElementHashForIndexing(AbstractTreeHasher base,
FragmentsCollector callBack,
PsiElement root,
PsiFragment upper,
NodeSpecificHasher hasher
) {
final List<PsiElement> children = hasher.getNodeChildren(root);
final PsiFragment fragment = base.buildFragment(hasher, root, base.getCost(root));
if (upper != null) {
fragment.setParent(upper);
}
final int size = children.size();
if (size == 0 && !(root instanceof LeafElement)) {
// contains only whitespaces and other unmeaning children
return new TreeHashResult(0, hasher.getNodeCost(root), fragment);
}
final int discardCost = base.getDiscardCost(root);
int c = hasher.getNodeCost(root);
int h = hasher.getNodeHash(root);
for (int i = 0; i < size; i++) {
PsiElement child = children.get(i);
final TreeHashResult res = base.hash(child, fragment, hasher);
int childCost = res.getCost();
c += childCost;
if (childCost > discardCost || !base.ignoreChildHash(child)) {
h += res.getHash();
}
}
if (base.shouldAnonymize(root, hasher)) {
h = 0;
}
if (callBack != null) {
callBack.add(h, c, fragment);
}
return new TreeHashResult(h, c, fragment);
}
}