Updated Branches: refs/heads/master 75685ce8b -> 3a2e0a925
http://git-wip-us.apache.org/repos/asf/accumulo/blob/74c89324/core/src/main/java/org/apache/accumulo/core/data/Range.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/data/Range.java b/core/src/main/java/org/apache/accumulo/core/data/Range.java index 65873c3..adfd17b 100644 --- a/core/src/main/java/org/apache/accumulo/core/data/Range.java +++ b/core/src/main/java/org/apache/accumulo/core/data/Range.java @@ -30,10 +30,10 @@ import org.apache.hadoop.io.Text; import org.apache.hadoop.io.WritableComparable; /** - * This class is used to specify a range of Accumulo Keys. + * This class is used to specify a range of Accumulo keys. * + * @see Key */ - public class Range implements WritableComparable<Range> { private Key start; @@ -46,113 +46,96 @@ public class Range implements WritableComparable<Range> { /** * Creates a range that goes from negative to positive infinity */ - public Range() { this((Key) null, true, (Key) null, true); } /** - * Creates a range from startKey inclusive to endKey inclusive + * Creates a range from startKey inclusive to endKey inclusive. * - * @param startKey - * set this to null when negative infinity is needed - * @param endKey - * set this to null when positive infinity is needed + * @param startKey starting key; set to null for negative infinity + * @param endKey ending key; set to null for positive infinity + * @throws IllegalArgumentException if end key is before start key */ public Range(Key startKey, Key endKey) { this(startKey, true, endKey, true); } /** - * Creates a range that covers an entire row + * Creates a range that covers an entire row. * - * @param row - * set this to null to cover all rows + * @param row row to cover; set to null to cover all rows */ public Range(CharSequence row) { this(row, true, row, true); } /** - * Creates a range that covers an entire row + * Creates a range that covers an entire row. * - * @param row - * set this to null to cover all rows + * @param row row to cover; set to null to cover all rows */ public Range(Text row) { this(row, true, row, true); } /** - * Creates a range from startRow inclusive to endRow inclusive + * Creates a range from startRow inclusive to endRow inclusive. * - * @param startRow - * set this to null when negative infinity is needed - * @param endRow - * set this to null when positive infinity is needed + * @param startRow starting row; set to null for negative infinity + * @param endRow ending row; set to null for positive infinity + * @throws IllegalArgumentException if end row is before start row */ public Range(Text startRow, Text endRow) { this(startRow, true, endRow, true); } /** - * Creates a range from startRow inclusive to endRow inclusive + * Creates a range from startRow inclusive to endRow inclusive. * - * @param startRow - * set this to null when negative infinity is needed - * @param endRow - * set this to null when positive infinity is needed + * @param startRow starting row; set to null for negative infinity + * @param endRow ending row; set to null for positive infinity + * @throws IllegalArgumentException if end row is before start row */ public Range(CharSequence startRow, CharSequence endRow) { this(startRow, true, endRow, true); } /** - * Creates a range from startRow to endRow + * Creates a range from startRow to endRow. * - * @param startRow - * set this to null when negative infinity is needed - * @param startRowInclusive - * determines if the start row is skipped - * @param endRow - * set this to null when positive infinity is needed - * @param endRowInclusive - * determines if the endRow is included + * @param startRow starting row; set to null for negative infinity + * @param startRowInclusive true to include start row, false to skip + * @param endRow ending row; set to null for positive infinity + * @param endRowInclusive true to include start row, false to skip + * @throws IllegalArgumentException if end row is before start row */ - public Range(Text startRow, boolean startRowInclusive, Text endRow, boolean endRowInclusive) { this((startRow == null ? null : (startRowInclusive ? new Key(startRow) : new Key(startRow).followingKey(PartialKey.ROW))), true, (endRow == null ? null : (endRowInclusive ? new Key(endRow).followingKey(PartialKey.ROW) : new Key(endRow))), false); } /** - * Creates a range from startRow to endRow + * Creates a range from startRow to endRow. * - * @param startRow - * set this to null when negative infinity is needed - * @param startRowInclusive - * determines if the start row is skipped - * @param endRow - * set this to null when positive infinity is needed - * @param endRowInclusive - * determines if the endRow is included + * @param startRow starting row; set to null for negative infinity + * @param startRowInclusive true to include start row, false to skip + * @param endRow ending row; set to null for positive infinity + * @param endRowInclusive true to include start row, false to skip + * @throws IllegalArgumentException if end row is before start row */ - public Range(CharSequence startRow, boolean startRowInclusive, CharSequence endRow, boolean endRowInclusive) { this(startRow == null ? null : new Text(startRow.toString()), startRowInclusive, endRow == null ? null : new Text(endRow.toString()), endRowInclusive); } /** - * Creates a range from startKey to endKey + * Creates a range from startKey to endKey. * - * @param startKey - * set this to null when negative infinity is needed - * @param startKeyInclusive - * determines if the ranges includes the start key - * @param endKey - * set this to null when infinity is needed - * @param endKeyInclusive - * determines if the range includes the end key + * @param startKey starting key; set to null for negative infinity + * @param startKeyInclusive true to include start key, false to skip + * @param endKey ending key; set to null for positive infinity + * @param endKeyInclusive true to include start key, false to skip + * @throws IllegalArgumentException if end key is before start key */ public Range(Key startKey, boolean startKeyInclusive, Key endKey, boolean endKeyInclusive) { this.start = startKey; @@ -168,7 +151,9 @@ public class Range implements WritableComparable<Range> { } /** - * Copies a range + * Copies a range. + * + * @param range range to copy */ public Range(Range range) { this(range.start, range.startKeyInclusive, range.infiniteStartKey, range.stop, range.stopKeyInclusive, range.infiniteStopKey); @@ -233,6 +218,11 @@ public class Range implements WritableComparable<Range> { this.infiniteStopKey = infiniteStopKey; } + /** + * Creates a range from a Thrift range. + * + * @param trange Thrift range + */ public Range(TRange trange) { this(trange.start == null ? null : new Key(trange.start), trange.startKeyInclusive, trange.infiniteStartKey, trange.stop == null ? null : new Key(trange.stop), trange.stopKeyInclusive, trange.infiniteStopKey); @@ -242,7 +232,9 @@ public class Range implements WritableComparable<Range> { } /** - * @return the first key in the range, null if the key is infinite + * Gets the start key, or null if the start is negative infinity. + * + * @return start key */ public Key getStartKey() { if (infiniteStartKey) { @@ -252,8 +244,9 @@ public class Range implements WritableComparable<Range> { } /** - * - * @param key + * Determines if the given key is before the start key of this range. + * + * @param key key to check * @return true if the given key is before the range, otherwise false */ public boolean beforeStartKey(Key key) { @@ -267,9 +260,10 @@ public class Range implements WritableComparable<Range> { } /** - * @return the last key in the range, null if the end key is infinite + * Gets the ending key, or null if the end is positive infinity. + * + * @return ending key */ - public Key getEndKey() { if (infiniteStopKey) { return null; @@ -278,10 +272,11 @@ public class Range implements WritableComparable<Range> { } /** - * @param key + * Determines if the given key is after the ending key of this range. + * + * @param key key to check * @return true if the given key is after the range, otherwise false */ - public boolean afterEndKey(Key key) { if (infiniteStopKey) return false; @@ -306,14 +301,24 @@ public class Range implements WritableComparable<Range> { return false; } + /** + * Determines if this range equals another. + * + * @param otherRange range to compare + * @return true if ranges are equals, false otherwise + * @see #compareTo(Range) + */ public boolean equals(Range otherRange) { return compareTo(otherRange) == 0; } /** - * Compares this range to another range. Compares in the order start key, inclusiveness of start key, end key, inclusiveness of end key. Infinite keys sort + * Compares this range to another range. Compares in order: start key, inclusiveness of start key, end key, inclusiveness of end key. Infinite keys sort * first, and non-infinite keys are compared with {@link Key#compareTo(Key)}. Inclusive sorts before non-inclusive. + * + * @param o range to compare + * @return comparison result */ public int compareTo(Range o) { int comp; @@ -356,31 +361,31 @@ public class Range implements WritableComparable<Range> { } /** - * - * @param key - * @return true if the given key falls within the range + * Determines if the given key falls within this range. + * + * @param key key to consider + * @return true if the given key falls within the range, false otherwise */ public boolean contains(Key key) { return !beforeStartKey(key) && !afterEndKey(key); } /** - * Takes a collection on range and merges overlapping and adjacent ranges. For example given the following input + * Merges overlapping and adjacent ranges. For example given the following input: * * <pre> * [a,c], (c, d], (g,m), (j,t] * </pre> * - * the following ranges would be returned + * the following ranges would be returned: * * <pre> * [a,d], (g,t] * </pre> * - * @param ranges + * @param ranges to merge * @return list of merged ranges */ - public static List<Range> mergeOverlapping(Collection<Range> ranges) { if (ranges.size() == 0) return Collections.emptyList(); @@ -447,24 +452,24 @@ public class Range implements WritableComparable<Range> { * System.out.println(range3.equals(new Range("c", "f"))); * </pre> * - * @param range - * @return the intersection - * @throws IllegalArgumentException - * if ranges does not overlap + * @param range range to clip to + * @return the intersection of this range and the given range + * @throws IllegalArgumentException if ranges does not overlap */ - public Range clip(Range range) { return clip(range, false); } /** - * Same as other clip function except if gives the option to return null of the ranges do not overlap instead of throwing an exception. + * Creates a range which represents the intersection of this range and the passed in range. Unlike {@link #clip(Range)}, + * this method can optionally return null if the ranges do not overlap, instead of throwing an exception. The returnNullIfDisjoint parameter controls this + * behavior. * + * @param range range to clip to + * @param returnNullIfDisjoint true to return null if ranges are disjoint, false to throw an exception + * @return the intersection of this range and the given range, or null if ranges do not overlap and returnNullIfDisjoint is true + * @throws IllegalArgumentException if ranges does not overlap and returnNullIfDisjoint is false * @see Range#clip(Range) - * @param range - * @param returnNullIfDisjoint - * If the ranges do not overlap and true is passed, then null is returned otherwise an exception is thrown. - * @return the intersection */ public Range clip(Range range, boolean returnNullIfDisjoint) { @@ -509,17 +514,14 @@ public class Range implements WritableComparable<Range> { } /** - * Creates a new range that is bounded by the columns passed in. The stary key in the returned range will have a column >= to the minimum column. The end key + * Creates a new range that is bounded by the columns passed in. The start key in the returned range will have a column >= to the minimum column. The end key * in the returned range will have a column <= the max column. * - * - * @param min - * @param max + * @param min minimum column + * @param max maximum column * @return a column bounded range - * @throws IllegalArgumentException - * if min > max + * @throws IllegalArgumentException if the minimum column compares greater than the maximum column */ - public Range bound(Column min, Column max) { if (min.compareTo(max) > 0) { @@ -631,45 +633,67 @@ public class Range implements WritableComparable<Range> { out.writeBoolean(stopKeyInclusive); } + /** + * Gets whether the start key of this range is inclusive. + * + * @return true if start key is inclusive + */ public boolean isStartKeyInclusive() { return startKeyInclusive; } + /** + * Gets whether the end key of this range is inclusive. + * + * @return true if end key is inclusive + */ public boolean isEndKeyInclusive() { return stopKeyInclusive; } + /** + * Converts this range to Thrift. + * + * @return Thrift range + */ public TRange toThrift() { return new TRange(start == null ? null : start.toThrift(), stop == null ? null : stop.toThrift(), startKeyInclusive, stopKeyInclusive, infiniteStartKey, infiniteStopKey); } + /** + * Gets whether the start key is negative infinity. + * + * @return true if start key is negative infinity + */ public boolean isInfiniteStartKey() { return infiniteStartKey; } + /** + * Gets whether the end key is positive infinity. + * + * @return true if end key is positive infinity + */ public boolean isInfiniteStopKey() { return infiniteStopKey; } /** - * Creates a range that covers an exact row Returns the same Range as new Range(row) + * Creates a range that covers an exact row. Returns the same Range as + * {@link #Range(Text)}. * - * @param row - * all keys in the range will have this row + * @param row row to cover; set to null to cover all rows */ public static Range exact(Text row) { return new Range(row); } /** - * Creates a range that covers an exact row and column family - * - * @param row - * all keys in the range will have this row + * Creates a range that covers an exact row and column family. * - * @param cf - * all keys in the range will have this column family + * @param row row row to cover + * @param cf column family to cover */ public static Range exact(Text row, Text cf) { Key startKey = new Key(row, cf); @@ -677,16 +701,11 @@ public class Range implements WritableComparable<Range> { } /** - * Creates a range that covers an exact row, column family, and column qualifier + * Creates a range that covers an exact row, column family, and column qualifier. * - * @param row - * all keys in the range will have this row - * - * @param cf - * all keys in the range will have this column family - * - * @param cq - * all keys in the range will have this column qualifier + * @param row row row to cover + * @param cf column family to cover + * @param cq column qualifier to cover */ public static Range exact(Text row, Text cf, Text cq) { Key startKey = new Key(row, cf, cq); @@ -694,19 +713,12 @@ public class Range implements WritableComparable<Range> { } /** - * Creates a range that covers an exact row, column family, column qualifier, and visibility - * - * @param row - * all keys in the range will have this row - * - * @param cf - * all keys in the range will have this column family - * - * @param cq - * all keys in the range will have this column qualifier + * Creates a range that covers an exact row, column family, column qualifier, and column visibility. * - * @param cv - * all keys in the range will have this column visibility + * @param row row row to cover + * @param cf column family to cover + * @param cq column qualifier to cover + * @param cv column visibility to cover */ public static Range exact(Text row, Text cf, Text cq, Text cv) { Key startKey = new Key(row, cf, cq, cv); @@ -714,22 +726,13 @@ public class Range implements WritableComparable<Range> { } /** - * Creates a range that covers an exact row, column family, column qualifier, visibility, and timestamp - * - * @param row - * all keys in the range will have this row - * - * @param cf - * all keys in the range will have this column family - * - * @param cq - * all keys in the range will have this column qualifier - * - * @param cv - * all keys in the range will have this column visibility + * Creates a range that covers an exact row, column family, column qualifier, column visibility, and timestamp. * - * @param ts - * all keys in the range will have this timestamp + * @param row row row to cover + * @param cf column family to cover + * @param cq column qualifier to cover + * @param cv column visibility to cover + * @param ts timestamp to cover */ public static Range exact(Text row, Text cf, Text cq, Text cv, long ts) { Key startKey = new Key(row, cf, cq, cv, ts); @@ -737,9 +740,11 @@ public class Range implements WritableComparable<Range> { } /** - * Returns a Text that sorts just after all Texts beginning with a prefix + * Returns a Text that sorts just after all Texts beginning with a prefix. * - * @param prefix + * @param prefix to follow + * @return prefix that immediately follows the given prefix when sorted, or + * null if no prefix can follow (i.e., the string is all 0xff bytes) */ public static Text followingPrefix(Text prefix) { byte[] prefixBytes = prefix.getBytes(); @@ -761,10 +766,9 @@ public class Range implements WritableComparable<Range> { } /** - * Returns a Range that covers all rows beginning with a prefix + * Returns a Range that covers all rows beginning with a prefix. * - * @param rowPrefix - * all keys in the range will have rows that begin with this prefix + * @param rowPrefix prefix of rows to cover */ public static Range prefix(Text rowPrefix) { Text fp = followingPrefix(rowPrefix); @@ -772,13 +776,10 @@ public class Range implements WritableComparable<Range> { } /** - * Returns a Range that covers all column families beginning with a prefix within a given row + * Returns a Range that covers all column families beginning with a prefix within a given row. * - * @param row - * all keys in the range will have this row - * - * @param cfPrefix - * all keys in the range will have column families that begin with this prefix + * @param row row to cover + * @param cfPrefix prefix of column families to cover */ public static Range prefix(Text row, Text cfPrefix) { Text fp = followingPrefix(cfPrefix); @@ -786,16 +787,11 @@ public class Range implements WritableComparable<Range> { } /** - * Returns a Range that covers all column qualifiers beginning with a prefix within a given row and column family - * - * @param row - * all keys in the range will have this row + * Returns a Range that covers all column qualifiers beginning with a prefix within a given row and column family. * - * @param cf - * all keys in the range will have this column family - * - * @param cqPrefix - * all keys in the range will have column qualifiers that begin with this prefix + * @param row row to cover + * @param cf column family to cover + * @param cqPrefix prefix of column qualifiers to cover */ public static Range prefix(Text row, Text cf, Text cqPrefix) { Text fp = followingPrefix(cqPrefix); @@ -803,19 +799,12 @@ public class Range implements WritableComparable<Range> { } /** - * Returns a Range that covers all column visibilities beginning with a prefix within a given row, column family, and column qualifier - * - * @param row - * all keys in the range will have this row + * Returns a Range that covers all column visibilities beginning with a prefix within a given row, column family, and column qualifier. * - * @param cf - * all keys in the range will have this column family - * - * @param cq - * all keys in the range will have this column qualifier - * - * @param cvPrefix - * all keys in the range will have column visibilities that begin with this prefix + * @param row row to cover + * @param cf column family to cover + * @param cq column qualifier to cover + * @param cvPrefix prefix of column visibilities to cover */ public static Range prefix(Text row, Text cf, Text cq, Text cvPrefix) { Text fp = followingPrefix(cvPrefix); @@ -824,81 +813,104 @@ public class Range implements WritableComparable<Range> { } /** - * Creates a range that covers an exact row + * Creates a range that covers an exact row. * - * @see Range#exact(Text) + * @param row row to cover; set to null to cover all rows + * @see #exact(Text) */ public static Range exact(CharSequence row) { return Range.exact(new Text(row.toString())); } /** - * Creates a range that covers an exact row and column family + * Creates a range that covers an exact row and column family. * - * @see Range#exact(Text, Text) + * @param row row row to cover + * @param cf column family to cover + * @see #exact(Text, Text) */ public static Range exact(CharSequence row, CharSequence cf) { return Range.exact(new Text(row.toString()), new Text(cf.toString())); } /** - * Creates a range that covers an exact row, column family, and column qualifier + * Creates a range that covers an exact row, column family, and column qualifier. * - * @see Range#exact(Text, Text, Text) + * @param row row row to cover + * @param cf column family to cover + * @param cq column qualifier to cover + * @see #exact(Text, Text, Text) */ public static Range exact(CharSequence row, CharSequence cf, CharSequence cq) { return Range.exact(new Text(row.toString()), new Text(cf.toString()), new Text(cq.toString())); } /** - * Creates a range that covers an exact row, column family, column qualifier, and visibility + * Creates a range that covers an exact row, column family, column qualifier, and column visibility. * - * @see Range#exact(Text, Text, Text, Text) + * @param row row row to cover + * @param cf column family to cover + * @param cq column qualifier to cover + * @param cv column visibility to cover + * @see #exact(Text, Text, Text, Text) */ public static Range exact(CharSequence row, CharSequence cf, CharSequence cq, CharSequence cv) { return Range.exact(new Text(row.toString()), new Text(cf.toString()), new Text(cq.toString()), new Text(cv.toString())); } /** - * Creates a range that covers an exact row, column family, column qualifier, visibility, and timestamp + * Creates a range that covers an exact row, column family, column qualifier, column visibility, and timestamp. * - * @see Range#exact(Text, Text, Text, Text, long) + * @param row row row to cover + * @param cf column family to cover + * @param cq column qualifier to cover + * @param cv column visibility to cover + * @param ts timestamp to cover + * @see #exact(Text, Text, Text, Text, long) */ public static Range exact(CharSequence row, CharSequence cf, CharSequence cq, CharSequence cv, long ts) { return Range.exact(new Text(row.toString()), new Text(cf.toString()), new Text(cq.toString()), new Text(cv.toString()), ts); } - /** - * Returns a Range that covers all rows beginning with a prefix + * Returns a Range that covers all rows beginning with a prefix. * - * @see Range#prefix(Text) + * @param rowPrefix prefix of rows to cover + * @see #prefix(Text) */ public static Range prefix(CharSequence rowPrefix) { return Range.prefix(new Text(rowPrefix.toString())); } /** - * Returns a Range that covers all column families beginning with a prefix within a given row + * Returns a Range that covers all column families beginning with a prefix within a given row. * - * @see Range#prefix(Text, Text) + * @param row row to cover + * @param cfPrefix prefix of column families to cover + * @see #prefix(Text, Text) */ public static Range prefix(CharSequence row, CharSequence cfPrefix) { return Range.prefix(new Text(row.toString()), new Text(cfPrefix.toString())); } /** - * Returns a Range that covers all column qualifiers beginning with a prefix within a given row and column family + * Returns a Range that covers all column qualifiers beginning with a prefix within a given row and column family. * - * @see Range#prefix(Text, Text, Text) + * @param row row to cover + * @param cf column family to cover + * @param cqPrefix prefix of column qualifiers to cover + * @see #prefix(Text, Text, Text) */ public static Range prefix(CharSequence row, CharSequence cf, CharSequence cqPrefix) { return Range.prefix(new Text(row.toString()), new Text(cf.toString()), new Text(cqPrefix.toString())); } - /** - * Returns a Range that covers all column visibilities beginning with a prefix within a given row, column family, and column qualifier + * Returns a Range that covers all column visibilities beginning with a prefix within a given row, column family, and column qualifier. * - * @see Range#prefix(Text, Text, Text, Text) + * @param row row to cover + * @param cf column family to cover + * @param cq column qualifier to cover + * @param cvPrefix prefix of column visibilities to cover + * @see #prefix(Text, Text, Text, Text) */ public static Range prefix(CharSequence row, CharSequence cf, CharSequence cq, CharSequence cvPrefix) { return Range.prefix(new Text(row.toString()), new Text(cf.toString()), new Text(cq.toString()), new Text(cvPrefix.toString())); http://git-wip-us.apache.org/repos/asf/accumulo/blob/74c89324/core/src/main/java/org/apache/accumulo/core/data/Value.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/data/Value.java b/core/src/main/java/org/apache/accumulo/core/data/Value.java index 39ebbd0..ec07411 100644 --- a/core/src/main/java/org/apache/accumulo/core/data/Value.java +++ b/core/src/main/java/org/apache/accumulo/core/data/Value.java @@ -32,42 +32,59 @@ import org.apache.hadoop.io.WritableComparator; /** * A byte sequence that is usable as a key or value. Based on {@link org.apache.hadoop.io.BytesWritable} only this class is NOT resizable and DOES NOT - * distinguish between the size of the sequence and the current capacity as {@link org.apache.hadoop.io.BytesWritable} does. Hence its comparatively + * distinguish between the size of the sequence and the current capacity as {@link org.apache.hadoop.io.BytesWritable} does. Hence it is comparatively * 'immutable'. */ public class Value implements WritableComparable<Object> { protected byte[] value; /** - * Create a zero-size sequence. + * Creates a zero-size sequence. */ public Value() { super(); } /** - * Create a Value using the byte array as the initial value. + * Creates a Value using a byte array as the initial value. The given byte + * array is used directly as the backing array, so later changes made to the + * array reflect into the new Value. * - * @param bytes - * This array becomes the backing storage for the object. + * @param bytes bytes of value */ - public Value(byte[] bytes) { this(bytes, false); } + /** + * Creates a Value using the bytes in a buffer as the initial value. Makes + * a defensive copy. + * + * @param bytes bytes of value + */ public Value(ByteBuffer bytes) { this(toBytes(bytes), false); } /** * @deprecated A copy of the bytes in the buffer is always made. Use {@link #Value(ByteBuffer)} instead. + * + * @param bytes bytes of value + * @param copy false to use the backing array of the buffer directly as the + * backing array, true to force a copy */ @Deprecated public Value(ByteBuffer bytes, boolean copy) { this(toBytes(bytes), false); } + /** + * Creates a Value using a byte array as the initial value. + * + * @param bytes bytes of value + * @param copy false to use the given byte array directly as the backing + * array, true to force a copy + */ public Value(byte[] bytes, boolean copy) { if (!copy) { this.value = bytes; @@ -79,24 +96,22 @@ public class Value implements WritableComparable<Object> { } /** - * Set the new Value to a copy of the contents of the passed <code>ibw</code>. + * Creates a new Value based on another. * - * @param ibw - * the value to set this Value to. + * @param ibw original Value */ public Value(final Value ibw) { this(ibw.get(), 0, ibw.getSize()); } /** - * Set the value to a copy of the given byte range + * Creates a Value based on a range in a byte array. A copy of the bytes is + * always made. * - * @param newData - * the new values to copy in - * @param offset - * the offset in newData to start at - * @param length - * the number of bytes to copy + * @param newData byte array containing value bytes + * @param offset the offset in newData to start with for valye bytes + * @param length the number of bytes in the value + * @throws IndexOutOfBoundsException if offset or length are invalid */ public Value(final byte[] newData, final int offset, final int length) { this.value = new byte[length]; @@ -104,9 +119,11 @@ public class Value implements WritableComparable<Object> { } /** - * Get the data from the BytesWritable. + * Gets the byte data of this value. * - * @return The data is only valid between 0 and getSize() - 1. + * @return value bytes + * @throws IllegalStateException if this object is uninitialized because it + * was not read correctly from a data stream */ public byte[] get() { if (this.value == null) { @@ -116,17 +133,20 @@ public class Value implements WritableComparable<Object> { } /** - * @param b - * Use passed bytes as backing array for this instance. + * Sets the byte data of this value. The given byte array is used directly as + * the backing array, so later changes made to the array reflect into this + * Value. + * + * @param b bytes of value */ public void set(final byte[] b) { this.value = b; } /** - * - * @param b - * copy bytes + * Sets the byte data of this value. The given byte array is copied. + * + * @param b bytes of value */ public void copy(byte[] b) { this.value = new byte[b.length]; @@ -134,7 +154,11 @@ public class Value implements WritableComparable<Object> { } /** - * @return the current size of the buffer. + * Gets the size of this value. + * + * @return size in bytes + * @throws IllegalStateException if this object is uninitialized because it + * was not read correctly from a data stream */ public int getSize() { if (this.value == null) { @@ -222,6 +246,10 @@ public class Value implements WritableComparable<Object> { } /** + * Converts a list of byte arrays to a two-dimensional array. + * + * @param array list of byte arrays + * @return two-dimensional byte array containing one given byte array per row */ public static byte[][] toArray(final List<byte[]> array) { // List#toArray doesn't work on lists of byte []. http://git-wip-us.apache.org/repos/asf/accumulo/blob/74c89324/core/src/main/java/org/apache/accumulo/core/data/doc-files/mutation-serialization.html ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/data/doc-files/mutation-serialization.html b/core/src/main/java/org/apache/accumulo/core/data/doc-files/mutation-serialization.html new file mode 100644 index 0000000..d4d5ed3 --- /dev/null +++ b/core/src/main/java/org/apache/accumulo/core/data/doc-files/mutation-serialization.html @@ -0,0 +1,196 @@ +<html> +<head> + <title>Serialization Formats for Mutation</title> +<!-- + 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. +--> +</head> +<body> + <p> + The <code>Mutation</code> class supports two serialization formats. + While it only currently serializes to the newer version 2 format, it + can read both version 1 and version 2 serialized forms. + </p> + + <h2>Version 1 Format</h2> + <p> + Mutation data serialized in the version 1 format has the following + layout. + </p> + <table> + <tr> + <th>data location</th> + <th>description</th> + </tr> + <tr> + <td>bytes 0 through 3</td> + <td>4-byte integer for length of row ID</td> + </tr> + <tr> + <td>next <i>n</i> bytes</td> + <td>row ID</td> + </tr> + <tr> + <td>next integer</td> + <td>data length</td> + </tr> + <tr> + <td>next <i>n</i> bytes</td> + <td>data (see below)</td> + </tr> + <tr> + <td>next integer</td> + <td>number of entries</td> + </tr> + <tr> + <td>next boolean</td> + <td>values present flag</td> + </tr> + <tr> + <td>next integer</td> + <td>number of values (only if values present flag is set)</td> + </tr> + <tr> + <td>next <i>n</i> sets of integers and byte arrays</td> + <td><i>n</i> value lengths and value data bytes (only if values + present flag is set)</td> + </tr> + </table> + <p> + The "data" block noted above has the following layout for each entry. + </p> + <table> + <tr> + <td>first integer and byte array</td> + <td>column family length and bytes</td> + </tr> + <tr> + <td>next integer and byte array</td> + <td>column qualifier length and bytes</td> + </tr> + <tr> + <td>next integer and byte array</td> + <td>column visibility length and bytes</td> + </tr> + <tr> + <td>next boolean</td> + <td>has timestamp flag</td> + </tr> + <tr> + <td>next long</td> + <td>timestamp</td> + </tr> + <tr> + <td>next boolean</td> + <td>deleted flag</td> + </tr> + <tr> + <td>next integer</td> + <td>value length; if negative, value bytes are the same as those + for already-read value (-length - 1)</td> + </tr> + <tr> + <td>next <i>n</i> bytes</td> + <td>value bytes (only if value length is non-negative)</td> + </tr> + </table> + + <h2>Version 2 Format</h2> + <p> + Mutation data serialized in the version 2 format has the following + layout. This format uses variable length encoding for integers and + longs. + </p> + <table> + <tr> + <th>data location</th> + <th>description</th> + </tr> + <tr> + <td>byte 0</td> + <td>control byte: top bit = 1 for version 2; bottom bit = + values present flag</td> + </tr> + <tr> + <td>next integer + <td>length of row ID</td> + </tr> + <tr> + <td>next <i>n</i> bytes</td> + <td>row ID</td> + </tr> + <tr> + <td>next integer</td> + <td>data length</td> + </tr> + <tr> + <td>next <i>n</i> bytes</td> + <td>data (see below)</td> + </tr> + <tr> + <td>next integer</td> + <td>number of entries</td> + </tr> + <tr> + <td>next integer</td> + <td>number of values (only if values present flag is set)</td> + </tr> + <tr> + <td>next <i>n</i> sets of integers and byte arrays</td> + <td><i>n</i> value lengths and value data bytes (only if values + present flag is set)</td> + </tr> + </table> + <p> + The "data" block noted above has the following layout for each entry. + </p> + <table> + <tr> + <td>first long and byte array</td> + <td>column family length and bytes</td> + </tr> + <tr> + <td>next long and byte array</td> + <td>column qualifier length and bytes</td> + </tr> + <tr> + <td>next long and byte array</td> + <td>column visibility length and bytes</td> + </tr> + <tr> + <td>next boolean</td> + <td>has timestamp flag</td> + </tr> + <tr> + <td>next long</td> + <td>timestamp (only present if timestamp flag is set)</td> + </tr> + <tr> + <td>next boolean</td> + <td>deleted flag</td> + </tr> + <tr> + <td>next long</td> + <td>value length; if negative, value bytes are the same as those + for already-read value (-length - 1)</td> + </tr> + <tr> + <td>next <i>n</i> bytes</td> + <td>value bytes (only if value length is non-negative)</td> + </tr> + </table> +</body> +</html> http://git-wip-us.apache.org/repos/asf/accumulo/blob/74c89324/core/src/main/java/org/apache/accumulo/core/util/UnsynchronizedBuffer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/util/UnsynchronizedBuffer.java b/core/src/main/java/org/apache/accumulo/core/util/UnsynchronizedBuffer.java index b640581..36aa473 100644 --- a/core/src/main/java/org/apache/accumulo/core/util/UnsynchronizedBuffer.java +++ b/core/src/main/java/org/apache/accumulo/core/util/UnsynchronizedBuffer.java @@ -21,20 +21,32 @@ import java.nio.ByteBuffer; import org.apache.hadoop.io.WritableUtils; /** - * + * A utility class for reading and writing bytes to byte buffers without + * synchronization. */ public class UnsynchronizedBuffer { // created this little class instead of using ByteArrayOutput stream and DataOutputStream // because both are synchronized... lots of small syncs slow things down + /** + * A byte buffer writer. + */ public static class Writer { int offset = 0; byte data[]; + /** + * Creates a new writer. + */ public Writer() { data = new byte[64]; } + /** + * Creates a new writer. + * + * @param initialCapacity initial byte capacity + */ public Writer(int initialCapacity) { data = new byte[initialCapacity]; } @@ -50,12 +62,25 @@ public class UnsynchronizedBuffer { } + /** + * Adds bytes to this writer's buffer. + * + * @param bytes byte array + * @param off offset into array to start copying bytes + * @param length number of bytes to add + * @throws IndexOutOfBoundsException if off or length are invalid + */ public void add(byte[] bytes, int off, int length) { reserve(length); System.arraycopy(bytes, off, data, offset, length); offset += length; } + /** + * Adds a Boolean value to this writer's buffer. + * + * @param b Boolean value + */ public void add(boolean b) { reserve(1); if (b) @@ -64,20 +89,46 @@ public class UnsynchronizedBuffer { data[offset++] = 0; } + /** + * Gets (a copy of) the contents of this writer's buffer. + * + * @return byte buffer contents + */ public byte[] toArray() { byte ret[] = new byte[offset]; System.arraycopy(data, 0, ret, 0, offset); return ret; } + /** + * Gets a <code>ByteBuffer</code> wrapped around this writer's buffer. + * + * @return byte buffer + */ public ByteBuffer toByteBuffer() { return ByteBuffer.wrap(data, 0, offset); } + /** + * Adds an integer value to this writer's buffer. The integer is encoded as + * a variable-length list of bytes. See {@link #writeVLong(long)} for a + * description of the encoding. + * + * @param i integer value + */ public void writeVInt(int i) { writeVLong(i); } + /** + * Adds a long value to this writer's buffer. The long is encoded as + * a variable-length list of bytes. For a description of the encoding + * scheme, see <code>WritableUtils.writeVLong()</code> in the Hadoop + * API. + * [<a href="http://hadoop.apache.org/docs/stable/api/org/apache/hadoop/io/WritableUtils.html#writeVLong%28java.io.DataOutput,%20long%29">link</a>] + * + * @param i long value + */ public void writeVLong(long i) { reserve(9); if (i >= -112 && i <= 127) { @@ -109,14 +160,27 @@ public class UnsynchronizedBuffer { } } + /** + * A byte buffer reader. + */ public static class Reader { int offset; byte data[]; + /** + * Creates a new reader. + * + * @param b bytes to read + */ public Reader(byte b[]) { this.data = b; } + /** + * Creates a new reader. + * + * @param buffer byte buffer containing bytes to read + */ public Reader(ByteBuffer buffer) { if (buffer.hasArray()) { offset = buffer.arrayOffset(); @@ -127,28 +191,60 @@ public class UnsynchronizedBuffer { } } + /** + * Reads an integer value from this reader's buffer. + * + * @return integer value + */ public int readInt() { return (data[offset++] << 24) + ((data[offset++] & 255) << 16) + ((data[offset++] & 255) << 8) + ((data[offset++] & 255) << 0); } + /** + * Reads a long value from this reader's buffer. + * + * @return long value + */ public long readLong() { return (((long) data[offset++] << 56) + ((long) (data[offset++] & 255) << 48) + ((long) (data[offset++] & 255) << 40) + ((long) (data[offset++] & 255) << 32) + ((long) (data[offset++] & 255) << 24) + ((data[offset++] & 255) << 16) + ((data[offset++] & 255) << 8) + ((data[offset++] & 255) << 0)); } + /** + * Reads bytes from this reader's buffer, filling the given byte array. + * + * @param b byte array to fill + */ public void readBytes(byte b[]) { System.arraycopy(data, offset, b, 0, b.length); offset += b.length; } + /** + * Reads a Boolean value from this reader's buffer. + * + * @return Boolean value + */ public boolean readBoolean() { return (data[offset++] == 1); } + /** + * Reads an integer value from this reader's buffer, assuming the integer + * was encoded as a variable-length list of bytes. + * + * @return integer value + */ public int readVInt() { return (int) readVLong(); } + /** + * Reads a long value from this reader's buffer, assuming the long + * was encoded as a variable-length list of bytes. + * + * @return long value + */ public long readVLong() { byte firstByte = data[offset++]; int len = WritableUtils.decodeVIntSize(firstByte); @@ -167,7 +263,10 @@ public class UnsynchronizedBuffer { /** * Determines what next array size should be by rounding up to next power of two. - * + * + * @param i current array size + * @return next array size + * @throws IllegalArgumentException if i is negative */ public static int nextArraySize(int i) { if (i < 0)
