package com.bigdata.rdf.spo; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.Arrays; import java.util.HashSet; import org.openrdf.model.URI; import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.model.BigdataURI; /** * "IN" filter for the context position based on a sorted long[] of the * acceptable graph identifiers. While evaluation of the access path will be * ordered, the filter does not maintain evolving state so a hash set will * likely beat a binary search. * * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan * Thompson</a> * @version $Id$ * * @see InGraphHashSetFilter */ @SuppressWarnings("rawtypes") public final class InGraphBinarySearchFilter<E extends ISPO> extends SPOFilter<E> implements Externalizable { /** * */ private static final long serialVersionUID = -3566012247356882422L; /** * Note: Not final since the class implements {@link Externalizable}. */ private IV[] a; /** * Deserialization constructor. */ public InGraphBinarySearchFilter() { } /** * * @param graphs * The set of acceptable graph identifiers. */ public InGraphBinarySearchFilter(final Iterable<? extends URI> graphs) { /* * Create a sorted array of term identifiers for the set of contexts * we will accept. */ final HashSet<IV> contextSet = new HashSet<IV>(); for (URI uri : graphs) { final IV termId = ((BigdataURI) uri).getIV(); if (termId != null) { contextSet.add(termId); } } a = contextSet.toArray(new IV[0]); Arrays.sort(a); } @Override public boolean isValid(final Object o) { if (!canAccept(o)) { return true; } return accept((ISPO) o); } private boolean accept(final ISPO o) { final ISPO spo = (ISPO) o; return Arrays.binarySearch(a, spo.c()) >= 0; } @Override public String toString() { return getClass().getName() + "{size=" + a.length + "}"; } /** * The initial version. */ private static final transient short VERSION0 = 0; /** * The current version. */ private static final transient short VERSION = VERSION0; @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { final short version = in.readShort(); switch (version) { case VERSION0: break; default: throw new UnsupportedOperationException("Unknown version: " + version); } final int size = in.readInt(); a = new IV[size]; for(int i=0; i<size; i++) { a[i] = (IV) in.readObject(); } } @Override public void writeExternal(final ObjectOutput out) throws IOException { out.writeShort(VERSION); out.writeInt(a.length); for(IV iv : a) { out.writeObject(iv); } } }