All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.bop.fed.ThickChunkMessage Maven / Gradle / Ivy

/**

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
/*
 * Created on Sep 9, 2010
 */

package com.bigdata.bop.fed;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.rmi.RemoteException;
import java.util.UUID;

import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.engine.IChunkAccessor;
import com.bigdata.bop.engine.IChunkMessage;
import com.bigdata.bop.engine.IQueryClient;
import com.bigdata.io.DataInputBuffer;
import com.bigdata.io.DataOutputBuffer;
import com.bigdata.io.LongPacker;
import com.bigdata.io.ShortPacker;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.IVCache;
import com.bigdata.rdf.internal.encoder.IVSolutionSetDecoder;
import com.bigdata.rdf.internal.encoder.IVSolutionSetEncoder;
import com.bigdata.relation.accesspath.EmptyCloseableIterator;
import com.bigdata.relation.accesspath.ThickCloseableIterator;

import cutthecrap.utils.striterators.ICloseableIterator;

/**
 * A thick version of this interface in which the chunk is sent inline with the
 * RMI message.
 * 

* Note: The encoding is {@link IV} specific and supports the {@link IVCache} * associations. However, it CAN NOT be used with non-{@link IV} data. This is * fine in the deployed system but it makes the class properly dependent on the * RDF layer. * * @author Bryan Thompson * @version $Id$ */ public class ThickChunkMessage implements IChunkMessage, Externalizable { /** * */ private static final long serialVersionUID = 1L; private IQueryClient queryController; private UUID queryControllerId; private UUID queryId; private int bopId; private int partitionId; private int solutionCount; private byte[] data; @Override public IQueryClient getQueryController() { return queryController; } @Override public UUID getQueryControllerId() { return queryControllerId; } @Override public UUID getQueryId() { return queryId; } @Override public int getBOpId() { return bopId; } @Override public int getPartitionId() { return partitionId; } @Override public boolean isLastInvocation() { return false; // Never. } @Override public boolean isMaterialized() { return true; } @Override public int getSolutionCount() { return solutionCount; } public int getBytesAvailable() { return data.length; } @Override public String toString() { return getClass().getName() + "{queryId=" + queryId + ",bopId=" + bopId + ",partitionId=" + partitionId + ",controller=" + queryController + ", solutionCount=" + solutionCount + ", bytesAvailable=" + data.length + "}"; } /** * De-serialization constructor. */ public ThickChunkMessage() { } public ThickChunkMessage(final IQueryClient queryController, final UUID queryId, final int bopId, final int partitionId, final IBindingSet[] source) { if (queryController == null) throw new IllegalArgumentException(); if (queryId == null) throw new IllegalArgumentException(); if (source == null) throw new IllegalArgumentException(); // do not send empty chunks if (source.length == 0) throw new IllegalArgumentException(); this.queryController = queryController; try { this.queryControllerId = queryController.getServiceUUID(); } catch (RemoteException e) { throw new RuntimeException(e); } this.queryId = queryId; this.bopId = bopId; this.partitionId = partitionId; this.solutionCount = source.length; if (solutionCount == 0) { this.data = null; } else { /* * Encode the solutions. */ // SWAG. final int initialCapacity = solutionCount * 24; final DataOutputBuffer out = new DataOutputBuffer(initialCapacity); final IVSolutionSetEncoder encoder = new IVSolutionSetEncoder(); for (int i = 0; i < source.length; i++) { encoder.encodeSolution(out, source[i]); } this.data = out.toByteArray(); } } @Override public void materialize(final FederatedRunningQuery runningQuery) { // NOP } @Override public void release() { if (chunkAccessor != null) chunkAccessor.close(); } private transient volatile ChunkAccessor chunkAccessor = null; @Override public IChunkAccessor getChunkAccessor() { return new ChunkAccessor(); } /** * Deserialization of the binding sets. *

* Note: Both very small chunks (1-5 solutions) and large chunks (100-1000+) * are common on a cluster. The observed chunk size is a function of the * selectivity of the access path together with the chunk capacity (e.g., as * set by a query hint). * * @see HTree * performance tuning */ private class ChunkAccessor implements IChunkAccessor { private final ICloseableIterator source; @SuppressWarnings("unchecked") public ChunkAccessor() { if (solutionCount == 0) { source = new EmptyCloseableIterator(); return; } final IVSolutionSetDecoder decoder = new IVSolutionSetDecoder(); final IBindingSet[] a = new IBindingSet[solutionCount]; // Note: close() is NOT required for DataInputBuffer. final DataInputBuffer in = new DataInputBuffer(data, 0/* off */, data.length); for (int i = 0; i < solutionCount; i++) { a[i] = decoder .decodeSolution(in, true/* resolveCachedValues */); } source = new ThickCloseableIterator( ((E[][]) new IBindingSet[][] { a })); } public ICloseableIterator iterator() { return source; } public void close() { source.close(); } } @Override public void writeExternal(final ObjectOutput out) throws IOException { ShortPacker.packShort(out, currentVersion); out.writeObject(queryController); out.writeLong(queryControllerId.getMostSignificantBits()); out.writeLong(queryControllerId.getLeastSignificantBits()); out.writeLong(queryId.getMostSignificantBits()); out.writeLong(queryId.getLeastSignificantBits()); out.writeInt(bopId); out.writeInt(partitionId);// Note: 32-bit clean. LongPacker.packLong(out, solutionCount); // non-negative if (solutionCount > 0) { LongPacker.packLong(out, data.length); out.write(data); } } @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { final short version = ShortPacker.unpackShort(in); if (version != VERSION0) { throw new IOException("Unknown version: " + version); } queryController = (IQueryClient) in.readObject(); queryControllerId = new UUID(in.readLong()/* MSB */, in.readLong()/* LSB */); queryId = new UUID(in.readLong()/* MSB */, in.readLong()/* LSB */); bopId = in.readInt(); partitionId = in.readInt(); solutionCount = LongPacker.unpackInt(in); if (solutionCount > 0) { final int len = LongPacker.unpackInt(in); data = new byte[len]; in.readFully(data); } } /** * The original version. */ private static final transient short VERSION0 = 0x0; private static final transient short currentVersion = VERSION0; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy