001: /*
002: (c) Copyright 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: All rights reserved - see end of file.
004: $Id: GraphMemFaster.java,v 1.20 2008/01/02 12:09:58 andy_seaborne Exp $
005: */
006:
007: package com.hp.hpl.jena.mem.faster;
008:
009: import java.util.Iterator;
010:
011: import com.hp.hpl.jena.graph.*;
012: import com.hp.hpl.jena.graph.Reifier.Util;
013: import com.hp.hpl.jena.graph.impl.*;
014: import com.hp.hpl.jena.graph.query.*;
015: import com.hp.hpl.jena.mem.*;
016: import com.hp.hpl.jena.shared.ReificationStyle;
017: import com.hp.hpl.jena.util.iterator.ExtendedIterator;
018:
019: public class GraphMemFaster extends GraphMemBase {
020: public GraphMemFaster() {
021: this (ReificationStyle.Minimal);
022: }
023:
024: public GraphMemFaster(ReificationStyle style) {
025: super (style);
026: }
027:
028: protected TripleStore createTripleStore() {
029: return new FasterTripleStore(this );
030: }
031:
032: protected void destroy() {
033: store.close();
034: }
035:
036: public void performAdd(Triple t) {
037: if (!getReifier().handledAdd(t))
038: store.add(t);
039: }
040:
041: public void performDelete(Triple t) {
042: if (!getReifier().handledRemove(t))
043: store.delete(t);
044: }
045:
046: public int graphBaseSize() {
047: return store.size();
048: }
049:
050: public QueryHandler queryHandler() {
051: if (queryHandler == null)
052: queryHandler = new GraphMemFasterQueryHandler(this );
053: return queryHandler;
054: }
055:
056: protected GraphStatisticsHandler createStatisticsHandler() {
057: return new GraphMemFasterStatisticsHandler(
058: (FasterTripleStore) store, getReifier());
059: }
060:
061: /**
062: The GraphMemFasterStatisticsHandler exploits the existing FasterTripleStore
063: indexes to deliver statistics information for single-concrete-node queries
064: and for trivial cases of two-concrete-node queries.
065:
066: @author kers
067: */
068: protected static class GraphMemFasterStatisticsHandler implements
069: GraphStatisticsHandler {
070: protected final FasterTripleStore store;
071: protected final Reifier reifier;
072:
073: public GraphMemFasterStatisticsHandler(FasterTripleStore store,
074: Reifier reifier) {
075: this .store = store;
076: this .reifier = reifier;
077: }
078:
079: private static class C {
080: static final int NONE = 0;
081: static final int S = 1, P = 2, O = 4;
082: static final int SP = S + P, SO = S + O, PO = P + O;
083: static final int SPO = S + P + O;
084: }
085:
086: /**
087: Answer a good estimate of the number of triples matching (S, P, O)
088: if cheaply possible.
089:
090: <p>If there are any reifier triples, return -1. (We may be able to
091: improve this later.)
092:
093: <p>If only one of S, P, O is concrete, answers the number of triples
094: with that value in that field.
095:
096: <p>If two of S, P, P are concrete and at least one of them has no
097: corresponding triples, answers 0.
098:
099: <p>Otherwise answers -1, ie, no information available. (May change;
100: the two degenerate cases might deserve an answer.)
101:
102: @see com.hp.hpl.jena.graph.GraphStatisticsHandler#getStatistic(com.hp.hpl.jena.graph.Node, com.hp.hpl.jena.graph.Node, com.hp.hpl.jena.graph.Node)
103: */
104: public long getStatistic(Node S, Node P, Node O) {
105: if (reifier.size() > 0)
106: return -1;
107: int concrete = (S.isConcrete() ? C.S : 0)
108: + (P.isConcrete() ? C.P : 0)
109: + (O.isConcrete() ? C.O : 0);
110: switch (concrete) {
111: case C.NONE:
112: return store.size();
113:
114: case C.S:
115: return countInMap(S, store.getSubjects());
116:
117: case C.SP:
118: return countsInMap(S, store.getSubjects(), P, store
119: .getPredicates());
120:
121: case C.SO:
122: return countsInMap(S, store.getSubjects(), O, store
123: .getObjects());
124:
125: case C.P:
126: return countInMap(P, store.getPredicates());
127:
128: case C.PO:
129: return countsInMap(P, store.getPredicates(), O, store
130: .getObjects());
131:
132: case C.O:
133: return countInMap(O, store.getObjects());
134:
135: case C.SPO:
136: return store.contains(Triple.create(S, P, O)) ? 1 : 0;
137: }
138: return -1;
139: }
140:
141: public long countsInMap(Node a, NodeToTriplesMapFaster mapA,
142: Node b, NodeToTriplesMapFaster mapB) {
143: long countA = countInMap(a, mapA), countB = countInMap(b,
144: mapB);
145: return countA == 0 || countB == 0 ? 0 : -1L;
146: }
147:
148: public long countInMap(Node n, NodeToTriplesMapFaster map) {
149: TripleBunch b = map.get(n.getIndexingValue());
150: return b == null ? 0 : b.size();
151: }
152: }
153:
154: /**
155: Answer an ExtendedIterator over all the triples in this graph that match the
156: triple-pattern <code>m</code>. Delegated to the store.
157: */
158: public ExtendedIterator graphBaseFind(TripleMatch m) {
159: return store.find(m.asTriple());
160: }
161:
162: public Applyer createApplyer(ProcessedTriple pt) {
163: Applyer plain = ((FasterTripleStore) store).createApplyer(pt);
164: return matchesReification(pt) && hasReifications() ? withReification(
165: plain, pt)
166: : plain;
167: }
168:
169: protected boolean hasReifications() {
170: return reifier != null && reifier.size() > 0;
171: }
172:
173: public static boolean matchesReification(QueryTriple pt) {
174: return pt.P.node.isVariable()
175: || Util.isReificationPredicate(pt.P.node)
176: || Util.isReificationType(pt.P.node, pt.O.node);
177: }
178:
179: protected Applyer withReification(final Applyer plain,
180: final QueryTriple pt) {
181: return new Applyer() {
182: public void applyToTriples(Domain d, Matcher m,
183: StageElement next) {
184: plain.applyToTriples(d, m, next);
185: Triple tm = new Triple(pt.S.finder(d), pt.P.finder(d),
186: pt.O.finder(d));
187: Iterator it = reifier.findExposed(tm);
188: while (it.hasNext())
189: if (m.match(d, (Triple) it.next()))
190: next.run(d);
191: }
192: };
193: }
194:
195: /**
196: Answer true iff this graph contains <code>t</code>. If <code>t</code>
197: happens to be concrete, then we hand responsibility over to the store.
198: Otherwise we use the default implementation.
199: */
200: public boolean graphBaseContains(Triple t) {
201: return t.isConcrete() ? store.contains(t) : super
202: .graphBaseContains(t);
203: }
204:
205: /**
206: Clear this GraphMem, ie remove all its triples (delegated to the store).
207: */
208: public void clear() {
209: store.clear();
210: ((SimpleReifier) getReifier()).clear();
211: }
212: }
213:
214: /*
215: * (c) Copyright 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
216: * All rights reserved.
217: *
218: * Redistribution and use in source and binary forms, with or without
219: * modification, are permitted provided that the following conditions
220: * are met:
221: * 1. Redistributions of source code must retain the above copyright
222: * notice, this list of conditions and the following disclaimer.
223: * 2. Redistributions in binary form must reproduce the above copyright
224: * notice, this list of conditions and the following disclaimer in the
225: * documentation and/or other materials provided with the distribution.
226: * 3. The name of the author may not be used to endorse or promote products
227: * derived from this software without specific prior written permission.
228: *
229: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
230: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
231: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
232: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
233: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
234: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
237: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
238: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
239: */
|