001: /*
002: (c) Copyright 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: All rights reserved - see end of file.
004: $Id: NodeToTriplesMapFaster.java,v 1.29 2008/01/03 15:41:09 chris-dollin Exp $
005: */
006:
007: package com.hp.hpl.jena.mem.faster;
008:
009: import java.util.*;
010:
011: import com.hp.hpl.jena.graph.*;
012: import com.hp.hpl.jena.graph.Triple.Field;
013: import com.hp.hpl.jena.graph.query.*;
014: import com.hp.hpl.jena.mem.*;
015: import com.hp.hpl.jena.shared.JenaException;
016: import com.hp.hpl.jena.util.iterator.*;
017:
018: public class NodeToTriplesMapFaster extends NodeToTriplesMapBase {
019: public NodeToTriplesMapFaster(Field indexField, Field f2, Field f3) {
020: super (indexField, f2, f3);
021: }
022:
023: /**
024: Add <code>t</code> to this NTM; the node <code>o</code> <i>must</i>
025: be the index node of the triple. Answer <code>true</code> iff the triple
026: was not previously in the set, ie, it really truly has been added.
027: */
028: public boolean add(Triple t) {
029: Object o = getIndexField(t);
030: TripleBunch s = (TripleBunch) bunchMap.get(o);
031: if (s == null)
032: bunchMap.put(o, s = new ArrayBunch());
033: if (s.contains(t))
034: return false;
035: else {
036: if (s.size() == 9 && s instanceof ArrayBunch)
037: bunchMap.put(o, s = new HashedTripleBunch(s));
038: s.add(t);
039: size += 1;
040: return true;
041: }
042: }
043:
044: /**
045: Remove <code>t</code> from this NTM. Answer <code>true</code> iff the
046: triple was previously in the set, ie, it really truly has been removed.
047: */
048: public boolean remove(Triple t) {
049: Object o = getIndexField(t);
050: TripleBunch s = bunchMap.get(o);
051: if (s == null || !s.contains(t))
052: return false;
053: else {
054: s.remove(t);
055: size -= 1;
056: if (s.size() == 0)
057: bunchMap.remove(o);
058: return true;
059: }
060: }
061:
062: /**
063: Answer an iterator over all the triples in this NTM which have index node
064: <code>o</code>.
065: */
066: public Iterator iterator(Object o, HashCommon.NotifyEmpty container) {
067: // System.err.println( ">> BOINK" ); // if (true) throw new JenaException( "BOINK" );
068: TripleBunch s = (TripleBunch) bunchMap.get(o);
069: return s == null ? NullIterator.instance : s
070: .iterator(container);
071: }
072:
073: public class NotifyMe implements HashCommon.NotifyEmpty {
074: protected final Object key;
075:
076: public NotifyMe(Object key) {
077: this .key = key;
078: }
079:
080: // TODO fix the way this interacts (badly) with iteration and CMEs.
081: public void emptied() {
082: if (false)
083: throw new JenaException("BOOM"); /* System.err.println( ">> OOPS" ); */
084: bunchMap.remove(key);
085: }
086: }
087:
088: /**
089: Answer true iff this NTM contains the concrete triple <code>t</code>.
090: */
091: public boolean contains(Triple t) {
092: TripleBunch s = (TripleBunch) bunchMap.get(getIndexField(t));
093: return s == null ? false : s.contains(t);
094: }
095:
096: public boolean containsBySameValueAs(Triple t) {
097: TripleBunch s = (TripleBunch) bunchMap.get(getIndexField(t));
098: return s == null ? false : s.containsBySameValueAs(t);
099: }
100:
101: /**
102: Answer an iterator over all the triples in this NTM which match
103: <code>pattern</code>. The index field of this NTM is guaranteed
104: concrete in the pattern.
105: */
106: public ExtendedIterator iterator(Node index, Node n2, Node n3) {
107: Object indexValue = index.getIndexingValue();
108: TripleBunch s = (TripleBunch) bunchMap.get(indexValue);
109: // System.err.println( ">> ntmf::iterator: " + (s == null ? (Object) "None" : s.getClass()) );
110: return s == null ? NullIterator.instance : f2.filterOn(n2).and(
111: f3.filterOn(n3)).filterKeep(
112: s.iterator(new NotifyMe(indexValue)));
113: }
114:
115: public Applyer createFixedOApplyer(final ProcessedTriple Q) {
116: final TripleBunch ss = (TripleBunch) bunchMap.get(Q.O.node
117: .getIndexingValue());
118: if (ss == null)
119: return Applyer.empty;
120: else {
121: return new Applyer() {
122: final MatchOrBind x = MatchOrBind.createSP(Q);
123:
124: public void applyToTriples(Domain d, Matcher m,
125: StageElement next) {
126: ss.app(d, next, x.reset(d));
127: }
128: };
129: }
130: }
131:
132: public Applyer createBoundOApplyer(final ProcessedTriple pt) {
133: return new Applyer() {
134: final MatchOrBind x = MatchOrBind.createSP(pt);
135:
136: public void applyToTriples(Domain d, Matcher m,
137: StageElement next) {
138: TripleBunch c = (TripleBunch) bunchMap.get(pt.O.finder(
139: d).getIndexingValue());
140: if (c != null)
141: c.app(d, next, x.reset(d));
142: }
143: };
144: }
145:
146: public Applyer createBoundSApplyer(final ProcessedTriple pt) {
147: return new Applyer() {
148: final MatchOrBind x = MatchOrBind.createPO(pt);
149:
150: public void applyToTriples(Domain d, Matcher m,
151: StageElement next) {
152: TripleBunch c = (TripleBunch) bunchMap.get(pt.S
153: .finder(d));
154: if (c != null)
155: c.app(d, next, x.reset(d));
156: }
157: };
158: }
159:
160: public Applyer createFixedSApplyer(final ProcessedTriple Q) {
161: final TripleBunch ss = (TripleBunch) bunchMap.get(Q.S.node);
162: if (ss == null)
163: return Applyer.empty;
164: else {
165: return new Applyer() {
166: final MatchOrBind x = MatchOrBind.createPO(Q);
167:
168: public void applyToTriples(Domain d, Matcher m,
169: StageElement next) {
170: ss.app(d, next, x.reset(d));
171: }
172: };
173: }
174: }
175:
176: protected TripleBunch get(Object index) {
177: return (TripleBunch) bunchMap.get(index);
178: }
179:
180: /**
181: Answer an iterator over all the triples that are indexed by the item <code>y</code>.
182: Note that <code>y</code> need not be a Node (because of indexing values).
183: */
184: public Iterator iteratorForIndexed(Object y) {
185: return get(y).iterator();
186: }
187: }
188:
189: /*
190: * (c) Copyright 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
191: * All rights reserved.
192: *
193: * Redistribution and use in source and binary forms, with or without
194: * modification, are permitted provided that the following conditions
195: * are met:
196: * 1. Redistributions of source code must retain the above copyright
197: * notice, this list of conditions and the following disclaimer.
198: * 2. Redistributions in binary form must reproduce the above copyright
199: * notice, this list of conditions and the following disclaimer in the
200: * documentation and/or other materials provided with the distribution.
201: * 3. The name of the author may not be used to endorse or promote products
202: * derived from this software without specific prior written permission.
203: *
204: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
205: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
206: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
207: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
208: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
209: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
210: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
211: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
212: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
213: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
214: */
|