|
From: Bryan T. <tho...@us...> - 2007-04-20 17:24:28
|
Update of /cvsroot/cweb/bigdata/src/java/com/bigdata/service In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv1508/src/java/com/bigdata/service Modified Files: IDataService.java DataService.java DataServiceClient.java EmbeddedDataService.java Added Files: ResultSet.java Log Message: Implemented Externalizable for ResultSet and moved it to a top-level class. Index: IDataService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/IDataService.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** IDataService.java 20 Apr 2007 16:36:27 -0000 1.8 --- IDataService.java 20 Apr 2007 17:24:23 -0000 1.9 *************** *** 52,56 **** import com.bigdata.journal.ITransactionManager; import com.bigdata.journal.ITxCommitProtocol; - import com.bigdata.service.DataService.ResultSet; /** --- 52,55 ---- Index: EmbeddedDataService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/EmbeddedDataService.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** EmbeddedDataService.java 20 Apr 2007 16:36:27 -0000 1.5 --- EmbeddedDataService.java 20 Apr 2007 17:24:24 -0000 1.6 *************** *** 56,60 **** import com.bigdata.btree.IBatchOp; import com.bigdata.journal.ValidationError; - import com.bigdata.service.DataService.ResultSet; import com.bigdata.util.concurrent.DaemonThreadFactory; --- 56,59 ---- Index: DataServiceClient.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/DataServiceClient.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** DataServiceClient.java 20 Apr 2007 16:36:27 -0000 1.6 --- DataServiceClient.java 20 Apr 2007 17:24:24 -0000 1.7 *************** *** 54,58 **** import com.bigdata.btree.IBatchOp; import com.bigdata.journal.ValidationError; - import com.bigdata.service.DataService.ResultSet; /** --- 54,57 ---- Index: DataService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/DataService.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** DataService.java 20 Apr 2007 16:36:27 -0000 1.8 --- DataService.java 20 Apr 2007 17:24:23 -0000 1.9 *************** *** 48,54 **** package com.bigdata.service; - import java.io.Externalizable; import java.io.IOException; - import java.io.ObjectOutputStream; import java.io.Serializable; import java.net.InetSocketAddress; --- 48,52 ---- *************** *** 65,72 **** import com.bigdata.btree.BatchLookup; import com.bigdata.btree.BatchRemove; - import com.bigdata.btree.BytesUtil; import com.bigdata.btree.IBatchBTree; import com.bigdata.btree.IBatchOp; - import com.bigdata.btree.IEntryIterator; import com.bigdata.btree.IIndex; import com.bigdata.btree.ILinearList; --- 63,68 ---- *************** *** 1033,1157 **** /** - * - * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ - * - * @todo implement {@link Externalizable}, probably buffer the - * {@link ObjectOutputStream} and focus on byte[] transfers. - */ - public static class ResultSet implements Serializable { - - /** - * Total #of key-value pairs within the key range (approximate). - */ - public final int rangeCount; - - /** - * Actual #of key-value pairs in the {@link ResultSet} - */ - public final int ntuples; - - /** - * True iff the iterator exhausted the available keys such that no more - * results would be available if you formed the successor of the - * {@link #lastKey}. - */ - final public boolean exhausted; - - /** - * The last key visited by the iterator <em>regardless</em> of the - * filter imposed -or- <code>null</code> iff no keys were visited by - * the iterator for the specified key range. - * - * @see #nextKey() - */ - public final byte[] lastKey; - - /** - * The next key that should be used to retrieve keys and/or values - * starting from the first possible successor of the {@link #lastKey} - * visited by the iterator in this operation (the successor is formed by - * appending a <code>nul</code> byte to the {@link #lastKey}). - * - * @return The successor of {@link #lastKey} -or- <code>null</code> - * iff the iterator exhausted the available keys. - * - * @exception UnsupportedOperationException - * if the {@link #lastKey} is <code>null</code>. - */ - public byte[] nextKey() { - - if (lastKey == null) - throw new UnsupportedOperationException(); - - return BytesUtil.successor(lastKey); - - } - - /** - * The visited keys iff the {@link RangeQueryEnum#Keys} flag was set. - */ - public final byte[][] keys; - - /** - * The visited values iff the {@link RangeQueryEnum#Values} flag was - * set. - */ - public final byte[][] vals; - - public ResultSet(final IIndex ndx, final byte[] fromKey, - final byte[] toKey, final int capacity, final boolean sendKeys, - final boolean sendVals) { - - // The upper bound on the #of key-value pairs in the range. - rangeCount = ndx.rangeCount(fromKey, toKey); - - final int limit = (rangeCount > capacity ? capacity : rangeCount); - - int ntuples = 0; - - keys = (sendKeys ? new byte[limit][] : null); - - vals = (sendVals ? new byte[limit][] : null); - - // iterator that will visit the key range. - IEntryIterator itr = ndx.rangeIterator(fromKey, toKey); - - /* - * true if any keys were visited regardless of whether or not they - * satisified the optional filter. This is used to make sure that we - * always return the lastKey visited if any keys were visited and - * otherwise set lastKey := null. - */ - boolean anything = false; - - while (ntuples < limit && itr.hasNext()) { - - anything = true; - - byte[] val = (byte[]) itr.next(); - - if (sendVals) - vals[ntuples] = val; - - if (sendKeys) - keys[ntuples] = itr.getKey(); - - // #of results that will be returned. - ntuples++; - - } - - this.ntuples = ntuples; - - this.lastKey = (anything ? itr.getKey() : null); - - this.exhausted = ! itr.hasNext(); - - } - - } - - /** * Abstract class for tasks that execute {@link IProcedure} operations. * There are various concrete subclasses, each of which MUST be submitted to --- 1029,1032 ---- --- NEW FILE: ResultSet.java --- package com.bigdata.service; import java.io.DataOutput; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import org.CognitiveWeb.extser.LongPacker; import org.CognitiveWeb.extser.ShortPacker; import com.bigdata.btree.BytesUtil; import com.bigdata.btree.IEntryIterator; import com.bigdata.btree.IIndex; /** * An object used to stream key scan results back to the client. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public class ResultSet implements Externalizable { /** * */ private static final long serialVersionUID = 8823205844134046434L; private int rangeCount; private int ntuples; private boolean exhausted; private byte[] lastKey; private byte[][] keys; private byte[][] vals; /** * Total #of key-value pairs within the key range (approximate). */ public int getRangeCount() {return rangeCount;} /** * Actual #of key-value pairs in the {@link ResultSet} */ public int getNumTuples() {return ntuples;} /** * True iff the iterator exhausted the available keys such that no more * results would be available if you formed the successor of the * {@link #lastKey}. */ public boolean isExhausted() {return exhausted;} /** * The last key visited by the iterator <em>regardless</em> of the * filter imposed -or- <code>null</code> iff no keys were visited by * the iterator for the specified key range. * * @see #successor() */ public byte[] getLastKey() {return lastKey;} /** * The next key that should be used to retrieve keys and/or values starting * from the first possible successor of the {@link #getLastKey()} visited by * the iterator in this operation (the successor is formed by appending a * <code>nul</code> byte to the {@link #getLastKey()}). * * @return The successor of {@link #getLastKey()} -or- <code>null</code> * iff the iterator exhausted the available keys. * * @exception UnsupportedOperationException * if the {@link #lastKey} is <code>null</code>. */ public byte[] successor() { if (lastKey == null) throw new UnsupportedOperationException(); return BytesUtil.successor(lastKey); } /** * The visited keys iff the keys were requested. */ public byte[][] getKeys() {return keys;} /** * The visited values iff the values were requested. */ public byte[][] getValues() {return vals;} /** * Deserialization constructor. */ public ResultSet() {} /** * Constructor used by the {@link DataService} to populate the * {@link ResultSet}. * * @param ndx * @param fromKey * @param toKey * @param capacity * @param sendKeys * @param sendVals */ public ResultSet(final IIndex ndx, final byte[] fromKey, final byte[] toKey, final int capacity, final boolean sendKeys, final boolean sendVals) { // The upper bound on the #of key-value pairs in the range. rangeCount = ndx.rangeCount(fromKey, toKey); final int limit = (rangeCount > capacity ? capacity : rangeCount); int ntuples = 0; keys = (sendKeys ? new byte[limit][] : null); vals = (sendVals ? new byte[limit][] : null); // iterator that will visit the key range. IEntryIterator itr = ndx.rangeIterator(fromKey, toKey); /* * true if any keys were visited regardless of whether or not they * satisified the optional filter. This is used to make sure that we * always return the lastKey visited if any keys were visited and * otherwise set lastKey := null. */ boolean anything = false; while (ntuples < limit && itr.hasNext()) { anything = true; byte[] val = (byte[]) itr.next(); if (sendVals) vals[ntuples] = val; if (sendKeys) keys[ntuples] = itr.getKey(); // #of results that will be returned. ntuples++; } this.ntuples = ntuples; this.lastKey = (anything ? itr.getKey() : null); this.exhausted = ! itr.hasNext(); } protected static short VERSION0 = 0x0; public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { final short version = ShortPacker.unpackShort(in); if (version != VERSION0) throw new IOException("Unknown version=" + version); rangeCount = (int) LongPacker.unpackLong(in); ntuples = (int)LongPacker.unpackLong(in); exhausted = in.readBoolean(); final boolean haveKeys = in.readBoolean(); final boolean haveVals = in.readBoolean(); final int lastKeySize = (int)LongPacker.unpackLong(in); if(lastKeySize!=0) { lastKey = new byte[lastKeySize]; in.readFully(lastKey); } else { lastKey = null; } if(haveKeys) { keys = new byte[ntuples][]; for(int i=0;i<ntuples;i++) { int size = (int)LongPacker.unpackLong(in); byte[] tmp = new byte[size]; in.readFully(tmp); keys[i] = tmp; } } else { keys = null; } if(haveVals) { vals = new byte[ntuples][]; for(int i=0;i<ntuples;i++) { int size = (int)LongPacker.unpackLong(in); byte[] tmp = new byte[size]; in.readFully(tmp); vals[i] = tmp; } } else { vals = null; } } public void writeExternal(ObjectOutput out) throws IOException { /* * @todo once I have some benchmarks for the data service protocol, * try the changes commented out below and see if the performance is * better when I explicitly buffer the writes. */ // ByteArrayOutputStream baos = new ByteArrayOutputStream(100 + ntuples // * 512); // DataOutput dos = new DataOutputStream(baos); DataOutput dos = out; ShortPacker.packShort(dos, VERSION0); LongPacker.packLong(dos, rangeCount); LongPacker.packLong(dos,ntuples); dos.writeBoolean(exhausted); dos.writeBoolean(keys!=null); dos.writeBoolean(vals!=null); LongPacker.packLong(dos,lastKey==null?0:lastKey.length); if(lastKey!=null) { dos.write(lastKey); } if(keys!=null) { for(int i=0; i<ntuples; i++) { LongPacker.packLong(dos, keys[i].length); dos.write(keys[i]); } } if(vals!=null) { for(int i=0; i<ntuples; i++) { LongPacker.packLong(dos, vals[i].length); dos.write(vals[i]); } } // out.write(baos.toByteArray()); } } |