diff --git a/src/org/apache/cassandra/gms/PureRandom.java b/src/org/apache/cassandra/gms/PureRandom.java index 1e3a52c0e3..5882efc837 100644 --- a/src/org/apache/cassandra/gms/PureRandom.java +++ b/src/org/apache/cassandra/gms/PureRandom.java @@ -19,9 +19,7 @@ package org.apache.cassandra.gms; import java.util.Random; - -import org.apache.cassandra.utils.BitSet; - +import java.util.BitSet; /** diff --git a/src/org/apache/cassandra/io/DataInputBuffer.java b/src/org/apache/cassandra/io/DataInputBuffer.java index 2b933e7016..e249ff37ba 100644 --- a/src/org/apache/cassandra/io/DataInputBuffer.java +++ b/src/org/apache/cassandra/io/DataInputBuffer.java @@ -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 buf[0] through buf[count-1] are - * the only bytes that can ever be read from the stream; element - * buf[pos] 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 - * count. The next byte to be read from the input stream - * buffer will be buf[pos]. - */ - 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 mark() - * method. The current buffer position is set to this point by the - * reset() method. - *

- * 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 buf. It is one greater than the position of the - * last byte within buf that can ever be read from the input - * stream buffer. - */ - protected int count; - - public FastByteArrayInputStream() - { - buf = new byte[0]; - } - - /** - * Creates a ByteArrayInputStream so that it uses - * buf as its buffer array. The buffer array is not copied. - * The initial value of pos is 0 and the - * initial value of count is the length of buf. - * - * @param buf - * the input buffer. - */ - public FastByteArrayInputStream(byte buf[]) - { - this.buf = buf; - this.pos = 0; - this.count = buf.length; - } - - /** - * Creates ByteArrayInputStream that uses buf - * as its buffer array. The initial value of pos is - * offset and the initial value of count is - * the minimum of offset+length and buf.length. - * 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 int in the range 0 to - * 255. If no byte is available because the end of the - * stream has been reached, the value -1 is returned. - *

- * This read method cannot block. - * - * @return the next byte of data, or -1 if the end of the - * stream has been reached. - */ - public final int read() - { - return (pos < count) ? ( buf[pos++] & 0xFF ) : -1; - } - - /** - * Reads up to len bytes of data into an array of bytes from - * this input stream. If pos equals count, - * then -1 is returned to indicate end of file. Otherwise, - * the number k of bytes read is equal to the smaller of - * len and count-pos. If k is - * positive, then bytes buf[pos] through - * buf[pos+k-1] are copied into b[off] through - * b[off+k-1] in the manner performed by - * System.arraycopy. The value k is added - * into pos and k is returned. - *

- * This read method cannot block. - * - * @param b - * the buffer into which the data is read. - * @param off - * the start offset in the destination array b - * @param len - * the maximum number of bytes read. - * @return the total number of bytes read into the buffer, or - * -1 if there is no more data because the end of the - * stream has been reached. - * @exception NullPointerException - * If b is null. - * @exception IndexOutOfBoundsException - * If off is negative, len is - * negative, or len is greater than - * b.length - off - */ - 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 n bytes of input from this input stream. Fewer bytes - * might be skipped if the end of the input stream is reached. The actual - * number k of bytes to be skipped is equal to the smaller of - * n and count-pos. The value k - * is added into pos and k 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. - *

- * The value returned is count - pos, 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 InputStream supports mark/reset. The - * markSupported method of ByteArrayInputStream - * always returns true. - * - * @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. - *

- * 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). - * - *

- * Note: The readAheadLimit 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 ByteArrayInputStream has no effect. The methods in - * this class can be called after the stream has been closed without - * generating an IOException. - *

- */ - 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() { diff --git a/src/org/apache/cassandra/io/DataOutputBuffer.java b/src/org/apache/cassandra/io/DataOutputBuffer.java index dfcb5d731d..0c9f6d7a91 100644 --- a/src/org/apache/cassandra/io/DataOutputBuffer.java +++ b/src/org/apache/cassandra/io/DataOutputBuffer.java @@ -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 len bytes from the specified byte array - * starting at offset off 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 out.write(buf, 0, count). - * - * @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 count 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 count 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 - * String is a function of the character set, and hence may - * not be equal to the size of the buffer. - * - *

- * 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 String is a function of the charset, - * and hence may not be equal to the length of the byte array. - * - *

- * 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 charset} - * @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 c in the resulting string is - * constructed from the corresponding element b in the byte - * array such that:

