/******************************************************************************* * Copyright 2012 University of Southern California * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This code was developed by the Information Integration Group as part * of the Karma project at the Information Sciences Institute of the * University of Southern California. For more information, publications, * and related projects, please see: http://www.isi.edu/integration ******************************************************************************/ package edu.isi.karma.kr2rml.planning; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class TriplesMapGraph { private Set<TriplesMapLink> links; private Map<String, List<TriplesMapLink>> neighboringTriplesMapCache; private Map<String, TriplesMap> triplesMapIndex; public TriplesMapGraph() { this.links = new HashSet<>(); this.neighboringTriplesMapCache = new HashMap<>(); this.triplesMapIndex = new HashMap<>(); } public Set<TriplesMapLink> getLinks() { return links; } public void addTriplesMap(TriplesMap triplesMap) { triplesMapIndex.put(triplesMap.getId(), triplesMap); List<TriplesMapLink> neighbouringLinks = neighboringTriplesMapCache.get(triplesMap.getId()); if (neighbouringLinks == null) { neighbouringLinks = new LinkedList<>(); neighboringTriplesMapCache.put(triplesMap.getId(), neighbouringLinks); } } public void addLink(TriplesMapLink link) { links.add(link); updateCache(link); } public static TriplesMapGraph mergeGraphs(TriplesMapGraph graphToMerge1, TriplesMapGraph graphToMerge2) { TriplesMapGraph newGraph = new TriplesMapGraph(); for(TriplesMapLink link : graphToMerge1.getLinks()) { newGraph.addLink(link); } for(TriplesMapLink link : graphToMerge2.getLinks()) { newGraph.addLink(link); } return newGraph; } private void updateCache(TriplesMapLink link) { // Add source neighboring links to the cache List<TriplesMapLink> sourceNeighbouringLinks = neighboringTriplesMapCache.get(link.getSourceMap().getId()); if (sourceNeighbouringLinks == null) { sourceNeighbouringLinks = new LinkedList<>(); } sourceNeighbouringLinks.add(link); triplesMapIndex.put(link.getSourceMap().getId(),link.getSourceMap()); neighboringTriplesMapCache.put(link.getSourceMap().getId(), sourceNeighbouringLinks); // Add target neighboring links to the cache List<TriplesMapLink> targetNeighbouringLinks = neighboringTriplesMapCache.get(link.getTargetMap().getId()); if (targetNeighbouringLinks == null) { targetNeighbouringLinks = new LinkedList<>(); } targetNeighbouringLinks.add(link); triplesMapIndex.put(link.getTargetMap().getId(),link.getTargetMap()); neighboringTriplesMapCache.put(link.getTargetMap().getId(), targetNeighbouringLinks); } public List<TriplesMapLink> getAllNeighboringTriplesMap(String triplesMapId) { if (neighboringTriplesMapCache.get(triplesMapId) == null) return new LinkedList<>(); return neighboringTriplesMapCache.get(triplesMapId); } public List<String> removeLink(TriplesMapLink link) { List<String> removedTriplesMaps = new LinkedList<>(); links.remove(link); removedTriplesMaps.addAll(removeLinkFromCache(link, link.getTargetMap().getId())); removedTriplesMaps.addAll(removeLinkFromCache(link, link.getSourceMap().getId())); return removedTriplesMaps; } private List<String> removeLinkFromCache(TriplesMapLink link, String mapId) { List<String> removedTriplesMaps = new LinkedList<>(); List<TriplesMapLink> targetLinks = neighboringTriplesMapCache.get(mapId); targetLinks.remove(link); if(targetLinks.isEmpty()) { neighboringTriplesMapCache.remove(mapId); triplesMapIndex.remove(mapId); removedTriplesMaps.add(mapId); } return removedTriplesMaps; } public Set<String> getTriplesMapIds() { return triplesMapIndex.keySet(); } public String findRoot(RootStrategy strategy) { return strategy.findRoot(this); } public TriplesMap getTriplesMap(String triplesMapId) { return this.triplesMapIndex.get(triplesMapId); } public List<String> removeTriplesMap(String triplesMapId) { List<String> removedTriplesMaps = new LinkedList<>(); List<TriplesMapLink> targetLinks = neighboringTriplesMapCache.get(triplesMapId); if(targetLinks != null) { for(TriplesMapLink link : targetLinks) { removedTriplesMaps.addAll(removeLink(link)); } } else { removedTriplesMaps.add(triplesMapId); } neighboringTriplesMapCache.remove(triplesMapId); triplesMapIndex.remove(triplesMapId); return removedTriplesMaps; } public TriplesMapGraph copyGraph(HashSet<String> triplesMapsIds) { TriplesMapGraph newGraph = new TriplesMapGraph(); for(TriplesMapLink link : links) { if (triplesMapsIds != null) { triplesMapsIds.add(link.getSourceMap().getId()); triplesMapsIds.add(link.getTargetMap().getId()); } newGraph.addLink(link); } return newGraph; } public TriplesMapGraph copyGraph() { TriplesMapGraph newGraph = new TriplesMapGraph(); for(TriplesMap triplesMap : triplesMapIndex.values()) { newGraph.addTriplesMap(triplesMap); } for(TriplesMapLink link : links) { newGraph.addLink(new TriplesMapLink(link.getSourceMap(), link.getTargetMap(), link.getPredicateObjectMapLink())); } return newGraph; } public TriplesMapGraph shallowCopyGraph() { TriplesMapGraph newGraph = new TriplesMapGraph(); newGraph.links.addAll(links); for (Entry<String, List<TriplesMapLink>> entry : neighboringTriplesMapCache.entrySet()) { newGraph.neighboringTriplesMapCache.put(entry.getKey(), new LinkedList<>(entry.getValue())); } newGraph.triplesMapIndex.putAll(triplesMapIndex); return newGraph; } public void killTriplesMap(List<String> tripleMapToKill, RootStrategy strategy) { if (tripleMapToKill.isEmpty()) { return; } List<TriplesMapLink> remainedLinks = new LinkedList<>(); Set<String> visited = new HashSet<>(); killTriplesMap(strategy.findRoot(this), tripleMapToKill, remainedLinks, visited); links.clear(); neighboringTriplesMapCache.clear(); triplesMapIndex.clear(); for (TriplesMapLink link : remainedLinks) { addLink(link); } } private void killTriplesMap(String rootId, List<String> tripleMapToKill, List<TriplesMapLink> remainedLinks, Set<String> visited) { visited.add(rootId); Set<String> next = new HashSet<>(); List<TriplesMapLink> links = neighboringTriplesMapCache.get(rootId); if (links != null) { for (TriplesMapLink link : links) { if (link.getSourceMap().getId().equals(rootId) && !tripleMapToKill.contains(link.getTargetMap().getId())) { next.add(link.getTargetMap().getId()); remainedLinks.add(link); } } } for (String n : next) { if (!visited.contains(n)) { killTriplesMap(n, tripleMapToKill, remainedLinks, visited); } } } public void killPredicateObjectMap(List<String> POMToKill, RootStrategy strategy) { if (POMToKill.isEmpty()) { return; } List<TriplesMapLink> remainedLinks = new LinkedList<>(); Set<String> visited = new HashSet<>(); killPredicateObjectMap(strategy.findRoot(this), POMToKill, remainedLinks, visited); links.clear(); neighboringTriplesMapCache.clear(); triplesMapIndex.clear(); for (TriplesMapLink link : remainedLinks) { addLink(link); } } private void killPredicateObjectMap(String rootId, List<String> POMToKill, List<TriplesMapLink> remainedLinks, Set<String> visited) { visited.add(rootId); Set<String> next = new HashSet<>(); List<TriplesMapLink> links = neighboringTriplesMapCache.get(rootId); if (links != null) { for (TriplesMapLink link : links) { if (link.getSourceMap().getId().equals(rootId) && !POMToKill.contains(link.getPredicateObjectMapLink().getId())) { next.add(link.getTargetMap().getId()); remainedLinks.add(link); } } } for (String n : next) { if (!visited.contains(n)) { killPredicateObjectMap(n, POMToKill, remainedLinks, visited); } } } public void stopTriplesMap(List<String> tripleMapToStop, RootStrategy strategy) { if (tripleMapToStop.isEmpty()) { return; } List<TriplesMapLink> remainedLinks = new LinkedList<>(); Set<String> visited = new HashSet<>(); stopTriplesMap(strategy.findRoot(this), tripleMapToStop, remainedLinks, visited); links.clear(); neighboringTriplesMapCache.clear(); triplesMapIndex.clear(); for (TriplesMapLink link : remainedLinks) { addLink(link); } } private void stopTriplesMap(String rootId, List<String> tripleMapToStop, List<TriplesMapLink> remainedLinks, Set<String> visited) { visited.add(rootId); if (tripleMapToStop.contains(rootId)) { return; } Set<String> next = new HashSet<>(); List<TriplesMapLink> links = neighboringTriplesMapCache.get(rootId); if (links != null) { for (TriplesMapLink link : links) { if (link.getSourceMap().getId().equals(rootId)) { next.add(link.getTargetMap().getId()); remainedLinks.add(link); } } } for (String n : next) { if (!visited.contains(n)) { stopTriplesMap(n, tripleMapToStop, remainedLinks, visited); } } } }