r/m copied JDK code

patch by jbellis; reviewed by Eric Evans for CASSANDRA-37

git-svn-id: https://svn.apache.org/repos/asf/incubator/cassandra/trunk@769088 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jonathan Ellis 2009-04-27 18:24:25 +00:00
parent d2a61c67b0
commit 7bb094f086
7 changed files with 39 additions and 1700 deletions

View File

@ -19,9 +19,7 @@
package org.apache.cassandra.gms;
import java.util.Random;
import org.apache.cassandra.utils.BitSet;
import java.util.BitSet;
/**

View File

@ -34,267 +34,7 @@ import org.apache.cassandra.continuations.Suspendable;
public final class DataInputBuffer extends DataInputStream
{
/*
* This is a clone of the ByteArrayInputStream class w/o any
* method being synchronized.
*/
public static class FastByteArrayInputStream extends InputStream
{
/**
* An array of bytes that was provided by the creator of the stream.
* Elements <code>buf[0]</code> through <code>buf[count-1]</code> are
* the only bytes that can ever be read from the stream; element
* <code>buf[pos]</code> is the next byte to be read.
*/
protected byte buf[];
/**
* The index of the next character to read from the input stream buffer.
* This value should always be nonnegative and not larger than the value of
* <code>count</code>. The next byte to be read from the input stream
* buffer will be <code>buf[pos]</code>.
*/
protected int pos;
/**
* The currently marked position in the stream. ByteArrayInputStream objects
* are marked at position zero by default when constructed. They may be
* marked at another position within the buffer by the <code>mark()</code>
* method. The current buffer position is set to this point by the
* <code>reset()</code> method.
* <p>
* If no mark has been set, then the value of mark is the offset passed to
* the constructor (or 0 if the offset was not supplied).
*
* @since JDK1.1
*/
protected int mark = 0;
/**
* The index one greater than the last valid character in the input stream
* buffer. This value should always be nonnegative and not larger than the
* length of <code>buf</code>. It is one greater than the position of the
* last byte within <code>buf</code> that can ever be read from the input
* stream buffer.
*/
protected int count;
public FastByteArrayInputStream()
{
buf = new byte[0];
}
/**
* Creates a <code>ByteArrayInputStream</code> so that it uses
* <code>buf</code> as its buffer array. The buffer array is not copied.
* The initial value of <code>pos</code> is <code>0</code> and the
* initial value of <code>count</code> is the length of <code>buf</code>.
*
* @param buf
* the input buffer.
*/
public FastByteArrayInputStream(byte buf[])
{
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
/**
* Creates <code>ByteArrayInputStream</code> that uses <code>buf</code>
* as its buffer array. The initial value of <code>pos</code> is
* <code>offset</code> and the initial value of <code>count</code> is
* the minimum of <code>offset+length</code> and <code>buf.length</code>.
* The buffer array is not copied. The buffer's mark is set to the specified
* offset.
*
* @param buf
* the input buffer.
* @param offset
* the offset in the buffer of the first byte to read.
* @param length
* the maximum number of bytes to read from the buffer.
*/
public FastByteArrayInputStream(byte buf[], int offset, int length)
{
this.buf = buf;
this.pos = offset;
this.count = Math.min(offset + length, buf.length);
this.mark = offset;
}
public final void setBytes(byte[] bytes)
{
buf = bytes;
pos = 0;
count = bytes.length;
}
/**
* Reads the next byte of data from this input stream. The value byte is
* returned as an <code>int</code> in the range <code>0</code> to
* <code>255</code>. If no byte is available because the end of the
* stream has been reached, the value <code>-1</code> is returned.
* <p>
* This <code>read</code> method cannot block.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream has been reached.
*/
public final int read()
{
return (pos < count) ? ( buf[pos++] & 0xFF ) : -1;
}
/**
* Reads up to <code>len</code> bytes of data into an array of bytes from
* this input stream. If <code>pos</code> equals <code>count</code>,
* then <code>-1</code> is returned to indicate end of file. Otherwise,
* the number <code>k</code> of bytes read is equal to the smaller of
* <code>len</code> and <code>count-pos</code>. If <code>k</code> is
* positive, then bytes <code>buf[pos]</code> through
* <code>buf[pos+k-1]</code> are copied into <code>b[off]</code> through
* <code>b[off+k-1]</code> in the manner performed by
* <code>System.arraycopy</code>. The value <code>k</code> is added
* into <code>pos</code> and <code>k</code> is returned.
* <p>
* This <code>read</code> method cannot block.
*
* @param b
* the buffer into which the data is read.
* @param off
* the start offset in the destination array <code>b</code>
* @param len
* the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of the
* stream has been reached.
* @exception NullPointerException
* If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException
* If <code>off</code> is negative, <code>len</code> is
* negative, or <code>len</code> is greater than
* <code>b.length - off</code>
*/
public final int read(byte b[], int off, int len)
{
if (b == null)
{
throw new NullPointerException();
}
else if (off < 0 || len < 0 || len > b.length - off)
{
throw new IndexOutOfBoundsException();
}
if (pos >= count)
{
return -1;
}
if (pos + len > count)
{
len = count - pos;
}
if (len <= 0)
{
return 0;
}
System.arraycopy(buf, pos, b, off, len);
pos += len;
return len;
}
/**
* Skips <code>n</code> bytes of input from this input stream. Fewer bytes
* might be skipped if the end of the input stream is reached. The actual
* number <code>k</code> of bytes to be skipped is equal to the smaller of
* <code>n</code> and <code>count-pos</code>. The value <code>k</code>
* is added into <code>pos</code> and <code>k</code> is returned.
*
* @param n
* the number of bytes to be skipped.
* @return the actual number of bytes skipped.
*/
public final long skip(long n)
{
if (pos + n > count)
{
n = count - pos;
}
if (n < 0)
{
return 0;
}
pos += n;
return n;
}
/**
* Returns the number of remaining bytes that can be read (or skipped over)
* from this input stream.
* <p>
* The value returned is <code>count&nbsp;- pos</code>, which is the
* number of bytes remaining to be read from the input buffer.
*
* @return the number of remaining bytes that can be read (or skipped over)
* from this input stream without blocking.
*/
public final int available()
{
return count - pos;
}
/**
* Tests if this <code>InputStream</code> supports mark/reset. The
* <code>markSupported</code> method of <code>ByteArrayInputStream</code>
* always returns <code>true</code>.
*
* @since JDK1.1
*/
public final boolean markSupported()
{
return true;
}
/**
* Set the current marked position in the stream. ByteArrayInputStream
* objects are marked at position zero by default when constructed. They may
* be marked at another position within the buffer by this method.
* <p>
* If no mark has been set, then the value of the mark is the offset passed
* to the constructor (or 0 if the offset was not supplied).
*
* <p>
* Note: The <code>readAheadLimit</code> for this class has no meaning.
*
* @since JDK1.1
*/
public final void mark(int readAheadLimit)
{
mark = pos;
}
/**
* Resets the buffer to the marked position. The marked position is 0 unless
* another position was marked or an offset was specified in the
* constructor.
*/
public final void reset()
{
pos = mark;
}
/**
* Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an <tt>IOException</tt>.
* <p>
*/
public final void close() throws IOException
{
}
}
private static class Buffer extends FastByteArrayInputStream
private static class Buffer extends ByteArrayInputStream
{
public Buffer()
{
@ -351,18 +91,6 @@ public final class DataInputBuffer extends DataInputStream
buffer_.reset(input, start, length);
}
/** Returns the current position in the input. */
public int getPosition()
{
return buffer_.getPosition();
}
/** Set the position within the input */
public void setPosition(int position)
{
buffer_.setPosition(position);
}
/** Returns the length of the input. */
public int getLength()
{

View File

@ -35,246 +35,7 @@ import org.apache.cassandra.continuations.Suspendable;
*/
public class DataOutputBuffer extends DataOutputStream
{
/*
* This is a clone of the ByteArrayOutputStream but w/o the unnecessary
* synchronized keyword usage.
*/
public static class FastByteArrayOutputStream extends OutputStream
{
/**
* The buffer where data is stored.
*/
protected byte buf[];
/**
* The number of valid bytes in the buffer.
*/
protected int count;
/**
* Creates a new byte array output stream. The buffer capacity is
* initially 32 bytes, though its size increases if necessary.
*/
public FastByteArrayOutputStream()
{
this(32);
}
/**
* Creates a new byte array output stream, with a buffer capacity of the
* specified size, in bytes.
*
* @param size
* the initial size.
* @exception IllegalArgumentException
* if size is negative.
*/
public FastByteArrayOutputStream(int size)
{
if (size < 0)
{
throw new IllegalArgumentException("Negative initial size: "
+ size);
}
buf = new byte[size];
}
/**
* Writes the specified byte to this byte array output stream.
*
* @param b
* the byte to be written.
*/
public void write(int b)
{
int newcount = count + 1;
if (newcount > buf.length)
{
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
buf[count] = (byte) b;
count = newcount;
}
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this byte array output
* stream.
*
* @param b
* the data.
* @param off
* the start offset in the data.
* @param len
* the number of bytes to write.
*/
public void write(byte b[], int off, int len)
{
if ((off < 0) || (off > b.length) || (len < 0)
|| ((off + len) > b.length) || ((off + len) < 0))
{
throw new IndexOutOfBoundsException();
}
else if (len == 0)
{
return;
}
int newcount = count + len;
if (newcount > buf.length)
{
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
System.arraycopy(b, off, buf, count, len);
count = newcount;
}
/**
* Writes the complete contents of this byte array output stream to the
* specified output stream argument, as if by calling the output
* stream's write method using <code>out.write(buf, 0, count)</code>.
*
* @param out
* the output stream to which to write the data.
* @exception IOException
* if an I/O error occurs.
*/
public void writeTo(OutputStream out) throws IOException
{
out.write(buf, 0, count);
}
/**
* Resets the <code>count</code> field of this byte array output
* stream to zero, so that all currently accumulated output in the
* output stream is discarded. The output stream can be used again,
* reusing the already allocated buffer space.
*
* @see java.io.ByteArrayInputStream#count
*/
public void reset()
{
count = 0;
}
/**
* Creates a newly allocated byte array. Its size is the current size of
* this output stream and the valid contents of the buffer have been
* copied into it.
*
* @return the current contents of this output stream, as a byte array.
* @see java.io.ByteArrayOutputStream#size()
*/
public byte toByteArray()[]
{
return Arrays.copyOf(buf, count);
}
/**
* Returns the current size of the buffer.
*
* @return the value of the <code>count</code> field, which is the
* number of valid bytes in this output stream.
* @see java.io.ByteArrayOutputStream#count
*/
public int size()
{
return count;
}
/**
* Converts the buffer's contents into a string decoding bytes using the
* platform's default character set. The length of the new
* <tt>String</tt> is a function of the character set, and hence may
* not be equal to the size of the buffer.
*
* <p>
* This method always replaces malformed-input and unmappable-character
* sequences with the default replacement string for the platform's
* default character set. The
* {@linkplain java.nio.charset.CharsetDecoder} class should be used
* when more control over the decoding process is required.
*
* @return String decoded from the buffer's contents.
* @since JDK1.1
*/
public String toString()
{
return new String(buf, 0, count);
}
/**
* Converts the buffer's contents into a string by decoding the bytes
* using the specified {@link java.nio.charset.Charset charsetName}.
* The length of the new <tt>String</tt> is a function of the charset,
* and hence may not be equal to the length of the byte array.
*
* <p>
* This method always replaces malformed-input and unmappable-character
* sequences with this charset's default replacement string. The {@link
* java.nio.charset.CharsetDecoder} class should be used when more
* control over the decoding process is required.
*
* @param charsetName
* the name of a supported
* {@linkplain java.nio.charset.Charset </code>charset<code>}
* @return String decoded from the buffer's contents.
* @exception UnsupportedEncodingException
* If the named charset is not supported
* @since JDK1.1
*/
public String toString(String charsetName) throws UnsupportedEncodingException
{
return new String(buf, 0, count, charsetName);
}
/**
* Creates a newly allocated string. Its size is the current size of the
* output stream and the valid contents of the buffer have been copied
* into it. Each character <i>c</i> in the resulting string is
* constructed from the corresponding element <i>b</i> in the byte
* array such that: <blockquote>
*
* <pre>
* c == (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
* </pre>
*
* </blockquote>
*
* @deprecated This method does not properly convert bytes into
* characters. As of JDK&nbsp;1.1, the preferred way to do
* this is via the <code>toString(String enc)</code>
* method, which takes an encoding-name argument, or the
* <code>toString()</code> method, which uses the
* platform's default character encoding.
*
* @param hibyte
* the high byte of each resulting Unicode character.
* @return the current contents of the output stream, as a string.
* @see java.io.ByteArrayOutputStream#size()
* @see java.io.ByteArrayOutputStream#toString(String)
* @see java.io.ByteArrayOutputStream#toString()
*/
@Deprecated
public String toString(int hibyte)
{
return new String(buf, hibyte, 0, count);
}
/**
* Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods
* in this class can be called after the stream has been closed without
* generating an <tt>IOException</tt>.
* <p>
*
*/
public void close() throws IOException
{
}
}
private static class Buffer extends FastByteArrayOutputStream
private static class Buffer extends ByteArrayOutputStream
{
public byte[] getData()
{
@ -300,24 +61,9 @@ public class DataOutputBuffer extends DataOutputStream
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
long start = System.currentTimeMillis();
in.readFully(buf, count, len);
count = newcount;
}
public void write(ByteBuffer buffer, int len) throws IOException
{
int newcount = count + len;
if (newcount > buf.length)
{
byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
long start = System.currentTimeMillis();
buffer.get(buf, count, len);
count = newcount;
}
}
private Buffer buffer;
@ -362,10 +108,4 @@ public class DataOutputBuffer extends DataOutputStream
{
buffer.write(in, length);
}
/** Writes bytes from a ByteBuffer directly into the buffer. */
public void write(ByteBuffer in, int length) throws IOException
{
buffer.write(in, length);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
package org.apache.cassandra.utils;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.util.BitSet;
import org.apache.cassandra.io.ICompactSerializer;
class BitSetSerializer
{
public static void serialize(BitSet bs, DataOutputStream dos) throws IOException
{
ObjectOutputStream oos = new ObjectOutputStream(dos);
oos.writeObject(bs);
oos.flush();
}
public static BitSet deserialize(DataInputStream dis) throws IOException
{
ObjectInputStream ois = new ObjectInputStream(dis);
try
{
return (BitSet) ois.readObject();
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
}

View File

@ -21,6 +21,7 @@ package org.apache.cassandra.utils;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.BitSet;
import org.apache.cassandra.io.ICompactSerializer;
@ -127,13 +128,13 @@ class BloomFilterSerializer implements ICompactSerializer<BloomFilter>
throws IOException
{
dos.writeInt(bf.getHashCount());
BitSet.serializer().serialize(bf.filter(), dos);
BitSetSerializer.serialize(bf.filter(), dos);
}
public BloomFilter deserialize(DataInputStream dis) throws IOException
{
int hashes = dis.readInt();
BitSet bs = BitSet.serializer().deserialize(dis);
BitSet bs = BitSetSerializer.deserialize(dis);
return new BloomFilter(hashes, bs);
}
}

View File

@ -6,25 +6,6 @@ import java.util.Random;
import java.io.IOException;
public class DataInputBufferTest {
@Test
public void testRandom() throws IOException {
Random random = new Random();
byte[] bytes = new byte[1024*1024];
random.nextBytes(bytes);
DataInputBuffer.FastByteArrayInputStream bis = new DataInputBuffer.FastByteArrayInputStream(bytes);
int read = 0;
int n = 0;
while ( true )
{
read = bis.read();
if ( read == -1 )
break;
assert read == ((int)bytes[n++]&0xFF);
}
assert n == bytes.length;
}
@Test
public void testSmall() throws IOException {
DataOutputBuffer bufOut = new DataOutputBuffer();