/******************************************************************************* * Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * File: $Source: /cvsroot/slrp/boca/com.ibm.adtech.boca.core/src/com/ibm/adtech/boca/model/Attic/QuadStore.java,v $ * Created by: Matthew Roy ( <a href="mailto:mroy@us.ibm.com">mroy@us.ibm.com </a>) * Created on: Apr 25, 2007 * Revision: $Id: QuadStore.java 168 2007-07-31 14:11:14Z mroy $ * * Contributors: * IBM Corporation - initial API and implementation * Cambridge Semantics Incorporated - Fork to Anzo *******************************************************************************/ package org.openanzo.rdf; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.apache.commons.collections15.MultiMap; import org.openanzo.exceptions.AnzoException; import org.openanzo.exceptions.AnzoRuntimeException; import org.openanzo.exceptions.ExceptionConstants; import org.openanzo.exceptions.LogUtils; import org.openanzo.glitter.Engine; import org.openanzo.glitter.dataset.DefaultQueryDataset; import org.openanzo.glitter.query.QueryResults; import org.openanzo.glitter.syntax.concrete.ParseException; import org.openanzo.rdf.query.CoreEngineConfig; import org.openanzo.rdf.query.QuadStoreEngineConfig; import org.openanzo.rdf.utils.MultiTreeArrayMap; import org.openanzo.rdf.utils.UriGenerator; import org.openanzo.rdf.vocabulary.Anzo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Core storage of quads with indexes for s,p,o,nguri, po, and sp * * @author Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com </a>) * */ public class MemQuadStore extends BaseQuadStore implements IQuadStore { private static final Logger log = LoggerFactory.getLogger(MemQuadStore.class); //Set of all statements in store private final Collection<Statement> statements; //Index map of namedGraphUris to statements private final MultiMap<URI, Statement> namedGraphMap; //Index map of subjects to statements private final MultiMap<Resource, Statement> subjectMap; //Index map of predicates to statements private final MultiMap<URI, Statement> predMap; //Index map of object to statements private final MultiMap<Value, Statement> objMap; //Index map of predicates/object to statements private final Map<URI, MultiMap<Value, Statement>> poIndex; //Index map of predicate/subject to statements private final Map<URI, MultiMap<Resource, Statement>> psIndex; private final Engine glitter; /** * Initialize quadstore's statement set and indexes */ public MemQuadStore() { statements = new HashSet<Statement>(); subjectMap = new MultiTreeArrayMap<Resource, Statement>(); predMap = new MultiTreeArrayMap<URI, Statement>(); objMap = new MultiTreeArrayMap<Value, Statement>(); namedGraphMap = new MultiTreeArrayMap<URI, Statement>(); poIndex = new TreeMap<URI, MultiMap<Value, Statement>>(); psIndex = new TreeMap<URI, MultiMap<Resource, Statement>>(); CoreEngineConfig config = new QuadStoreEngineConfig(this); glitter = new Engine(config); } /** * Add statements to store and index them * * @param statements * Statements to add * @throws AnzoRuntimeException * if the namedGraphURI of a statement is null */ public void add(Statement... statements) { synchronized (this.statements) { for (Statement stmt : statements) { if (stmt.getNamedGraphUri() == null) { throw new AnzoRuntimeException(ExceptionConstants.CLIENT.URI_NOT_NULL); } if (stmt.getSubject() == null || stmt.getPredicate() == null || stmt.getObject() == null) throw new IllegalStateException("statement cannot contain nulls"); if (this.statements.add(stmt)) { addMaps(stmt); } } } } /** * Delete statements from store and remove indexes * * @param statements * Statements to delete * @throws AnzoRuntimeException * if the namedGraphURI of a statement is null */ public void remove(Statement... statements) { synchronized (this.statements) { for (Statement stmt : statements) { if (stmt.getNamedGraphUri() == null) { throw new AnzoRuntimeException(ExceptionConstants.CLIENT.URI_NOT_NULL); } if (this.statements.remove(stmt)) { removeMaps(stmt); } } } } /** * Index this statement * * @param stmt * Statement to index */ private void addMaps(Statement stmt) { URI c = stmt.getNamedGraphUri(); Resource s = stmt.getSubject(); URI p = stmt.getPredicate(); Value o = stmt.getObject(); subjectMap.put(s, stmt); predMap.put(p, stmt); objMap.put(o, stmt); namedGraphMap.put(c, stmt); MultiMap<Value, Statement> poIndexMap = poIndex.get(p); if (poIndexMap == null) { poIndexMap = new MultiTreeArrayMap<Value, Statement>(); poIndex.put(p, poIndexMap); } poIndexMap.put(o, stmt); MultiMap<Resource, Statement> psIndexMap = psIndex.get(p); if (psIndexMap == null) { psIndexMap = new MultiTreeArrayMap<Resource, Statement>(); psIndex.put(p, psIndexMap); } psIndexMap.put(s, stmt); } /** * Remove indexes for this statement * * @param stmt * statement to deindex */ private void removeMaps(Statement stmt) { Resource c = stmt.getNamedGraphUri(); Resource s = stmt.getSubject(); URI p = stmt.getPredicate(); Value o = stmt.getObject(); subjectMap.remove(s, stmt); predMap.remove(p, stmt); objMap.remove(o, stmt); namedGraphMap.remove(c, stmt); MultiMap<Value, Statement> poIndexMap = poIndex.get(p); if (poIndexMap != null) { poIndexMap.remove(o, stmt); if (poIndexMap.size() == 0) { poIndex.remove(p); } } MultiMap<Resource, Statement> psIndexMap = psIndex.get(p); if (psIndexMap != null) { psIndexMap.remove(s, stmt); if (psIndexMap.size() == 0) { psIndex.remove(p); } } } public Collection<Statement> find(Resource subj, URI pred, Value obj, URI... namedGraphUris) { if (namedGraphUris != null && namedGraphUris.length == 1 && namedGraphUris[0] == null) { namedGraphUris = new URI[0]; } return findStatements(subj, pred, obj, namedGraphUris); } /** * Find set of statements that match provided parameters * * @param subj * Subject value to match, or wildcard if null * @param pred * predicate value to match, or wildcard if null * @param obj * Object value to match, or wildcard if null * @param namedGraphUris * namedGraphURI value to match, or wildcard if null * @return Collection<Statement> of matching statements */ private Collection<Statement> findStatements(Resource subj, URI pred, Value obj, URI... namedGraphUris) { //Determine what kind of query this is based on what values are provided int type = 0; if (subj != null) { type |= 1; } if (pred != null) { type |= 2; } if (obj != null) { type |= 4; } if (namedGraphUris != null && namedGraphUris.length > 0) { type |= 8; } synchronized (statements) { switch (type) { case 0: ArrayList<Statement> results = new ArrayList<Statement>(statements); return results; case 1: Collection<Statement> sSet = subjectMap.get(subj); if (sSet == null) { return Collections.<Statement> emptyList(); } else { return org.openanzo.rdf.utils.Collections.copyCollection(sSet); } case 2: Collection<Statement> pSet = predMap.get(pred); if (pSet == null) { return Collections.<Statement> emptyList(); } else { return org.openanzo.rdf.utils.Collections.copyCollection(pSet); } case 3: return findPS(subj, pred); case 4: Collection<Statement> oSet = objMap.get(obj); if (oSet == null) { return Collections.<Statement> emptyList(); } else { return org.openanzo.rdf.utils.Collections.copyCollection(oSet); } case 5: return findSOC(subj, obj); case 6: return findPO(pred, obj); case 7: return findSPO(subj, pred, obj); case 8: Collection<Statement> matches = new ArrayList<Statement>(); if (namedGraphUris != null) { for (Resource namedGraphURI : namedGraphUris) { Collection<Statement> gSet = namedGraphMap.get(namedGraphURI); if (gSet != null) { matches.addAll(gSet); } } } return matches; case 9: return findSC(subj, namedGraphUris); case 10: return findPC(pred, namedGraphUris); case 11: return findPS(subj, pred, namedGraphUris); case 12: return findOC(obj, namedGraphUris); case 13: return findSOC(subj, obj, namedGraphUris); case 14: return findPO(pred, obj, namedGraphUris); case 15: matches = new HashSet<Statement>(); if (namedGraphUris != null) { for (URI namedGraphURI : namedGraphUris) { Statement stmt = new Statement(subj, pred, obj, namedGraphURI); if (statements.contains(stmt)) { matches.add(stmt); } } } return matches; default: return Collections.<Statement> emptyList(); } } } /** * Use the predicate/Subject index to find statements * * @param subj * Subject value to match * @param pred * predicate value to match * @param namedGraphUris * namedGraphURI value to match, or wildcard if null * @return Collection<Statement> of matching statements */ private Collection<Statement> findPS(Resource subj, URI pred, URI... namedGraphUris) { //Lookup predicate/subject index for predicate value provided MultiMap<Resource, Statement> psIndexMap = psIndex.get(pred); if (psIndexMap != null) { //Find subject index for subject provided Collection<Statement> map = psIndexMap.get(subj); if (map != null && map.size() > 0) { //If only 1 namedGraphURI is provided, then get index for that namedGraphURI if (namedGraphUris == null || namedGraphUris.length == 0) { return org.openanzo.rdf.utils.Collections.copyCollection(map); } else if (namedGraphUris.length == 1) { Collection<Statement> gSet = namedGraphMap.get(namedGraphUris[0]); if (gSet == null) { return Collections.<Statement> emptyList(); } Collection<Statement> matches = new ArrayList<Statement>(); //Use the smallest set of statements, the ones from the index or set from namedGraphURI index if (gSet.size() < map.size()) { for (Statement stmt : gSet) { if (stmt.getPredicate().equals(pred) && stmt.getSubject().equals(subj)) { matches.add(stmt); } } } else { for (Statement stmt : map) { if (stmt.getNamedGraphUri().equals(namedGraphUris[0])) { matches.add(stmt); } } } return matches; } else { //If more than one namedGraphURI compare the namedGraphURI of statement from p/s index to set of namedGraphUris Collection<Statement> matches = new ArrayList<Statement>(); HashSet<Resource> namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); for (Statement stmt : map) { if (namedGraphUriset.contains(stmt.getNamedGraphUri())) { matches.add(stmt); } } return matches; } } } return Collections.<Statement> emptyList(); } /** * Use the predicate/Object index to find statements * * @param pred * predicate value to match * @param obj * Object value to match * @param namedGraphUris * namedGraphURI value to match, or wildcard if null * @return Collection<Statement> of matching statements */ private Collection<Statement> findPO(URI pred, Value obj, Resource... namedGraphUris) { MultiMap<Value, Statement> poIndexMap = poIndex.get(pred); if (poIndexMap != null) { Collection<Statement> map = poIndexMap.get(obj); if (map != null && map.size() > 0) { if (namedGraphUris == null || namedGraphUris.length == 0) { return org.openanzo.rdf.utils.Collections.copyCollection(map); } else if (namedGraphUris.length == 1) { Collection<Statement> matches = new ArrayList<Statement>(); Collection<Statement> gSet = namedGraphMap.get(namedGraphUris[0]); if (gSet == null) { return Collections.<Statement> emptyList(); } if (gSet.size() < map.size()) { for (Statement stmt : gSet) { if (stmt.getPredicate().equals(pred) && stmt.getObject().equals(obj)) { matches.add(stmt); } } } else { for (Statement stmt : map) { if (stmt.getNamedGraphUri().equals(namedGraphUris[0])) { matches.add(stmt); } } } return matches; } else { Collection<Statement> matches = new ArrayList<Statement>(); HashSet<Resource> namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); for (Statement stmt : map) { if (namedGraphUriset.contains(stmt.getNamedGraphUri())) { matches.add(stmt); } } return matches; } } } return Collections.<Statement> emptyList(); } /** * Find statements that match Subject,Predicate, and Object values provided * * @param subj * Subject value to match * @param pred * predicate value to match * @param obj * Object value to match * @return Collection<Statement> of matching statements */ @SuppressWarnings("unchecked") private Collection<Statement> findSPO(Resource subj, URI pred, Value obj) { Collection<Statement> sSet = subjectMap.get(subj); if (sSet == null) { return Collections.<Statement> emptyList(); } Collection<Statement> pSet = predMap.get(pred); if (pSet == null) { return Collections.<Statement> emptyList(); } Collection<Statement> oSet = objMap.get(obj); if (oSet == null) { return Collections.<Statement> emptyList(); } Collection<Statement>[] set = new Collection[3]; set[0] = sSet; set[1] = pSet; set[2] = oSet; Arrays.sort(set, comparator); Collection<Statement> matches = new ArrayList<Statement>(); if (set[0] == sSet) { for (Statement stmt : sSet) { if (stmt.getObject().equals(obj) && stmt.getPredicate().equals(pred)) { matches.add(stmt); } } } else if (set[0] == oSet) { for (Statement stmt : oSet) { if (stmt.getSubject().equals(subj) && stmt.getPredicate().equals(pred)) { matches.add(stmt); } } } else { for (Statement stmt : pSet) { if (stmt.getSubject().equals(subj) && stmt.getObject().equals(obj)) { matches.add(stmt); } } } return matches; } /** * Find statements that match Subject and Object values provided * * @param subj * Subject value to match * @param obj * Object value to match * @param namedGraphUris * namedGraphURI value to match, or wildcard if null * @return Collection<Statement> of matching statements */ @SuppressWarnings("unchecked") private Collection<Statement> findSOC(Resource subj, Value obj, Resource... namedGraphUris) { Collection<Statement> sSet = subjectMap.get(subj); if (sSet == null || sSet.size() == 0) { return Collections.<Statement> emptyList(); } Collection<Statement> oSet = objMap.get(obj); if (oSet == null || oSet.size() == 0) { return Collections.<Statement> emptyList(); } if (namedGraphUris != null && namedGraphUris.length > 0) { if (namedGraphUris.length == 1) { Collection<Statement> gSet = namedGraphMap.get(namedGraphUris[0]); if (gSet == null || gSet.size() == 0) { return Collections.<Statement> emptyList(); } Collection<Statement>[] set = new Collection[3]; set[0] = sSet; set[1] = gSet; set[2] = oSet; Arrays.sort(set, comparator); Collection<Statement> matches = new ArrayList<Statement>(); if (set[0] == sSet) { for (Statement stmt : sSet) { if (stmt.getObject().equals(obj) && stmt.getNamedGraphUri().equals(namedGraphUris[0])) { matches.add(stmt); } } } else if (set[0] == oSet) { for (Statement stmt : oSet) { if (stmt.getSubject().equals(subj) && stmt.getNamedGraphUri().equals(namedGraphUris[0])) { matches.add(stmt); } } } else { for (Statement stmt : gSet) { if (stmt.getSubject().equals(subj) && stmt.getObject().equals(obj)) { matches.add(stmt); } } } return matches; } else { Collection<Statement> matches = new ArrayList<Statement>(); HashSet<Resource> namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); if (sSet.size() < oSet.size()) { for (Statement stmt : sSet) { if (stmt.getObject().equals(obj) && namedGraphUriset.contains(stmt.getNamedGraphUri())) { matches.add(stmt); } } } else { for (Statement stmt : oSet) { if (stmt.getSubject().equals(subj) && namedGraphUriset.contains(stmt.getNamedGraphUri())) { matches.add(stmt); } } } return matches; } } else { Collection<Statement> matches = new ArrayList<Statement>(); if (sSet.size() < oSet.size()) { for (Statement stmt : sSet) { if (stmt.getObject().equals(obj)) { matches.add(stmt); } } } else { for (Statement stmt : oSet) { if (stmt.getSubject().equals(subj)) { matches.add(stmt); } } } return matches; } } /** * Find statements that match predicate and namedGraphURI values provided * * @param pred * predicate value to match * @param namedGraphUris * namedGraphURI value to match, or wildcard if null * @return Collection<Statement> of matching statements */ private Collection<Statement> findPC(URI pred, Resource... namedGraphUris) { Collection<Statement> pSet = predMap.get(pred); if (pSet == null) { return Collections.<Statement> emptyList(); } if (namedGraphUris.length == 1) { Collection<Statement> gSet = namedGraphMap.get(namedGraphUris[0]); if (gSet == null) { return Collections.<Statement> emptyList(); } Collection<Statement> matches = new ArrayList<Statement>(); if (gSet.size() < pSet.size()) { for (Statement stmt : gSet) { if (stmt.getPredicate().equals(pred)) { matches.add(stmt); } } } else { for (Statement stmt : pSet) { if (stmt.getNamedGraphUri().equals(namedGraphUris[0])) { matches.add(stmt); } } } return matches; } else { Collection<Statement> matches = new ArrayList<Statement>(); HashSet<Resource> namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); for (Statement stmt : pSet) { if (namedGraphUriset.contains(stmt.getNamedGraphUri())) { matches.add(stmt); } } return matches; } } /** * Find statements that match Subject and namedGraphURI values provided * * @param subj * Subject value to match * @param namedGraphUris * namedGraphURI value to match, or wildcard if null * @return Collection<Statement> of matching statements */ private Collection<Statement> findSC(Resource subj, Resource... namedGraphUris) { Collection<Statement> sSet = subjectMap.get(subj); if (sSet == null) { return Collections.<Statement> emptyList(); } if (namedGraphUris.length == 1) { Collection<Statement> gSet = namedGraphMap.get(namedGraphUris[0]); if (gSet == null) { return Collections.<Statement> emptyList(); } Collection<Statement> matches = new ArrayList<Statement>(); if (gSet.size() < sSet.size()) { for (Statement stmt : gSet) { if (stmt.getSubject().equals(subj)) { matches.add(stmt); } } } else { for (Statement stmt : sSet) { if (stmt.getNamedGraphUri().equals(namedGraphUris[0])) { matches.add(stmt); } } } return matches; } else { Collection<Statement> matches = new ArrayList<Statement>(); HashSet<Resource> namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); for (Statement stmt : sSet) { if (namedGraphUriset.contains(stmt.getNamedGraphUri())) { matches.add(stmt); } } return matches; } } /** * Find statements that match Subject and namedGraphURI values provided * * @param obj * Object value to match * @param namedGraphUris * namedGraphURI value to match, or wildcard if null * @return Collection<Statement> of matching statements */ private Collection<Statement> findOC(Value obj, Resource... namedGraphUris) { Collection<Statement> oSet = objMap.get(obj); if (oSet == null) { return Collections.<Statement> emptyList(); } if (namedGraphUris.length == 1) { Collection<Statement> gSet = namedGraphMap.get(namedGraphUris[0]); if (gSet == null) { return Collections.<Statement> emptyList(); } Collection<Statement> matches = new ArrayList<Statement>(); if (gSet.size() < oSet.size()) { for (Statement stmt : gSet) { if (stmt.getObject().equals(obj)) { matches.add(stmt); } } } else { for (Statement stmt : oSet) { if (stmt.getNamedGraphUri().equals(namedGraphUris[0])) { matches.add(stmt); } } } return matches; } else { Collection<Statement> matches = new ArrayList<Statement>(); HashSet<Resource> namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); for (Statement stmt : oSet) { if (namedGraphUriset.contains(stmt.getNamedGraphUri())) { matches.add(stmt); } } return matches; } } /** * Return all statements in the store * * @return Collection<Statement> of statements in store */ public Collection<Statement> getStatements() { return new ArrayList<Statement>(statements); } /** * Tests if a statement is contained in the store. * * @param match * is the statement to be tested * @return boolean result to indicate if the statement was contained in store */ public boolean contains(Statement match) { return contains(match.getSubject(), match.getPredicate(), match.getObject(), match.getNamedGraphUri()); } /** * Tests if a statement is contained in store that match provided parameters * * @param subj * Subject value to match, or wildcard if null * @param pred * predicate value to match, or wildcard if null * @param obj * Object value to match, or wildcard if null * @param namedGraphUris * namedGraphURI value to match, or wildcard if null * @return boolean result to indicate if the statement was contained in store */ @SuppressWarnings( { "unchecked" }) public boolean contains(Resource subj, URI pred, Value obj, URI... namedGraphUris) { if ((subj == null && pred == null && obj == null && namedGraphUris == null) || statements.size() == 0) { return (statements.size() > 0); } synchronized (this.statements) { if (subj != null && pred != null && obj != null && namedGraphUris != null && namedGraphUris.length == 1) { Statement stmt = new Statement(subj, pred, obj, namedGraphUris[0]); return statements.contains(stmt); } if (subj == null && pred != null && obj != null) { MultiMap<Value, Statement> poIndexMap = poIndex.get(pred); if (poIndexMap != null) { Collection<Statement> map = poIndexMap.get(obj); if (map != null && map.size() > 0) { if (namedGraphUris != null && namedGraphUris.length > 0) { Collection<Statement> gSet = null; HashSet<Resource> namedGraphUriset = null; if (namedGraphUris.length == 1) { gSet = namedGraphMap.get(namedGraphUris[0]); } else { namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); } if (gSet != null) { Collection<Statement>[] set = new Collection[2]; set[0] = (gSet.size() < map.size()) ? gSet : map; set[1] = (gSet.size() < map.size()) ? map : gSet; for (Statement stmt : set[0]) { if (set[1].contains(stmt)) { return true; } } } else if (namedGraphUriset != null) { for (Statement stmt : map) { if (namedGraphUriset.contains(stmt.getNamedGraphUri())) { return true; } } } } else { return true; } } else { return false; } } } if (subj != null && pred != null && obj == null) { MultiMap<Resource, Statement> psIndexMap = psIndex.get(pred); if (psIndexMap != null) { Collection<Statement> map = psIndexMap.get(subj); if (map != null && map.size() > 0) { if (namedGraphUris != null && namedGraphUris.length > 0) { Collection<Statement> gSet = null; HashSet<Resource> namedGraphUriset = null; if (namedGraphUris.length == 1) { gSet = namedGraphMap.get(namedGraphUris[0]); } else { namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); } if (gSet != null) { Collection<Statement>[] set = new Collection[2]; set[0] = (gSet.size() < map.size()) ? gSet : map; set[1] = (gSet.size() < map.size()) ? map : gSet; for (Statement stmt : set[0]) { if (set[1].contains(stmt)) { return true; } } } else if (namedGraphUriset != null) { for (Statement stmt : map) { if (namedGraphUriset.contains(stmt.getNamedGraphUri())) { return true; } } } } else { return true; } } else { return false; } } } Collection<Statement> sSet = (subj != null) ? subjectMap.get(subj) : statements; Collection<Statement> pSet = (pred != null) ? predMap.get(pred) : statements; Collection<Statement> oSet = (obj != null) ? objMap.get(obj) : statements; Collection<Statement> gSet = null; if (namedGraphUris != null) { if (namedGraphUris.length == 1) { gSet = namedGraphMap.get(namedGraphUris[0]); if (gSet == null) { return false; } } } else { gSet = statements; } if (sSet != null && pSet != null && oSet != null && gSet != null) { Collection<Statement>[] set = new Collection[4]; set[0] = sSet; set[1] = pSet; set[2] = oSet; set[3] = gSet; Arrays.sort(set, comparator); if (set[0].size() == statements.size()) { return true; } else { for (Statement stmt : set[0]) { if ((set[1] == statements || set[1].contains(stmt)) && (set[2] == statements || set[2].contains(stmt)) && (set[3] == statements || set[3].contains(stmt))) { return true; } } } } else if (sSet != null && pSet != null && oSet != null && gSet == null) { if (namedGraphUris != null) { HashSet<Resource> namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); Collection<Statement>[] set = new Collection[3]; set[0] = sSet; set[1] = pSet; set[2] = oSet; Arrays.sort(set, comparator); if (set[0].size() == statements.size()) { return true; } else { for (Statement stmt : set[0]) { if ((set[1] == statements || set[1].contains(stmt)) && (set[2] == statements || set[2].contains(stmt)) && namedGraphUriset.contains(stmt.getNamedGraphUri())) { return true; } } } } } } return false; } /** * Tests if a statement is contained in store that match provided parameters * * @param subj * Subject value to match, or wildcard if null * @param pred * predicate value to match, or wildcard if null * @param obj * Object value to match, or wildcard if null * @param namedGraphUris * namedGraphURI value to match, or wildcard if null * @return boolean result to indicate if the statement was contained in store */ @SuppressWarnings( { "unchecked" }) public long count(Resource subj, URI pred, Value obj, URI... namedGraphUris) { if ((subj == null && pred == null && obj == null && namedGraphUris == null) || statements.size() == 0) { return statements.size(); } synchronized (this.statements) { if (subj != null && pred != null && obj != null && namedGraphUris != null && namedGraphUris.length == 1) { Statement stmt = new Statement(subj, pred, obj, namedGraphUris[0]); return statements.contains(stmt) ? 1 : 0; } long count = 0; if (subj == null && pred != null && obj != null) { MultiMap<Value, Statement> poIndexMap = poIndex.get(pred); if (poIndexMap != null) { Collection<Statement> map = poIndexMap.get(obj); if (map != null && map.size() > 0) { if (namedGraphUris != null && namedGraphUris.length > 0) { Collection<Statement> gSet = null; HashSet<Resource> namedGraphUriset = null; if (namedGraphUris.length == 1) { gSet = namedGraphMap.get(namedGraphUris[0]); } else { namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); } if (gSet != null) { Collection<Statement>[] set = new Collection[2]; set[0] = (gSet.size() < map.size()) ? gSet : map; set[1] = (gSet.size() < map.size()) ? map : gSet; for (Statement stmt : set[0]) { if (set[1].contains(stmt)) { count++; } } } else if (namedGraphUriset != null) { for (Statement stmt : map) { if (namedGraphUriset.contains(stmt.getNamedGraphUri())) { count++; } } } } else { return map.size(); } } else { return 0; } } } if (subj != null && pred != null && obj == null) { MultiMap<Resource, Statement> psIndexMap = psIndex.get(pred); if (psIndexMap != null) { Collection<Statement> map = psIndexMap.get(subj); if (map != null && map.size() > 0) { if (namedGraphUris != null && namedGraphUris.length > 0) { Collection<Statement> gSet = null; HashSet<Resource> namedGraphUriset = null; if (namedGraphUris.length == 1) { gSet = namedGraphMap.get(namedGraphUris[0]); } else { namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); } if (gSet != null) { Collection<Statement>[] set = new Collection[2]; set[0] = (gSet.size() < map.size()) ? gSet : map; set[1] = (gSet.size() < map.size()) ? map : gSet; for (Statement stmt : set[0]) { if (set[1].contains(stmt)) { return count++; } } } else if (namedGraphUriset != null) { for (Statement stmt : map) { if (namedGraphUriset.contains(stmt.getNamedGraphUri())) { return count++; } } } } else { return map.size(); } } else { return 0; } } } Collection<Statement> sSet = (subj != null) ? subjectMap.get(subj) : statements; Collection<Statement> pSet = (pred != null) ? predMap.get(pred) : statements; Collection<Statement> oSet = (obj != null) ? objMap.get(obj) : statements; Collection<Statement> gSet = null; if (namedGraphUris != null) { if (namedGraphUris.length == 1) { gSet = namedGraphMap.get(namedGraphUris[0]); if (gSet == null) { return 0; } } } else { gSet = statements; } if (sSet != null && pSet != null && oSet != null && gSet != null) { Collection<Statement>[] set = new Collection[4]; set[0] = sSet; set[1] = pSet; set[2] = oSet; set[3] = gSet; Arrays.sort(set, comparator); if (set[0].size() == statements.size()) { return statements.size(); } else { for (Statement stmt : set[0]) { if ((set[1] == statements || set[1].contains(stmt)) && (set[2] == statements || set[2].contains(stmt)) && (set[3] == statements || set[3].contains(stmt))) { return count++; } } } } else if (sSet != null && pSet != null && oSet != null && gSet == null) { if (namedGraphUris != null) { HashSet<Resource> namedGraphUriset = new HashSet<Resource>(namedGraphUris.length); Collections.addAll(namedGraphUriset, namedGraphUris); Collection<Statement>[] set = new Collection[3]; set[0] = sSet; set[1] = pSet; set[2] = oSet; Arrays.sort(set, comparator); if (set[0].size() == statements.size()) { return statements.size(); } else { for (Statement stmt : set[0]) { if ((set[1] == statements || set[1].contains(stmt)) && (set[2] == statements || set[2].contains(stmt)) && namedGraphUriset.contains(stmt.getNamedGraphUri())) { return count++; } } } } } return count; } } /** * Simple comparator to sort arrays by size */ private final static StmtSetComp comparator = new StmtSetComp(); static private class StmtSetComp implements Comparator<Collection<?>> { public int compare(Collection<?> o1, Collection<?> o2) { int result = 0; if (o1.size() == o2.size()) { return result; } return (o1.size() < o2.size()) ? -1 : 1; } } /** * Clear statements and indexes from memory */ public void clear() { synchronized (this.statements) { statements.clear(); subjectMap.clear(); predMap.clear(); objMap.clear(); namedGraphMap.clear(); poIndex.clear(); psIndex.clear(); } } /** * Return the number of statements in the store * * @return the number of statements in the store */ public int size() { return statements.size(); } /** * Return if store is empty * * @return if store is empty */ public boolean isEmpty() { return statements.isEmpty(); } /* Return the number of statements in the store for given namedGraphUris * @param namedGraphUris to determine size of in container * @return the number of statements in the store for given namedGraphUris */ public int size(URI... namedGraphUris) { int size = 0; for (Resource namedGraphURI : namedGraphUris) { Collection<Statement> stmts = namedGraphMap.get(namedGraphURI); if (stmts != null) { size += stmts.size(); } } return size; } /** * Return the set of namedGraphUris contained within store * * @return collection of namedGraphUris contained within store */ public Collection<URI> getNamedGraphUris() { return new HashSet<URI>(namedGraphMap.keySet()); } public QueryResults executeQuery(Set<URI> defaultNamedGraphsIn, Set<URI> namedGraphsIn, Set<URI> namedDatasets, String query, URI baseUri) throws AnzoException { try { HashSet<URI> defaultNamedGraphs = new HashSet<URI>(defaultNamedGraphsIn); HashSet<URI> namedGraphs = new HashSet<URI>(namedGraphsIn); if (namedDatasets != null) { for (URI uri : namedDatasets) { for (Statement s : find(uri, Anzo.DEFAULTGRAPH, null, uri)) { defaultNamedGraphs.add((URI) s.getObject()); } for (Statement s : find(uri, Anzo.NAMEDGRAPH, null, uri)) { namedGraphs.add((URI) s.getObject()); } } } // copy these since we then modify them UriGenerator.handleSpecialGraphUris(defaultNamedGraphs, this); UriGenerator.handleSpecialGraphUris(namedGraphs, this); return glitter.executeQuery(null, query, new DefaultQueryDataset(defaultNamedGraphs, namedGraphs), baseUri); } catch (ParseException e) { log.error(LogUtils.GLITTER_MARKER, "Error parsing query:" + query, e); throw new AnzoException(ExceptionConstants.CLIENT.ERROR_PARSING_QUERY, e, query); } } }