List of usage examples for java.util TreeSet contains
public boolean contains(Object o)
From source file:org.openanzo.glitter.query.SPARQLAlgebra.java
/** * Conjoins two solution sets./*from ww w .j a v a 2s .c om*/ * * (A null list of solutions functions equivalently to a solution set with a single bindings-less solution. This is shorthand and is COMPLETELY different * from a solution set with zero solutions (which conjoins with any other solution set to the empty solution set).) * * * @param set1 * @param set2 * @return The conjunction of the two solution sets. */ static public SolutionSet join(SolutionSet set1, SolutionSet set2) { boolean isEnabled = RequestAnalysis.getAnalysisLogger().isDebugEnabled(); log.trace(LogUtils.GLITTER_MARKER, "join"); if (set1 == null) { if (isEnabled) RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_identityJoin-RHS] {}", Integer.toString(set2.size())); return set2; } if (set2 == null) { if (isEnabled) RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_identityJoin-LHS] {}", Integer.toString(set1.size())); return set1; } Comparator<Value> comparator = getComparator(set1, set2); if (set1.size() == 0 || set2.size() == 0) { if (isEnabled) RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_nullJoin]"); return new SolutionList(); } PatternSolution sol1[] = set1.toArray(new PatternSolution[0]); PatternSolution sol2[] = set2.toArray(new PatternSolution[0]); if (sol1.length == 1 && sol1[0].size() == 0) { if (isEnabled) RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_identityJoin-RHS] {}", Integer.toString(set2.size())); return set2; } else if (sol2.length == 1 && sol2[0].size() == 0) { if (isEnabled) RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_identityJoin-LHS] {}", Integer.toString(set1.size())); return set1; } SolutionSet newSolutions = new CustomCompareSolutionSet.ComparableSolutionList(comparator); long start = 0; if (isEnabled) { RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_startJoin] {}:{}", Integer.toString(set1.size()), Integer.toString(set2.size())); start = System.currentTimeMillis(); } TreeSet<Bindable> count = new TreeSet<Bindable>(); for (PatternSolution element : sol1) { for (Bindable bindable : element.getBoundDomain(true)) { count.add(bindable); } } TreeSet<Bindable> count2 = new TreeSet<Bindable>(); for (PatternSolution element : sol2) { for (Bindable bindable : element.getBoundDomain(true)) { count2.add(bindable); } } TreeSet<Bindable> matchSet = new TreeSet<Bindable>(); if (count.size() < count2.size()) { for (Bindable bindable : count) { if (count2.contains(bindable)) matchSet.add(bindable); } } else { for (Bindable bindable : count2) { if (count.contains(bindable)) { matchSet.add(bindable); } } } Bindable matchedBindables[] = matchSet.toArray(new Bindable[0]); if (isEnabled) { StringBuilder sb = new StringBuilder(); for (Bindable bindable : matchSet) { sb.append(bindable.toString()); sb.append(","); } RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_matchingBindings] {}", sb.toString()); } long startSort = 0; if (isEnabled) { startSort = System.currentTimeMillis(); } Arrays.sort(sol1, 0, sol1.length, new PatternSolutionImpl.SetSolutionComparator(matchSet, comparator)); if (isEnabled) { RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_leftSortTime] {}", Long.toString(System.currentTimeMillis() - startSort)); startSort = System.currentTimeMillis(); } Arrays.sort(sol2, 0, sol2.length, new PatternSolutionImpl.SetSolutionComparator(matchSet, comparator)); if (isEnabled) { RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_rightSortTime] {}", Long.toString(System.currentTimeMillis() - startSort)); startSort = System.currentTimeMillis(); } //System.err.println("Joining:" + sol1.length + ":" + sol2.length); int j = 0; //long start = System.currentTimeMillis(); if (matchSet.size() > 0) { for (PatternSolution solution : sol1) { Bindable sol1Bindables[] = solution.getBoundDomainArray(); boolean done = false; for (int k = j; k < sol2.length && !done; k++) { if (sol1Bindables.length == 0) { newSolutions.add(sol2[k]); } else { boolean match = true; boolean cloned = false; PatternSolution solution2 = sol2[k]; boolean firstEmpty = true; Bindable bindables2[] = solution2.getBoundDomainArray(); int m = 0; if (bindables2.length > 0) { boolean breaker = false; for (Bindable element : matchedBindables) { firstEmpty = false; for (int mm = m; mm < bindables2.length && !breaker; mm++) { int comp1 = element.compareTo(bindables2[mm]); if (comp1 == 0) { Value term = solution.getBinding(element); Value term2 = solution2.getBinding(bindables2[mm]); //If term is null, this means that lh solution does not have a binding for a shared binding, so have to do slow conjoin if (term == null) { PatternSolution psNew = conjoin(solution, solution2); if (psNew != null) { newSolutions.add(psNew); } match = false; breaker = true; } else { int comp = comparator.compare(term, term2); if (comp > 0) { match = false; breaker = true; j = k; break; } else if (comp < 0) { match = false; done = true; breaker = true; break; } else { if (!cloned) { bindables2 = bindables2.clone(); cloned = true; } // conjunction.put(bindables2[mm], term); bindables2[mm] = null; m = mm + 1; break; } } } else if (comp1 > 0) { m = mm; } } if (breaker) break; } if (match) { if (firstEmpty) { newSolutions.add(solution2); } else { PatternSolutionImpl newSolution = new PatternSolutionImpl(solution); for (Bindable element : bindables2) { if (element != null) { newSolution.setBinding(element, solution2.getBinding(element)); } } newSolutions.add(new PatternSolutionImpl(newSolution)); } } } else { newSolutions.add(solution); } } } } } else { for (PatternSolution solution : sol1) { for (PatternSolution solution2 : sol2) { Bindable bindable[] = new Bindable[solution.getBoundDomainArray().length + solution2.getBoundDomainArray().length]; Value value[] = new Value[solution.getBoundDomainArray().length + solution2.getBoundDomainArray().length]; Bindable bs[] = solution.getBoundDomain(false); Value vs[] = solution.getBoundVariablesArray(false); System.arraycopy(bs, 0, bindable, 0, bs.length); System.arraycopy(vs, 0, value, 0, vs.length); int last = vs.length; bs = solution2.getBoundDomain(false); vs = solution2.getBoundVariablesArray(false); System.arraycopy(bs, 0, bindable, last, bs.length); System.arraycopy(vs, 0, value, last, vs.length); newSolutions.add(new PatternSolutionImpl(bindable, value)); } } } //System.err.println("Join:" + (System.currentTimeMillis() - start) + ":" + newSolutions.size()); if (isEnabled) { RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_endJoin] {}:{}", Integer.toString(newSolutions.size()), Long.toString(System.currentTimeMillis() - start)); } return newSolutions; /* SolutionSet newSolutions2 = new SolutionList(); for (PatternSolution ps1 : set1) { for (PatternSolution ps2 : set2) { PatternSolution psNew = ps1.conjoin(ps2); if (psNew != null) newSolutions2.add(psNew); } } return newSolutions;*/ }
From source file:org.orbeon.oxf.util.SystemUtils.java
/** * Walks class loader hierarchy of clazz looking for instances of URLClassLoader. * For each found gets file urls and adds, converted, elements to the path. * Note that the more junior a class loader is the later in the path it's * contribution is. <br/>// w ww. ja v a2 s.c o m * Also, tries to deal with fact that urls may or may not be encoded. * Converts the urls to java.io.File and checks for existence. If it * exists file name is used as is. If not name is URLDecoded. If the * decoded form exists that that is used. If neither exists then the * undecoded for is used. * * @param clazz Class to try and build a classpath from. * @return java.io.File.pathSeparator delimited path. */ public static String pathFromLoaders(final Class clazz) throws java.io.UnsupportedEncodingException { final TreeSet sysPths = new TreeSet(); gatherSystemPaths(sysPths); final StringBuilder sbuf = new StringBuilder(); final LinkedList urlLst = new LinkedList(); for (ClassLoader cl = clazz.getClassLoader(); cl != null; cl = cl.getParent()) { if (!(cl instanceof java.net.URLClassLoader)) { continue; } final java.net.URLClassLoader ucl = (java.net.URLClassLoader) cl; final java.net.URL[] urls = ucl.getURLs(); if (urls == null) continue; for (int i = urls.length - 1; i > -1; i--) { final java.net.URL url = urls[i]; final String prot = url.getProtocol(); if (!"file".equalsIgnoreCase(prot)) continue; urlLst.addFirst(url); } } for (final Iterator itr = urlLst.iterator(); itr.hasNext();) { final java.net.URL url = (java.net.URL) itr.next(); final String fnam = url.getFile(); final File fil = new File(fnam); if (sysPths.contains(fil)) continue; // 11/14/2004 d : Odd test attempts to deal with fact that // a.) The URLs passed to a URLClassLoader don't have to be encoded // in general. // b.) The app class loader and the extensions class loader, the // jdk class loaders responsible for loading classes from classpath // and the extensions dir respectively, do encode their urls. // c.) java.io.File.toURL doesn't produce encoded urls. ( Perhaps // a sun bug... ) // As you can see given (a) and (c) odds are pretty good that // should anyone use something other than jdk class loaders we // will end up unencoded urls. if (!fil.exists()) { final String unEncNam = URLDecoder.decode(fnam, "utf-8"); final File unEncFil = new File(unEncNam); if (unEncFil.exists()) sbuf.append(unEncNam); } else { sbuf.append(fnam); } sbuf.append(File.pathSeparatorChar); } final String ret = sbuf.toString(); return ret; }
From source file:org.opendatakit.aggregate.odktables.impl.api.FileServiceImpl.java
@Override public Response deleteFile(@PathParam("odkClientVersion") String odkClientVersion, @PathParam("filePath") List<PathSegment> segments) throws IOException, ODKTaskLockException, PermissionDeniedException, ODKDatastoreException { TreeSet<GrantedAuthorityName> ui = SecurityServiceUtil.getCurrentUserSecurityInfo(cc); if (!ui.contains(GrantedAuthorityName.ROLE_ADMINISTER_TABLES)) { throw new PermissionDeniedException("User does not belong to the 'Administer Tables' group"); }/*from w ww .j a v a2 s . c o m*/ if (segments.size() < 1) { return Response.status(Status.BAD_REQUEST).entity(FileService.ERROR_MSG_INSUFFICIENT_PATH) .header(ApiConstants.OPEN_DATA_KIT_VERSION_HEADER, ApiConstants.OPEN_DATA_KIT_VERSION) .header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true") .build(); } String appRelativePath = constructPathFromSegments(segments); String tableId = FileManager.getTableIdForFilePath(appRelativePath); // DbTableFileInfo.NO_TABLE_ID -- means that we are working with app-level permissions if (!DbTableFileInfo.NO_TABLE_ID.equals(tableId)) { userPermissions.checkPermission(appId, tableId, TablePermission.WRITE_PROPERTIES); } FileManager fm = new FileManager(appId, cc); fm.deleteFile(odkClientVersion, tableId, appRelativePath); return Response.ok().header(ApiConstants.OPEN_DATA_KIT_VERSION_HEADER, ApiConstants.OPEN_DATA_KIT_VERSION) .header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true") .build(); }
From source file:org.opendatakit.aggregate.odktables.impl.api.FileServiceImpl.java
@Override public Response putFile(@PathParam("odkClientVersion") String odkClientVersion, @PathParam("filePath") List<PathSegment> segments, byte[] content) throws IOException, ODKTaskLockException, PermissionDeniedException, ODKDatastoreException { TreeSet<GrantedAuthorityName> ui = SecurityServiceUtil.getCurrentUserSecurityInfo(cc); if (!ui.contains(GrantedAuthorityName.ROLE_ADMINISTER_TABLES)) { throw new PermissionDeniedException("User does not belong to the 'Administer Tables' group"); }//from www.java 2 s .c o m if (segments.size() < 1) { return Response.status(Status.BAD_REQUEST).entity(FileService.ERROR_MSG_INSUFFICIENT_PATH) .header(ApiConstants.OPEN_DATA_KIT_VERSION_HEADER, ApiConstants.OPEN_DATA_KIT_VERSION) .header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true") .build(); } String appRelativePath = constructPathFromSegments(segments); String tableId = FileManager.getTableIdForFilePath(appRelativePath); String contentType = req.getContentType(); // DbTableFileInfo.NO_TABLE_ID -- means that we are working with app-level // permissions if (!DbTableFileInfo.NO_TABLE_ID.equals(tableId)) { userPermissions.checkPermission(appId, tableId, TablePermission.WRITE_PROPERTIES); } FileManager fm = new FileManager(appId, cc); FileContentInfo fi = new FileContentInfo(contentType, Long.valueOf(content.length), null, content); FileChangeDetail outcome = fm.putFile(odkClientVersion, tableId, appRelativePath, userPermissions, fi); UriBuilder ub = info.getBaseUriBuilder(); ub.path(OdkTables.class, "getFilesService"); URI self = ub.path(FileService.class, "getFile").build(appId, odkClientVersion, appRelativePath); String locationUrl = self.toURL().toExternalForm(); return Response.status((outcome == FileChangeDetail.FILE_UPDATED) ? Status.ACCEPTED : Status.CREATED) .header("Location", locationUrl) .header(ApiConstants.OPEN_DATA_KIT_VERSION_HEADER, ApiConstants.OPEN_DATA_KIT_VERSION) .header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true") .build(); }
From source file:de.uzk.hki.da.cb.ScanAction.java
/** * @author Daniel M. de Oliveira//from w ww. j a va2s. c om * @param filesArchival */ private List<ConversionInstruction> generateConversionInstructions(List<DAFile> filesArchival) { List<ConversionInstruction> cis = new ArrayList<ConversionInstruction>(); TreeSet<String> neverConverted = this.neverConverted(); for (DAFile file : filesArchival) { String relPath = file.getRelative_path(); if (neverConverted.contains(relPath)) { logger.debug("Skipping file: " + relPath); } else { List<ConversionPolicy> convPolicy = preservationSystem.getApplicablePolicies(file, false); if (convPolicy.size() < 1) { logger.debug("No policy: " + relPath); } else { if (FriendlyFilesUtils.isFriendlyFile(relPath, o.getFriendlyFileExtensions())) { this.suppressedEvent(file); logger.debug("Friendly file: " + relPath); } else { for (ConversionPolicy p : convPolicy) { ConversionInstruction ci = ciB.assembleConversionInstruction(wa, file, p); ci.setSource_file(file); cis.add(ci); logger.debug(ci.toString()); } } } } } return cis; }
From source file:org.opendatakit.api.odktables.FileService.java
/** * Delete only works on full file paths -- you cannot specify a partial path or wildcard (*) path. * * @param odkClientVersion// w w w . ja v a2 s .com * @param segments * @return * @throws IOException * @throws ODKTaskLockException * @throws ODKOverQuotaException * @throws ODKEntityNotFoundException * @throws ODKDatastoreException * @throws PermissionDeniedException */ @DELETE @Path("{odkClientVersion}/{filePath:.*}") public Response deleteFile(@PathParam("odkClientVersion") String odkClientVersion, @PathParam("filePath") List<PathSegment> segments) throws IOException, ODKTaskLockException, ODKEntityNotFoundException, ODKOverQuotaException, PermissionDeniedException, ODKDatastoreException { TreeSet<GrantedAuthorityName> ui = SecurityServiceUtil.getCurrentUserSecurityInfo(callingContext); if (!ui.contains(GrantedAuthorityName.ROLE_ADMINISTER_TABLES)) { throw new PermissionDeniedException("User does not belong to the 'Administer Tables' group"); } if (segments.size() < 1) { return Response.status(Status.BAD_REQUEST).entity(FileService.ERROR_MSG_INSUFFICIENT_PATH) .header(ApiConstants.OPEN_DATA_KIT_VERSION_HEADER, ApiConstants.OPEN_DATA_KIT_VERSION) .header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true") .build(); } String appRelativePath = constructPathFromSegments(segments); String tableId = FileManager.getTableIdForFilePath(appRelativePath); // DbTableFileInfo.NO_TABLE_ID -- means that we are working with app-level // permissions if (!DbTableFileInfo.NO_TABLE_ID.equals(tableId)) { userPermissions.checkPermission(appId, tableId, TablePermission.WRITE_PROPERTIES); } FileManager fm = new FileManager(appId, callingContext); fm.deleteFile(odkClientVersion, tableId, appRelativePath); return Response.ok().header(ApiConstants.OPEN_DATA_KIT_VERSION_HEADER, ApiConstants.OPEN_DATA_KIT_VERSION) .header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true") .build(); }
From source file:org.opendatakit.api.odktables.RealizedTableService.java
/** * Delete a realized tableId and all its data (supplied in implementation constructor) * * @return successful status code if successful. * @throws ODKDatastoreException/*from www .j av a 2 s . c o m*/ * @throws ODKTaskLockException * @throws PermissionDeniedException */ @DELETE public Response deleteTable() throws ODKDatastoreException, ODKTaskLockException, PermissionDeniedException { TreeSet<GrantedAuthorityName> ui = SecurityServiceUtil.getCurrentUserSecurityInfo(cc); if (!ui.contains(GrantedAuthorityName.ROLE_ADMINISTER_TABLES)) { throw new PermissionDeniedException("User does not belong to the 'Administer Tables' group"); } tm.deleteTable(tableId); return Response.ok().header(ApiConstants.OPEN_DATA_KIT_VERSION_HEADER, ApiConstants.OPEN_DATA_KIT_VERSION) .header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true") .build(); }
From source file:org.opendatakit.api.odktables.FileService.java
@POST @Path("{odkClientVersion}/{filePath:.*}") public Response putFile(@PathParam("odkClientVersion") String odkClientVersion, @PathParam("filePath") List<PathSegment> segments, byte[] content) throws IOException, ODKTaskLockException, PermissionDeniedException, ODKDatastoreException { TreeSet<GrantedAuthorityName> ui = SecurityServiceUtil.getCurrentUserSecurityInfo(callingContext); if (!ui.contains(GrantedAuthorityName.ROLE_ADMINISTER_TABLES)) { throw new PermissionDeniedException("User does not belong to the 'Administer Tables' group"); }/*ww w. j a v a2s . c o m*/ if (segments.size() < 1) { return Response.status(Status.BAD_REQUEST).entity(FileService.ERROR_MSG_INSUFFICIENT_PATH) .header(ApiConstants.OPEN_DATA_KIT_VERSION_HEADER, ApiConstants.OPEN_DATA_KIT_VERSION) .header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true") .build(); } String appRelativePath = constructPathFromSegments(segments); String tableId = FileManager.getTableIdForFilePath(appRelativePath); String contentType = req.getContentType(); // DbTableFileInfo.NO_TABLE_ID -- means that we are working with app-level // permissions if (!DbTableFileInfo.NO_TABLE_ID.equals(tableId)) { userPermissions.checkPermission(appId, tableId, TablePermission.WRITE_PROPERTIES); } FileManager fm = new FileManager(appId, callingContext); FileContentInfo fi = new FileContentInfo(appRelativePath, contentType, Long.valueOf(content.length), null, content); ConfigFileChangeDetail outcome = fm.putFile(odkClientVersion, tableId, fi, userPermissions); UriBuilder ub = info.getBaseUriBuilder(); ub.path(OdkTables.class, "getFilesService"); URI self = ub.path(FileService.class, "getFile") .build(ArrayUtils.toArray(appId, odkClientVersion, appRelativePath), false); String locationUrl = self.toURL().toExternalForm(); return Response.status((outcome == ConfigFileChangeDetail.FILE_UPDATED) ? Status.ACCEPTED : Status.CREATED) .header("Location", locationUrl) .header(ApiConstants.OPEN_DATA_KIT_VERSION_HEADER, ApiConstants.OPEN_DATA_KIT_VERSION) .header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true") .build(); }
From source file:fr.paris.lutece.plugins.directory.utils.DirectoryUtils.java
/** * Like {@link List#retainAll(java.util.Collection)}, keeping first list * order. This method is based on the fact that list1 and list2 have unique * elements.//from ww w.j ava2 s .c om * * @param list1 * the first list * @param list2 * the other list * @return first list */ public static List<Integer> retainAllIdsKeepingFirstOrder(List<Integer> list1, List<Integer> list2) { Iterator<Integer> it = list1.iterator(); // makes contains quicker TreeSet<Integer> ts = new TreeSet<Integer>(list2); while (it.hasNext()) { if (!ts.contains(it.next())) { it.remove(); } } return list1; }
From source file:org.openanzo.glitter.query.SPARQLAlgebra.java
/** * Implements the SPARQL LeftJoin operator. (For the SPARQL <tt>OPTIONAL</tt> keyword.) * //from w w w .j a va 2 s .com * @param set1 * The left-hand-side of the outer join. See the SPARQL spec. for precise semantics. * @param set2 * The right-hand-side of the outer join. * @param filters * Filters that are scoped to this left join. * @return The results of applying the LeftJoin operator. */ static public SolutionSet leftJoin(SolutionSet set1, SolutionSet set2, Set<Expression> filters) { Comparator<Value> comparator = getComparator(set1, set2); if (set1 == null) return filterSolutions(set2, filters); if (set2 == null) return filterSolutions(set1, filters); long start = 0; boolean isEnabled = RequestAnalysis.getAnalysisLogger().isDebugEnabled(); if (isEnabled) { RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_startLeftJoin] {}:{}", Integer.toString(set1.size()), Integer.toString(set2.size())); start = System.currentTimeMillis(); } SolutionSet newSolutions = new CustomCompareSolutionSet.ComparableSolutionList(comparator); PatternSolution sol1[] = set1.toArray(new PatternSolution[0]); // count1 contains all the variables (& bnodes) in the first (required) // solution set. count2 contains all the bindables that appear in the // second. TreeSet<Bindable> count1 = new TreeSet<Bindable>(); for (PatternSolution element : sol1) { for (Bindable bindable : element.getBoundDomain(true)) { count1.add(bindable); } } PatternSolution sol2[] = set2.toArray(new PatternSolution[0]); TreeSet<Bindable> count2 = new TreeSet<Bindable>(); for (PatternSolution element : sol2) { for (Bindable bindable : element.getBoundDomain(true)) { count2.add(bindable); } } // populate matchSet with all the bindables that are in common // between the two solution sets. Order the Binding names in the matchSet TreeSet<Bindable> matchSet = new TreeSet<Bindable>(); if (count1.size() < count2.size()) { for (Bindable bindable : count1) { if (count2.contains(bindable)) matchSet.add(bindable); } } else { for (Bindable bindable : count2) { if (count1.contains(bindable)) { matchSet.add(bindable); } } } Bindable matchedBindables[] = matchSet.toArray(new Bindable[0]); //Matt:Sort the solutions in sol1+sol2 based on the ordered matchSet, ie //the matchSet is sorted alphabetically by the binding names, so sort the solutions in sol1 + sol2 //by a progressive alphabetical sort based on the ordered binding names, ie //if you have binding "A" and binding "B", the solutions would get ordered first by //and alphabetical sort of the Binding "A" values, and when the values of Binding "A" match, //alphabetical sort of Biding "B" values. // //Example: 2 Binding "A" and "B" // // row 1: A=adam B=zebra // row 2: A=charlie b=apple // row 3: A=adam B=david // row 4: A=zed B=arrow //Sort order would be // row 3: A=adam B=david //since adam is alphabetically lower than charlie and zed, and then david is lower than zebra // row 1: A=adam B=zebra // row 2: A=charlie b=apple //charlie is after adam, and before zed, apple isn't used in sort since there are no other values with a match on A // row 4: A=zed B=arrow //zed is after adam and charlie, arrow isn't used in sort since there are no other values with a match on A long startSort = 0; if (isEnabled) { startSort = System.currentTimeMillis(); } Arrays.sort(sol1, 0, sol1.length, new PatternSolutionImpl.SetSolutionComparator(matchSet, comparator)); if (isEnabled) { RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_leftSortTime] {}", Long.toString(System.currentTimeMillis() - startSort)); startSort = System.currentTimeMillis(); } Arrays.sort(sol2, 0, sol2.length, new PatternSolutionImpl.SetSolutionComparator(matchSet, comparator)); if (isEnabled) { RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_rightSortTime] {}", Long.toString(System.currentTimeMillis() - startSort)); startSort = System.currentTimeMillis(); } // j is our current starting position for iterating over the optional // solutions. we can skip optional solutions p..r if we know that all // of them are incompatible with required solutions // //Matt:You know they are incompatiable because the sort order of the 2 solution sets is the same int j = 0; //long start = System.currentTimeMillis(); for (PatternSolution solution1 : sol1) { Bindable sol1Bindables[] = solution1.getBoundDomainArray(); boolean oneMatch = false; boolean done = false; //Matt:Since the solutions in the 2 sets are in the same sort order, you know that if //you compare solution(k) from the right solution set with solution(i) from the left solution set and solution(k) is //lower in the sort order than solution(i), then all the remaining solutions in left solution set will also have a //higher sort order than solutions(0-k) in right solution set. for (int k = j; k < sol2.length && !done; k++) { if (sol1Bindables.length == 0) { // the empty solution is the unit / identity solution oneMatch = true; newSolutions.add(sol2[k]); } else { // match starts as false; if all the bindings in solution1 // match bindings in solution2 (i.e. solution1 is compatible // with solution2), then match==true. // // Lee: There seems to be a bug here if the intersection of // bindable1 and bindable2 is empty: in this case, solution1 does not get // extended by solution2, as it should be. Would this be fixed // by defaulting match to true? boolean match = true; boolean cloned = false; PatternSolution solution2 = sol2[k]; // Map<Bindable, Value> conjunction = new HashMap<Bindable, Value>(); Bindable bindables2[] = solution2.getBoundDomainArray(); // we traverse the bindables in these solutions in parallel // this counter is our current starting position in the optional bindables //Matt:Since the bindables in the 2 arrays are in the same sort order, you know that if //you compare bindable(m) from the right array with bindable(l) from the left array and bindable(m) is //lower in the sort order than bindable(l), then all the remaining bindable in left array will also have a //higher sort order than bindable(0-m) in right array. int m = 0; // breaker is true if solution1 and solution2 are not compatible; // once one non-compatible binding has been found, the rest of // the bindables in solution1 will be copied, but we won't bother // checking them against solution2. boolean breaker = false; if (bindables2.length > 0) { for (Bindable element : matchedBindables) { // put in the required solution, unmodified, regardless of whether // we've found any incompatibilities yet //conjunction.put(element, solution1.getBinding(element)); for (int mm = m; mm < bindables2.length && !breaker; mm++) { int comp1 = element.compareTo(bindables2[mm]); if (comp1 == 0) { // the same bindable is in both solutions, check // the value its bound to; note that solutions in each // solution set are ordered by comparing terms (bound // values) Value term1 = solution1.getBinding(element); //If term is null, this means that lh solution does not have a binding for a shared binding, so have to do slow conjoin if (term1 == null) { PatternSolution newSolution = conjoin(solution1, solution2); if (newSolution != null) { if (keepSolution(newSolution, filters)) { // oneMatch indicates that solution1 (from the left-hand side) // was compatible with at least one solution from the right-hand // solution set oneMatch = true; newSolutions.add(newSolution); } } match = false; breaker = true; } else { Value term2 = solution2.getBinding(bindables2[mm]); int comp = comparator.compare(term1, term2); if (comp > 0) { // See note above - since the left solution has // a higher value for this term, we can skip all // right-hand solutions before this one when we // start with the next left-hand solution. match = false; breaker = true; j = k; break; } else if (comp < 0) { match = false; breaker = true; done = true; break; } else { if (!cloned) { bindables2 = bindables2.clone(); cloned = true; } match = true; // conjunction.put(bindables2[mm], term); bindables2[mm] = null; m = mm + 1; break; } } } else if (comp1 > 0) { m = mm; } } } // match is true if all of the terms in common between solution1 // and solution2 are bound to the same value in both solutions if (match) { PatternSolutionImpl newSolution = new PatternSolutionImpl(solution1); // before we accept this conjoined solution, we need to make sure // it passes the filter for (Bindable element : bindables2) { // bindings that match those in solution1 were nulled out above // so if a binding is not null, it extends solution 1 and we copy // it into the conjunction if (element != null) { newSolution.setBinding(element, solution2.getBinding(element)); } } if (keepSolution(newSolution, filters)) { // oneMatch indicates that solution1 (from the left-hand side) // was compatible with at least one solution from the right-hand // solution set oneMatch = true; newSolutions.add(newSolution); } } } } } // if solution1 wasn't compatible with any solutions in the right-hand side, then we just // copy solution1 into our resultset untouched if (!oneMatch) { newSolutions.add(solution1); } } //System.err.println("LeftJoin:" + (System.currentTimeMillis() - start) + ":" + newSolutions.size()); if (isEnabled) { RequestAnalysis.getAnalysisLogger().debug(LogUtils.GLITTER_MARKER, "[glitter_SPARQLAlgebra_endLeftJoin] {}:{}", Integer.toString(newSolutions.size()), Long.toString(System.currentTimeMillis() - start)); } return newSolutions; /*if (set1 == null) return set2; if (set2 == null) return set1; SolutionSet newSolutions = new SolutionList(); for (PatternSolution ps1 : set1) { boolean extendedPs1 = false; for (PatternSolution ps2 : set2) { PatternSolution psNew = ps1.conjoin(ps2); if (psNew != null) { extendedPs1 = true; newSolutions.add(psNew); } } // for this to be a left outer join, we have to include the left-hand // pattern solution even if all of the right-hand solutions conflict // with it if (!extendedPs1) newSolutions.add(ps1); } return newSolutions; */ }