- * - *
-         * c == (char) (((hibyte & 0xff) << 8) | (b & 0xff))
-         * 
- * - *
- * - * @deprecated This method does not properly convert bytes into - * characters. As of JDK 1.1, the preferred way to do - * this is via the toString(String enc) - * method, which takes an encoding-name argument, or the - * toString() 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 ByteArrayOutputStream has no effect. The methods - * in this class can be called after the stream has been closed without - * generating an IOException. - *

- * - */ - 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); - } } diff --git a/src/org/apache/cassandra/utils/BitSet.java b/src/org/apache/cassandra/utils/BitSet.java deleted file mode 100644 index 9e94a62163..0000000000 --- a/src/org/apache/cassandra/utils/BitSet.java +++ /dev/null @@ -1,1142 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.cassandra.utils; - -import java.io.*; -import java.util.*; - -import org.apache.cassandra.io.ICompactSerializer; - - -/** - * This class implements a vector of bits that grows as needed. Each component - * of the bit set has a boolean value. The bits of a - * BitSet are indexed by nonnegative integers. Individual indexed - * bits can be examined, set, or cleared. One BitSet may be used - * to modify the contents of another BitSet through logical AND, - * logical inclusive OR, and logical exclusive OR operations. - *

- * By default, all bits in the set initially have the value false. - *

- * Every bit set has a current size, which is the number of bits of space - * currently in use by the bit set. Note that the size is related to the - * implementation of a bit set, so it may change with implementation. The length - * of a bit set relates to logical length of a bit set and is defined - * independently of implementation. - *

- * Unless otherwise noted, passing a null parameter to any of the methods in a - * BitSet will result in a NullPointerException. - * - *

- * A BitSet is not safe for multithreaded use without external - * synchronization. - * - * Author : Avinash Lakshman ( alakshman@facebook.com) & Prashant Malik ( pmalik@facebook.com ) - */ -public class BitSet implements Cloneable, java.io.Serializable -{ - /* - * BitSets are packed into arrays of "words." Currently a word is a long, - * which consists of 64 bits, requiring 6 address bits. The choice of word - * size is determined purely by performance concerns. - */ - private final static int ADDRESS_BITS_PER_WORD = 6; - private final static int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD; - private final static int BIT_INDEX_MASK = BITS_PER_WORD - 1; - - /* Used to shift left or right for a partial word mask */ - private static final long WORD_MASK = 0xffffffffffffffffL; - - /** - * @serialField bits long[] - * - * The bits in this BitSet. The ith bit is stored in bits[i/64] at bit - * position i % 64 (where bit position 0 refers to the least significant bit - * and 63 refers to the most significant bit). - */ - private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField( - "bits", long[].class), }; - private static ICompactSerializer serializer_ = new BitSetSerializer(); - - static ICompactSerializer serializer() - { - return serializer_; - } - - /** - * The internal field corresponding to the serialField "bits". - */ - private long[] words; - - /** - * The number of words in the logical size of this BitSet. - */ - private int wordsInUse = 0; - - /** - * Whether the size of "words" is user-specified. If so, we assume the user - * knows what he's doing and try harder to preserve it. - */ - private transient boolean sizeIsSticky = false; - - /* use serialVersionUID from JDK 1.0.2 for interoperability */ - private static final long serialVersionUID = 7997698588986878753L; - - /** - * Given a bit index, return word index containing it. - */ - private static int wordIndex(int bitIndex) - { - return bitIndex >> ADDRESS_BITS_PER_WORD; - } - - /** - * Every public method must preserve these invariants. - */ - private void checkInvariants() - { - assert (wordsInUse == 0 || words[wordsInUse - 1] != 0); - assert (wordsInUse >= 0 && wordsInUse <= words.length); - assert (wordsInUse == words.length || words[wordsInUse] == 0); - } - - /** - * Set the field wordsInUse with the logical size in words of the bit set. - * WARNING:This method assumes that the number of words actually in use is - * less than or equal to the current value of wordsInUse! - */ - private void recalculateWordsInUse() - { - // Traverse the bitset until a used word is found - int i; - for (i = wordsInUse - 1; i >= 0; i--) - if (words[i] != 0) - break; - - wordsInUse = i + 1; // The new logical size - } - - /** - * Creates a new bit set. All bits are initially false. - */ - public BitSet() - { - initWords(BITS_PER_WORD); - sizeIsSticky = false; - } - - /** - * Creates a bit set whose initial size is large enough to explicitly - * represent bits with indices in the range 0 through - * nbits-1. All bits are initially false. - * - * @param nbits - * the initial size of the bit set. - * @exception NegativeArraySizeException - * if the specified initial size is negative. - */ - public BitSet(int nbits) - { - // nbits can't be negative; size 0 is OK - if (nbits < 0) - throw new NegativeArraySizeException("nbits < 0: " + nbits); - - initWords(nbits); - sizeIsSticky = true; - } - - /** - * This version is used only during deserialization. - * - * @param words the array which we use to defreeze - * the BitSet. - */ - BitSet(int wordsInUse, long[] words) - { - this.wordsInUse = wordsInUse; - this.words = words; - this.sizeIsSticky = true; - } - - int wordsInUse() - { - return this.wordsInUse; - } - - long[] words() - { - return this.words; - } - - private void initWords(int nbits) - { - words = new long[wordIndex(nbits - 1) + 1]; - } - - /** - * Ensures that the BitSet can hold enough words. - * - * @param wordsRequired - * the minimum acceptable number of words. - */ - private void ensureCapacity(int wordsRequired) - { - if (words.length < wordsRequired) - { - // Allocate larger of doubled size or required size - int request = Math.max(2 * words.length, wordsRequired); - words = Arrays.copyOf(words, request); - sizeIsSticky = false; - } - } - - /** - * Ensures that the BitSet can accommodate a given wordIndex, temporarily - * violating the invariants. The caller must restore the invariants before - * returning to the user, possibly using recalculateWordsInUse(). - * - * @param wordIndex - * the index to be accommodated. - */ - private void expandTo(int wordIndex) - { - int wordsRequired = wordIndex + 1; - if (wordsInUse < wordsRequired) - { - ensureCapacity(wordsRequired); - wordsInUse = wordsRequired; - } - } - - /** - * Checks that fromIndex ... toIndex is a valid range of bit indices. - */ - private static void checkRange(int fromIndex, int toIndex) - { - if (fromIndex < 0) - throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); - if (toIndex < 0) - throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex); - if (fromIndex > toIndex) - throw new IndexOutOfBoundsException("fromIndex: " + fromIndex - + " > toIndex: " + toIndex); - } - - /** - * Sets the bit at the specified index to the complement of its current - * value. - * - * @param bitIndex - * the index of the bit to flip. - * @exception IndexOutOfBoundsException - * if the specified index is negative. - * @since 1.4 - */ - public void flip(int bitIndex) - { - if (bitIndex < 0) - throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); - - int wordIndex = wordIndex(bitIndex); - expandTo(wordIndex); - - words[wordIndex] ^= (1L << bitIndex); - - recalculateWordsInUse(); - checkInvariants(); - } - - /** - * Sets each bit from the specified fromIndex (inclusive) to the - * specified toIndex (exclusive) to the complement of its current - * value. - * - * @param fromIndex - * index of the first bit to flip. - * @param toIndex - * index after the last bit to flip. - * @exception IndexOutOfBoundsException - * if fromIndex is negative, or toIndex - * is negative, or fromIndex is larger than - * toIndex. - * @since 1.4 - */ - public void flip(int fromIndex, int toIndex) - { - checkRange(fromIndex, toIndex); - - if (fromIndex == toIndex) - return; - - int startWordIndex = wordIndex(fromIndex); - int endWordIndex = wordIndex(toIndex - 1); - expandTo(endWordIndex); - - long firstWordMask = WORD_MASK << fromIndex; - long lastWordMask = WORD_MASK >>> -toIndex; - if (startWordIndex == endWordIndex) - { - // Case 1: One word - words[startWordIndex] ^= (firstWordMask & lastWordMask); - } - else - { - // Case 2: Multiple words - // Handle first word - words[startWordIndex] ^= firstWordMask; - - // Handle intermediate words, if any - for (int i = startWordIndex + 1; i < endWordIndex; i++) - words[i] ^= WORD_MASK; - - // Handle last word - words[endWordIndex] ^= lastWordMask; - } - - recalculateWordsInUse(); - checkInvariants(); - } - - /** - * Sets the bit at the specified index to true. - * - * @param bitIndex - * a bit index. - * @exception IndexOutOfBoundsException - * if the specified index is negative. - * @since JDK1.0 - */ - public void set(int bitIndex) - { - if (bitIndex < 0) - throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); - - int wordIndex = wordIndex(bitIndex); - expandTo(wordIndex); - - words[wordIndex] |= (1L << bitIndex); // Restores invariants - - checkInvariants(); - } - - /** - * Sets the bit at the specified index to the specified value. - * - * @param bitIndex - * a bit index. - * @param value - * a boolean value to set. - * @exception IndexOutOfBoundsException - * if the specified index is negative. - * @since 1.4 - */ - public void set(int bitIndex, boolean value) - { - if (value) - set(bitIndex); - else - clear(bitIndex); - } - - /** - * Sets the bits from the specified fromIndex (inclusive) to the - * specified toIndex (exclusive) to true. - * - * @param fromIndex - * index of the first bit to be set. - * @param toIndex - * index after the last bit to be set. - * @exception IndexOutOfBoundsException - * if fromIndex is negative, or toIndex - * is negative, or fromIndex is larger than - * toIndex. - * @since 1.4 - */ - public void set(int fromIndex, int toIndex) - { - checkRange(fromIndex, toIndex); - - if (fromIndex == toIndex) - return; - - // Increase capacity if necessary - int startWordIndex = wordIndex(fromIndex); - int endWordIndex = wordIndex(toIndex - 1); - expandTo(endWordIndex); - - long firstWordMask = WORD_MASK << fromIndex; - long lastWordMask = WORD_MASK >>> -toIndex; - if (startWordIndex == endWordIndex) - { - // Case 1: One word - words[startWordIndex] |= (firstWordMask & lastWordMask); - } - else - { - // Case 2: Multiple words - // Handle first word - words[startWordIndex] |= firstWordMask; - - // Handle intermediate words, if any - for (int i = startWordIndex + 1; i < endWordIndex; i++) - words[i] = WORD_MASK; - - // Handle last word (restores invariants) - words[endWordIndex] |= lastWordMask; - } - - checkInvariants(); - } - - /** - * Sets the bits from the specified fromIndex (inclusive) to the - * specified toIndex (exclusive) to the specified value. - * - * @param fromIndex - * index of the first bit to be set. - * @param toIndex - * index after the last bit to be set - * @param value - * value to set the selected bits to - * @exception IndexOutOfBoundsException - * if fromIndex is negative, or toIndex - * is negative, or fromIndex is larger than - * toIndex. - * @since 1.4 - */ - public void set(int fromIndex, int toIndex, boolean value) - { - if (value) - set(fromIndex, toIndex); - else - clear(fromIndex, toIndex); - } - - /** - * Sets the bit specified by the index to false. - * - * @param bitIndex - * the index of the bit to be cleared. - * @exception IndexOutOfBoundsException - * if the specified index is negative. - * @since JDK1.0 - */ - public void clear(int bitIndex) - { - if (bitIndex < 0) - throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); - - int wordIndex = wordIndex(bitIndex); - if (wordIndex >= wordsInUse) - return; - - words[wordIndex] &= ~(1L << bitIndex); - - recalculateWordsInUse(); - checkInvariants(); - } - - /** - * Sets the bits from the specified fromIndex (inclusive) to the - * specified toIndex (exclusive) to false. - * - * @param fromIndex - * index of the first bit to be cleared. - * @param toIndex - * index after the last bit to be cleared. - * @exception IndexOutOfBoundsException - * if fromIndex is negative, or toIndex - * is negative, or fromIndex is larger than - * toIndex. - * @since 1.4 - */ - public void clear(int fromIndex, int toIndex) - { - checkRange(fromIndex, toIndex); - - if (fromIndex == toIndex) - return; - - int startWordIndex = wordIndex(fromIndex); - if (startWordIndex >= wordsInUse) - return; - - int endWordIndex = wordIndex(toIndex - 1); - if (endWordIndex >= wordsInUse) - { - toIndex = length(); - endWordIndex = wordsInUse - 1; - } - - long firstWordMask = WORD_MASK << fromIndex; - long lastWordMask = WORD_MASK >>> -toIndex; - if (startWordIndex == endWordIndex) - { - // Case 1: One word - words[startWordIndex] &= ~(firstWordMask & lastWordMask); - } - else - { - // Case 2: Multiple words - // Handle first word - words[startWordIndex] &= ~firstWordMask; - - // Handle intermediate words, if any - for (int i = startWordIndex + 1; i < endWordIndex; i++) - words[i] = 0; - - // Handle last word - words[endWordIndex] &= ~lastWordMask; - } - - recalculateWordsInUse(); - checkInvariants(); - } - - /** - * Sets all of the bits in this BitSet to false. - * - * @since 1.4 - */ - public void clear() - { - while (wordsInUse > 0) - words[--wordsInUse] = 0; - } - - /** - * Returns the value of the bit with the specified index. The value is - * true if the bit with the index bitIndex is - * currently set in this BitSet; otherwise, the result is - * false. - * - * @param bitIndex - * the bit index. - * @return the value of the bit with the specified index. - * @exception IndexOutOfBoundsException - * if the specified index is negative. - */ - public boolean get(int bitIndex) - { - if (bitIndex < 0) - throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); - - checkInvariants(); - - int wordIndex = wordIndex(bitIndex); - return (wordIndex < wordsInUse) - && ((words[wordIndex] & (1L << bitIndex)) != 0); - } - - /** - * Returns a new BitSet composed of bits from this - * BitSet from fromIndex (inclusive) to - * toIndex (exclusive). - * - * @param fromIndex - * index of the first bit to include. - * @param toIndex - * index after the last bit to include. - * @return a new BitSet from a range of this BitSet. - * @exception IndexOutOfBoundsException - * if fromIndex is negative, or toIndex - * is negative, or fromIndex is larger than - * toIndex. - * @since 1.4 - */ - public BitSet get(int fromIndex, int toIndex) - { - checkRange(fromIndex, toIndex); - - checkInvariants(); - - int len = length(); - - // If no set bits in range return empty bitset - if (len <= fromIndex || fromIndex == toIndex) - return new BitSet(0); - - // An optimization - if (toIndex > len) - toIndex = len; - - BitSet result = new BitSet(toIndex - fromIndex); - int targetWords = wordIndex(toIndex - fromIndex - 1) + 1; - int sourceIndex = wordIndex(fromIndex); - boolean wordAligned = ((fromIndex & BIT_INDEX_MASK) == 0); - - // Process all words but the last word - for (int i = 0; i < targetWords - 1; i++, sourceIndex++) - result.words[i] = wordAligned ? words[sourceIndex] - : (words[sourceIndex] >>> fromIndex) - | (words[sourceIndex + 1] << -fromIndex); - - // Process the last word - long lastWordMask = WORD_MASK >>> -toIndex; - result.words[targetWords - 1] = ((toIndex - 1) & BIT_INDEX_MASK) < (fromIndex & BIT_INDEX_MASK) ? /* - * straddles - * source - * words - */ - ((words[sourceIndex] >>> fromIndex) | (words[sourceIndex + 1] & lastWordMask) << -fromIndex) - : ((words[sourceIndex] & lastWordMask) >>> fromIndex); - - // Set wordsInUse correctly - result.wordsInUse = targetWords; - result.recalculateWordsInUse(); - result.checkInvariants(); - - return result; - } - - /** - * Returns the index of the first bit that is set to true - * that occurs on or after the specified starting index. If no such bit - * exists then -1 is returned. - * - * To iterate over the true bits in a BitSet, - * use the following loop: - * - *

-     * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1))
-     * {
-     *     // operate on index i here
-     * }
-     * 
- * - * @param fromIndex - * the index to start checking from (inclusive). - * @return the index of the next set bit. - * @throws IndexOutOfBoundsException - * if the specified index is negative. - * @since 1.4 - */ - public int nextSetBit(int fromIndex) - { - if (fromIndex < 0) - throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); - - checkInvariants(); - - int u = wordIndex(fromIndex); - if (u >= wordsInUse) - return -1; - - long word = words[u] & (WORD_MASK << fromIndex); - - while (true) - { - if (word != 0) - return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word); - if (++u == wordsInUse) - return -1; - word = words[u]; - } - } - - /** - * Returns the index of the first bit that is set to false - * that occurs on or after the specified starting index. - * - * @param fromIndex - * the index to start checking from (inclusive). - * @return the index of the next clear bit. - * @throws IndexOutOfBoundsException - * if the specified index is negative. - * @since 1.4 - */ - public int nextClearBit(int fromIndex) - { - // Neither spec nor implementation handle bitsets of maximal length. - // See 4816253. - if (fromIndex < 0) - throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); - - checkInvariants(); - - int u = wordIndex(fromIndex); - if (u >= wordsInUse) - return fromIndex; - - long word = ~words[u] & (WORD_MASK << fromIndex); - - while (true) - { - if (word != 0) - return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word); - if (++u == wordsInUse) - return wordsInUse * BITS_PER_WORD; - word = ~words[u]; - } - } - - /** - * Returns the "logical size" of this BitSet: the index of - * the highest set bit in the BitSet plus one. Returns zero - * if the BitSet contains no set bits. - * - * @return the logical size of this BitSet. - * @since 1.2 - */ - public int length() - { - if (wordsInUse == 0) - return 0; - - return BITS_PER_WORD - * (wordsInUse - 1) - + (BITS_PER_WORD - Long - .numberOfLeadingZeros(words[wordsInUse - 1])); - } - - /** - * Returns true if this BitSet contains no bits that are set - * to true. - * - * @return boolean indicating whether this BitSet is empty. - * @since 1.4 - */ - public boolean isEmpty() - { - return wordsInUse == 0; - } - - /** - * Returns true if the specified BitSet has any bits set to - * true that are also set to true in this - * BitSet. - * - * @param set - * BitSet to intersect with - * @return boolean indicating whether this BitSet intersects - * the specified BitSet. - * @since 1.4 - */ - public boolean intersects(BitSet set) - { - for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--) - if ((words[i] & set.words[i]) != 0) - return true; - return false; - } - - /** - * Returns the number of bits set to true in this - * BitSet. - * - * @return the number of bits set to true in this - * BitSet. - * @since 1.4 - */ - public int cardinality() - { - int sum = 0; - for (int i = 0; i < wordsInUse; i++) - sum += Long.bitCount(words[i]); - return sum; - } - - /** - * Performs a logical AND of this target bit set with the argument - * bit set. This bit set is modified so that each bit in it has the value - * true if and only if it both initially had the value - * true and the corresponding bit in the bit set argument - * also had the value true. - * - * @param set - * a bit set. - */ - public void and(BitSet set) - { - if (this == set) - return; - - while (wordsInUse > set.wordsInUse) - words[--wordsInUse] = 0; - - // Perform logical AND on words in common - for (int i = 0; i < wordsInUse; i++) - words[i] &= set.words[i]; - - recalculateWordsInUse(); - checkInvariants(); - } - - /** - * Performs a logical OR of this bit set with the bit set argument. - * This bit set is modified so that a bit in it has the value - * true if and only if it either already had the value - * true or the corresponding bit in the bit set argument has - * the value true. - * - * @param set - * a bit set. - */ - public void or(BitSet set) - { - if (this == set) - return; - - int wordsInCommon = Math.min(wordsInUse, set.wordsInUse); - - if (wordsInUse < set.wordsInUse) - { - ensureCapacity(set.wordsInUse); - wordsInUse = set.wordsInUse; - } - - // Perform logical OR on words in common - for (int i = 0; i < wordsInCommon; i++) - words[i] |= set.words[i]; - - // Copy any remaining words - if (wordsInCommon < set.wordsInUse) - System.arraycopy(set.words, wordsInCommon, words, wordsInCommon, - wordsInUse - wordsInCommon); - - // recalculateWordsInUse() is unnecessary - checkInvariants(); - } - - /** - * Performs a logical XOR of this bit set with the bit set argument. - * This bit set is modified so that a bit in it has the value - * true if and only if one of the following statements holds: - * - * - * @param set - * a bit set. - */ - public void xor(BitSet set) - { - int wordsInCommon = Math.min(wordsInUse, set.wordsInUse); - - if (wordsInUse < set.wordsInUse) - { - ensureCapacity(set.wordsInUse); - wordsInUse = set.wordsInUse; - } - - // Perform logical XOR on words in common - for (int i = 0; i < wordsInCommon; i++) - words[i] ^= set.words[i]; - - // Copy any remaining words - if (wordsInCommon < set.wordsInUse) - System.arraycopy(set.words, wordsInCommon, words, wordsInCommon, - set.wordsInUse - wordsInCommon); - - recalculateWordsInUse(); - checkInvariants(); - } - - /** - * Clears all of the bits in this BitSet whose corresponding - * bit is set in the specified BitSet. - * - * @param set - * the BitSet with which to mask this - * BitSet. - * @since 1.2 - */ - public void andNot(BitSet set) - { - // Perform logical (a & !b) on words in common - for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--) - words[i] &= ~set.words[i]; - - recalculateWordsInUse(); - checkInvariants(); - } - - /** - * Returns a hash code value for this bit set. The hash code depends only on - * which bits have been set within this BitSet. The - * algorithm used to compute it may be described as follows. - *

- * Suppose the bits in the BitSet were to be stored in an - * array of long integers called, say, words, - * in such a manner that bit k is set in the - * BitSet (for nonnegative values of k) if - * and only if the expression - * - *

-     * ((k >> 6) < words.length) && ((words[k >> 6] & (1L << (bit & 0x3F))) != 0)
-     * 
- * - * is true. Then the following definition of the hashCode - * method would be a correct implementation of the actual algorithm: - * - *
-     * public int hashCode()
-     * {
-     *     long h = 1234;
-     *     for (int i = words.length; --i >= 0;)
-     *     {
-     *         h ˆ= words[i] * (i + 1);
-     *     }
-     *     return (int) ((h >> 32) ˆ h);
-     * }
-     * 
- * - * Note that the hash code values change if the set of bits is altered. - *

- * Overrides the hashCode method of Object. - * - * @return a hash code value for this bit set. - */ - public int hashCode() - { - long h = 1234; - for (int i = wordsInUse; --i >= 0;) - h ^= words[i] * (i + 1); - - return (int) ((h >> 32) ^ h); - } - - /** - * Returns the number of bits of space actually in use by this - * BitSet to represent bit values. The maximum element in the - * set is the size - 1st element. - * - * @return the number of bits currently in this bit set. - */ - public int size() - { - return words.length * BITS_PER_WORD; - } - - /** - * Compares this object against the specified object. The result is - * true if and only if the argument is not null - * and is a Bitset object that has exactly the same set of - * bits set to true as this bit set. That is, for every - * nonnegative int index k, - * - *

-     * ((BitSet) obj).get(k) == this.get(k)
-     * 
- * - * must be true. The current sizes of the two bit sets are not compared. - *

- * Overrides the equals method of Object. - * - * @param obj - * the object to compare with. - * @return true if the objects are the same; - * false otherwise. - * @see java.util.BitSet#size() - */ - public boolean equals(Object obj) - { - if (!(obj instanceof BitSet)) - return false; - if (this == obj) - return true; - - BitSet set = (BitSet) obj; - - checkInvariants(); - set.checkInvariants(); - - if (wordsInUse != set.wordsInUse) - return false; - - // Check words in use by both BitSets - for (int i = 0; i < wordsInUse; i++) - if (words[i] != set.words[i]) - return false; - - return true; - } - - /** - * Cloning this BitSet produces a new BitSet - * that is equal to it. The clone of the bit set is another bit set that has - * exactly the same bits set to true as this bit set. - * - *

- * Overrides the clone method of Object. - * - * @return a clone of this bit set. - * @see java.util.BitSet#size() - */ - public Object clone() - { - if (!sizeIsSticky) - trimToSize(); - - try - { - BitSet result = (BitSet) super.clone(); - result.words = words.clone(); - result.checkInvariants(); - return result; - } - catch (CloneNotSupportedException e) - { - throw new InternalError(); - } - } - - /** - * Attempts to reduce internal storage used for the bits in this bit set. - * Calling this method may, but is not required to, affect the value - * returned by a subsequent call to the {@link #size()} method. - */ - private void trimToSize() - { - if (wordsInUse != words.length) - { - words = Arrays.copyOf(words, wordsInUse); - checkInvariants(); - } - } - - /** - * Save the state of the BitSet instance to a stream (i.e., - * serialize it). - */ - private void writeObject(ObjectOutputStream s) throws IOException - { - - checkInvariants(); - - if (!sizeIsSticky) - trimToSize(); - - ObjectOutputStream.PutField fields = s.putFields(); - fields.put("bits", words); - s.writeFields(); - } - - /** - * Reconstitute the BitSet instance from a stream (i.e., - * deserialize it). - */ - private void readObject(ObjectInputStream s) throws IOException, - ClassNotFoundException - { - - ObjectInputStream.GetField fields = s.readFields(); - words = (long[]) fields.get("bits", null); - - // Assume maximum length then find real length - // because recalculateWordsInUse assumes maintenance - // or reduction in logical size - wordsInUse = words.length; - recalculateWordsInUse(); - sizeIsSticky = (words.length > 0 && words[words.length - 1] == 0L); // heuristic - checkInvariants(); - } - - /** - * Returns a string representation of this bit set. For every index for - * which this BitSet contains a bit in the set state, the - * decimal representation of that index is included in the result. Such - * indices are listed in order from lowest to highest, separated by - * ", " (a comma and a space) and surrounded by braces, resulting in - * the usual mathematical notation for a set of integers. - *

- * Overrides the toString method of Object. - *

- * Example: - * - *

-     * BitSet drPepper = new BitSet();
-     * 
- * - * Now drPepper.toString() returns "{}". - *

- * - *

-     * drPepper.set(2);
-     * 
- * - * Now drPepper.toString() returns "{2}". - *

- * - *

-     * drPepper.set(4);
-     * drPepper.set(10);
-     * 
- * - * Now drPepper.toString() returns "{2, 4, 10}". - * - * @return a string representation of this bit set. - */ - public String toString() - { - checkInvariants(); - - int numBits = (wordsInUse > 128) ? cardinality() : wordsInUse - * BITS_PER_WORD; - StringBuilder b = new StringBuilder(6 * numBits + 2); - b.append('{'); - - int i = nextSetBit(0); - if (i != -1) - { - b.append(i); - for (i = nextSetBit(i + 1); i >= 0; i = nextSetBit(i + 1)) - { - int endOfRun = nextClearBit(i); - do - { - b.append(", ").append(i); - } - while (++i < endOfRun); - } - } - - b.append('}'); - return b.toString(); - } -} - -class BitSetSerializer implements ICompactSerializer -{ - public void serialize(BitSet bs, DataOutputStream dos) throws IOException - { - dos.writeInt(bs.wordsInUse()); - long[] words = bs.words(); - dos.writeInt(words.length); - for ( int i = 0; i < words.length; ++i ) - { - dos.writeLong(words[i]); - } - } - - public BitSet deserialize(DataInputStream dis) throws IOException - { - int wordsInUse = dis.readInt(); - int size = dis.readInt(); - long[] words = new long[size]; - for ( int i = 0; i < size; ++i ) - { - words[i] = dis.readLong(); - } - return new BitSet(wordsInUse, words); - } -} diff --git a/src/org/apache/cassandra/utils/BitSetSerializer.java b/src/org/apache/cassandra/utils/BitSetSerializer.java new file mode 100644 index 0000000000..5449df389c --- /dev/null +++ b/src/org/apache/cassandra/utils/BitSetSerializer.java @@ -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); + } + } +} diff --git a/src/org/apache/cassandra/utils/BloomFilter.java b/src/org/apache/cassandra/utils/BloomFilter.java index 01d09b814d..44a9604595 100644 --- a/src/org/apache/cassandra/utils/BloomFilter.java +++ b/src/org/apache/cassandra/utils/BloomFilter.java @@ -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 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); } } diff --git a/test/unit/org/apache/cassandra/io/DataInputBufferTest.java b/test/unit/org/apache/cassandra/io/DataInputBufferTest.java index b6bb7a681c..81b19aae7e 100644 --- a/test/unit/org/apache/cassandra/io/DataInputBufferTest.java +++ b/test/unit/org/apache/cassandra/io/DataInputBufferTest.java @@ -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();