public void addLinks(Collection<Pair<T, T>> links) { for (Pair<T, T> link : links) { addLink(link); } }
public HashSet<T> getAncestors(T node, int position) { return getAncestors(node, position, position); }
public HashSet<T> getDescendants(T node, int position) { return getDescendants(node, position, position); }
public void addLink(T parent, T child) { readWriteLock.writeLock().lock(); try { addDescendants(parent, child); addAncestors(parent, child); } finally { readWriteLock.writeLock().unlock(); } }
BridgeTable<String> bridgeTable = new BridgeTable<String>(); bridgeTable.addLink("A", "B"); bridgeTable.addLink("A", "C"); bridgeTable.addLink("B", "D"); bridgeTable.addLink("B", "E"); bridgeTable.addLink("C", "F"); bridgeTable.addLink("C", "G"); assertEquals(2, bridgeTable.getDescendants("A", 1).size()); assertEquals(4, bridgeTable.getDescendants("A", 2).size()); assertEquals(6, bridgeTable.getDescendants("A", 1, 2).size()); assertEquals(2, bridgeTable.getDescendants("B", 1).size()); assertEquals(0, bridgeTable.getDescendants("B", 2).size()); assertEquals(2, bridgeTable.getDescendants("B", 1, 2).size()); bridgeTable.addLink("N", "O"); bridgeTable.addLink("N", "P"); bridgeTable.addLink("O", "Q"); bridgeTable.addLink("O", "R"); bridgeTable.addLink("P", "S"); bridgeTable.addLink("P", "T"); assertEquals(2, bridgeTable.getDescendants("N", 1).size()); assertEquals(4, bridgeTable.getDescendants("N", 2).size()); assertEquals(6, bridgeTable.getDescendants("N", 1, 2).size()); assertEquals(2, bridgeTable.getDescendants("O", 1).size()); assertEquals(0, bridgeTable.getDescendants("O", 2).size()); assertEquals(2, bridgeTable.getDescendants("O", 1, 2).size());
@Test public void test_100x100() { BridgeTable<String> bridgeTable = new BridgeTable<String>(); HashSet<Pair<String, String>> links = new HashSet<Pair<String, String>>(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { links.addAll(getTreeLinks(7)); } long start = System.nanoTime(); bridgeTable.addLinks(links); long end = System.nanoTime(); System.out.println("Trees " + bridgeTable.size() + " in " + ((end - start) / 1e9)); start = System.nanoTime(); for (String key : bridgeTable.keySet()) { bridgeTable.getAncestors(key); } end = System.nanoTime(); System.out.println("By key " + bridgeTable.size() + " in " + ((end - start) / 1e9)); } }
private BridgeTable<String> doBuildCache(String tenantId) { List<AuthorityBridgeLink> links = authorityBridgeDAO.getAuthorityBridgeLinks(); BridgeTable<String> bridgeTable = new BridgeTable<String>(); try { for (AuthorityBridgeLink link : links) { bridgeTable.addLink(link.getParentName(), link.getChildName()); } } catch (ConcurrentModificationException e) { // Explain exception checkCyclic(links); // If cyclic groups is not the cause then rethrow throw e; } return bridgeTable; }
@Test public void test_16k() { // 1M = 21 for (int i = 0; i < 15; i++) { BridgeTable<String> bridgeTable = new BridgeTable<String>(); long start = System.nanoTime(); bridgeTable.addLinks(getTreeLinks(i)); long end = System.nanoTime(); double elapsed = ((end - start) / 1e9); System.out.println("" + bridgeTable.size() + " in " + elapsed); assertTrue(elapsed < 60); } }
public void removeLinks(Collection<Pair<T, T>> links) { for (Pair<T, T> link : links) { removeLink(link); } }
/** * @param parent T * @param child T */ private void addDescendants(T parent, T child) { HashMap<Integer, HashMap<T, Counter>> parentsDescendants = descendants.get(parent); if (parentsDescendants == null) { parentsDescendants = new HashMap<Integer, HashMap<T, Counter>>(); descendants.put(parent, parentsDescendants); } HashMap<Integer, HashMap<T, Counter>> childDescendantsToAdd = descendants.get(child); // add all the childs children to the parents descendants add(childDescendantsToAdd, Integer.valueOf(0), parentsDescendants, child); // add childs descendants to all parents ancestors at the correct depth HashMap<Integer, HashMap<T, Counter>> ancestorsToFixUp = ancestors.get(parent); if (ancestorsToFixUp != null) { for (Integer ancestorPosition : ancestorsToFixUp.keySet()) { HashMap<T, Counter> ancestorsToFixUpAtPosition = ancestorsToFixUp.get(ancestorPosition); for (T ancestorToFixUpAtPosition : ancestorsToFixUpAtPosition.keySet()) { HashMap<Integer, HashMap<T, Counter>> ancestorDescendants = descendants.get(ancestorToFixUpAtPosition); add(childDescendantsToAdd, ancestorPosition, ancestorDescendants, child); } } } }
BridgeTable<String> bridgeTable = new BridgeTable<String>(); bridgeTable.addLink("A", "B"); bridgeTable.addLink("C", "D"); bridgeTable.addLink("E", "F"); assertEquals(0, bridgeTable.getAncestors("A").size()); assertEquals(1, bridgeTable.getAncestors("B").size()); assertEquals(0, bridgeTable.getAncestors("C").size()); assertEquals(1, bridgeTable.getAncestors("D").size()); assertEquals(0, bridgeTable.getAncestors("E").size()); assertEquals(1, bridgeTable.getAncestors("F").size()); assertEquals(1, bridgeTable.getDescendants("A").size()); assertEquals(0, bridgeTable.getDescendants("B").size()); assertEquals(1, bridgeTable.getDescendants("C").size()); assertEquals(0, bridgeTable.getDescendants("D").size()); assertEquals(1, bridgeTable.getDescendants("E").size()); assertEquals(0, bridgeTable.getDescendants("F").size()); bridgeTable.addLink("B", "C"); assertEquals(0, bridgeTable.getAncestors("A").size()); assertEquals(1, bridgeTable.getAncestors("B").size()); assertEquals(2, bridgeTable.getAncestors("C").size()); assertEquals(3, bridgeTable.getAncestors("D").size()); assertEquals(0, bridgeTable.getAncestors("E").size()); assertEquals(1, bridgeTable.getAncestors("F").size()); assertEquals(3, bridgeTable.getDescendants("A").size());
private BridgeTable<String> doBuildCache(String tenantId) { List<AuthorityBridgeLink> links = authorityBridgeDAO.getAuthorityBridgeLinks(); BridgeTable<String> bridgeTable = new BridgeTable<String>(); try { for (AuthorityBridgeLink link : links) { bridgeTable.addLink(link.getParentName(), link.getChildName()); } } catch (ConcurrentModificationException e) { // Explain exception checkCyclic(links); // If cyclic groups is not the cause then rethrow throw e; } return bridgeTable; }
public void removeLinks(Collection<Pair<T, T>> links) { for (Pair<T, T> link : links) { removeLink(link); } }
public void addLink(T parent, T child) { readWriteLock.writeLock().lock(); try { addDescendants(parent, child); addAncestors(parent, child); } finally { readWriteLock.writeLock().unlock(); } }
/** * @param parent T * @param child T */ private void addAncestors(T parent, T child) { HashMap<Integer, HashMap<T, Counter>> childsAncestors = ancestors.get(child); if (childsAncestors == null) { childsAncestors = new HashMap<Integer, HashMap<T, Counter>>(); ancestors.put(child, childsAncestors); } HashMap<Integer, HashMap<T, Counter>> parentAncestorsToAdd = ancestors.get(parent); // add all the childs children to the parents descendants add(parentAncestorsToAdd, Integer.valueOf(0), childsAncestors, parent); // add childs descendants to all parents ancestors at the correct depth HashMap<Integer, HashMap<T, Counter>> descenantsToFixUp = descendants.get(child); if (descenantsToFixUp != null) { for (Integer descendantPosition : descenantsToFixUp.keySet()) { HashMap<T, Counter> descenantsToFixUpAtPosition = descenantsToFixUp.get(descendantPosition); for (T descenantToFixUpAtPosition : descenantsToFixUpAtPosition.keySet()) { HashMap<Integer, HashMap<T, Counter>> descendatAncestors = ancestors.get(descenantToFixUpAtPosition); add(parentAncestorsToAdd, descendantPosition, descendatAncestors, parent); } } } }
public HashSet<T> getAncestors(T node) { return getAncestors(node, 1, Integer.MAX_VALUE); }
public void addLinks(Collection<Pair<T, T>> links) { for (Pair<T, T> link : links) { addLink(link); } }
public void removeLink(Pair<T, T> link) { removeLink(link.getFirst(), link.getSecond()); }
public HashSet<T> getDescendants(T node) { return getDescendants(node, 1, Integer.MAX_VALUE); }
/** * @param parent * @param child */ private void addDescendants(T parent, T child) { HashMap<Integer, HashMap<T, Counter>> parentsDescendants = descendants.get(parent); if (parentsDescendants == null) { parentsDescendants = new HashMap<Integer, HashMap<T, Counter>>(); descendants.put(parent, parentsDescendants); } HashMap<Integer, HashMap<T, Counter>> childDescendantsToAdd = descendants.get(child); // add all the childs children to the parents descendants add(childDescendantsToAdd, Integer.valueOf(0), parentsDescendants, child); // add childs descendants to all parents ancestors at the correct depth HashMap<Integer, HashMap<T, Counter>> ancestorsToFixUp = ancestors.get(parent); if (ancestorsToFixUp != null) { for (Integer ancestorPosition : ancestorsToFixUp.keySet()) { HashMap<T, Counter> ancestorsToFixUpAtPosition = ancestorsToFixUp.get(ancestorPosition); for (T ancestorToFixUpAtPosition : ancestorsToFixUpAtPosition.keySet()) { HashMap<Integer, HashMap<T, Counter>> ancestorDescendants = descendants.get(ancestorToFixUpAtPosition); add(childDescendantsToAdd, ancestorPosition, ancestorDescendants, child); } } } }