SoftReference<TIntSet> refLeaves = leafCache[concept.getNodeIndex()];
if (refLeaves != null && refLeaves.get() != null) {
return refLeaves.get();
}
// not in cache - compute recursively
TIntSet leaves = new TIntHashSet();
leafCache[concept.getNodeIndex()] = new SoftReference<TIntSet>(leaves);
if (concept.isLeaf()) {
// for leaves, just add the concept id
leaves.add(concept.getNodeIndex());
} else {
IntrinsicICInfo icInfo = icInfoMap.get(concept.getConceptID());
// have we already computed the leaf count for this node?
// if yes, then we can ignore previously visited nodes
// if no, then compute it now and revisit previously visited nodes
// if we have to
boolean needLeaves = (icInfo != null && icInfo.getLeafCount() == 0);
TIntSet visitedNodesLocal = visitedNodes;
if (needLeaves || visitedNodesLocal == null) {
// allocate a set to keep track of nodes we've already visited
// so that we don't revisit them. if we have already computed
// this node's leaf count then we reuse whatever the caller gave
// us if non null, else allocate a new one.
// if we haven't already computed this node's leaf count,
// allocate a new set to avoid duplications in the traversal for
// this node
visitedNodesLocal = new TIntHashSet();
}
// for inner nodes, recurse
for (ConcRel child : concept.getChildren()) {
// if we've already visited a node, then don't bother adding
// that node's leaves - we already have them
if (!visitedNodesLocal.contains(child.getNodeIndex())) {
leaves.addAll(getLeaves(child, leafCache, icInfoMap, cg, w,
visitedNodesLocal));
}
}
// add this node to the set of visited nodes so we know not to
// revisit. This is only of importance if the caller gave us
// a non-empty set.
if (visitedNodes != null && visitedNodes != visitedNodesLocal) {
visitedNodes.add(concept.getNodeIndex());
visitedNodes.addAll(visitedNodesLocal);
}
// update the leaf count if we haven't done so already
if (needLeaves) {
icInfo.setLeafCount(leaves.size());
// output leaves if desired
if (w != null) {
w.write(concept.getConceptID());
w.write("\t");
w.write(Integer.toString(leaves.size()));
w.write("\t");
TIntIterator iter = leaves.iterator();
while (iter.hasNext()) {
w.write(cg.getConceptList().get(iter.next())
.getConceptID());
w.write(" ");
}