private List<SNode> getNodesImpl(String conceptFQName, boolean includeInherited) { if (includeInherited) { Set<String> allDescendantsOfConcept = ConceptDescendantsCache.getInstance().getDescendants(conceptFQName); final ArrayList<List<SNode>> nodesOfConcept = new ArrayList<List<SNode>>(allDescendantsOfConcept.size()); int cnt = 0; synchronized (myNodeMap) { // utilize the fact values in map are immutable for (String d : allDescendantsOfConcept) { List<SNode> n = myNodeMap.get(d); nodesOfConcept.add(n); cnt += n.size(); } } final ArrayList<SNode> result = new ArrayList<SNode>(cnt); for (List<SNode> l : nodesOfConcept) { result.addAll(l); } return result; } else { synchronized (myNodeMap) { return myNodeMap.get(conceptFQName); } } }
/** Subclasses shall invoke once model had changed */ protected void removed(SNode n) { if (myNodeMap.isEmpty()) { return; } ConceptInstanceMap toDelete = build(new ConceptNodeMapBuilder(n)); synchronized (myNodeMap) { myNodeMap.forget(toDelete); } }
/** Subclasses shall invoke once model had changed */ protected void added(SNode n) { if (myNodeMap.isEmpty()) { return; } ConceptInstanceMap toAdd = build(new ConceptNodeMapBuilder(n)); synchronized (myNodeMap) { myNodeMap.merge(toAdd); } }
@Override public List<SNode> getNodes(String conceptFqName, boolean includeInherited) { // notify 'model nodes read access' myModel.getRootNodes().iterator(); if (!myNodeMap.isEmpty()) { return getNodesImpl(conceptFqName, includeInherited); } synchronized (myNodeMap) { if (myNodeMap.isEmpty()) { ConceptInstanceMap all = build(new ConceptNodeMapBuilder(myModel)); all.trimValues(); // merge may reuse lists, myNodeMap.merge(all); } return getNodesImpl(conceptFqName, includeInherited); } }
/** Subclasses shall invoke once model had changed */ protected void reset() { synchronized (myNodeMap) { myNodeMap.clear(); } }