}
void rebuildMethodTree() {
long[] exactMethods = this.exactMethods.clone();
Arrays.sort(exactMethods);
IntegerArray methods = new IntegerArray(1);
int lastClass = -1;
for (int i = 0; i < exactMethods.length; ++i) {
long exactMethod = exactMethods[i];
int classIndex = (int)(exactMethod >>> 32);
if (classIndex != lastClass) {
if (lastClass >= 0) {
ClassMetadata clsData = classesMetadata.get(lastClass);
clsData.methods = methods.getAll();
methods.clear();
}
lastClass = classIndex;
}
int methodIndex = (int)exactMethod;
methods.add(methodIndex);
}
if (lastClass >= 0) {
ClassMetadata clsData = classesMetadata.get(lastClass);
clsData.methods = methods.getAll();
Arrays.sort(clsData.methods);
}
int[] start = new int[exactMethods.length];
Arrays.fill(start, -1);
IntegerArray data = new IntegerArray(1);
IntegerArray next = new IntegerArray(1);
for (int i = 0; i < classesMetadata.size(); ++i) {
ClassMetadata clsData = classesMetadata.get(i);
if (clsData.parentId == null || clsData.methods == null) {
continue;
}
for (int methodIndex : clsData.methods) {
ClassMetadata superclsData = classesMetadata.get(clsData.parentId);
Integer parentId = clsData.parentId;
while (superclsData != null) {
if (superclsData.methods != null && Arrays.binarySearch(superclsData.methods, methodIndex) >= 0) {
int childMethod = getExactMethodIndex(i, methodIndex);
int parentMethod = getExactMethodIndex(parentId, methodIndex);
int ptr = start[parentMethod];
start[parentMethod] = data.size();
data.add(childMethod);
next.add(ptr);
break;
}
parentId = superclsData.parentId;
superclsData = parentId != null ? classesMetadata.get(parentId) : null;
}
}
}
MethodTree methodTree = new MethodTree();
methodTree.offsets = new int[start.length + 1];
methodTree.data = new int[data.size()];
int index = 0;
for (int i = 0; i < start.length; ++i) {
int ptr = start[i];
while (ptr != -1) {
methodTree.data[index++] = data.get(ptr);
ptr = next.get(ptr);
}
methodTree.offsets[i + 1] = index;
}
this.methodTree = methodTree;
}