Skip to content

Commit 7c16599

Browse files
jkosh44keith-turner
authored andcommitted
fixes #924 add byte[] compare to Bytes (#934)
Squashed commit of the following: commit dad21ce Author: Joseph Koshakow <koshy44@gmail.com> Date: Tue Oct 3 23:24:14 2017 -0400 Added the following methods: private int compareToUnchecked(byte[] bytes, int offset, int len){...} private boolean contentEqualsUnchecked(byte[] bytes, int offset, int len){...} Refactored the following methods: public final int compareTo(Bytes other){...} public int compareTo(byte[] bytes){...} public int compareTo(byte[] bytes, int offset, int len){...} public final boolean equals(Object other){...} public boolean contentEquals(byte[] bytes){...} public boolean contentEquals(byte[] bytes, int offset, int len){...} Added tests to test offsets greater than 0 commit b3038dd Author: Joseph Koshakow <koshy44@gmail.com> Date: Mon Oct 2 23:44:33 2017 -0400 Modified precondition for contentEquals(byte[] bytes, int offset, int len){...} commit ad5f06c Author: Joseph Koshakow <koshy44@gmail.com> Date: Mon Oct 2 23:37:04 2017 -0400 Added @SInCE 1.2.0 tags to new methods Added a Precondition.checkArgument to methods that take offset and len Added tests for different length Bytes and byte[] and empty Bytes and byte[] Added tests for invalid arguments commit d0033f5 Author: Joseph Koshakow <koshy44@gmail.com> Date: Mon Oct 2 20:17:32 2017 -0400 Created the following methods and corresponding unit tests for them: public boolean contentEquals(byte[] bytes){...} public boolean contentEquals(byte[] bytes, int offset, int len){...} public int compareTo(byte[] bytes){...} public int compareTo(byte[] bytes, int offset, int len){...} Refactored the following methods: public final int compareTo(Bytes other){...} public final boolean equals(Object other){...}
1 parent 69df4dd commit 7c16599

File tree

2 files changed

+165
-16
lines changed

2 files changed

+165
-16
lines changed

modules/api/src/main/java/org/apache/fluo/api/data/Bytes.java

+92-16
Original file line numberDiff line numberDiff line change
@@ -186,32 +186,81 @@ public void writeTo(OutputStream out) throws IOException {
186186
}
187187
}
188188

189+
/**
190+
* Compares this to the passed bytes, byte by byte, returning a negative, zero, or positive result
191+
* if the first sequence is less than, equal to, or greater than the second. The comparison is
192+
* performed starting with the first byte of each sequence, and proceeds until a pair of bytes
193+
* differs, or one sequence runs out of byte (is shorter). A shorter sequence is considered less
194+
* than a longer one.
195+
*
196+
* @return comparison result
197+
*/
198+
@Override
199+
public final int compareTo(Bytes other) {
200+
if (this == other) {
201+
return 0;
202+
} else {
203+
return compareToUnchecked(other.data, other.offset, other.length);
204+
}
205+
}
206+
189207
/**
190208
* Compares this to the passed bytes, byte by byte, returning a negative, zero, or positive result
191209
* if the first sequence is less than, equal to, or greater than the second. The comparison is
192210
* performed starting with the first byte of each sequence, and proceeds until a pair of bytes
193211
* differs, or one sequence runs out of byte (is shorter). A shorter sequence is considered less
194212
* than a longer one.
195213
*
214+
* @since 1.2.0
196215
* @return comparison result
197216
*/
198-
@Override
199-
public final int compareTo(Bytes other) {
200-
if (this == other) {
201-
return 0;
202-
} else if (this.length == this.data.length && other.length == other.data.length) {
203-
return UnsignedBytes.lexicographicalComparator().compare(this.data, other.data);
217+
public int compareTo(byte[] bytes) {
218+
return compareToUnchecked(bytes, 0, bytes.length);
219+
}
220+
221+
/**
222+
* Compares this to the passed bytes, byte by byte, returning a negative, zero, or positive result
223+
* if the first sequence is less than, equal to, or greater than the second. The comparison is
224+
* performed starting with the first byte of each sequence, and proceeds until a pair of bytes
225+
* differs, or one sequence runs out of byte (is shorter). A shorter sequence is considered less
226+
* than a longer one.
227+
*
228+
* This method checks the arguments passed to it.
229+
*
230+
* @since 1.2.0
231+
* @return comparison result
232+
*/
233+
public int compareTo(byte[] bytes, int offset, int len) {
234+
Preconditions.checkArgument(offset >= 0 && len >= 0 && offset + len <= bytes.length);
235+
return compareToUnchecked(bytes, offset, len);
236+
}
237+
238+
/**
239+
* Compares this to the passed bytes, byte by byte, returning a negative, zero, or positive result
240+
* if the first sequence is less than, equal to, or greater than the second. The comparison is
241+
* performed starting with the first byte of each sequence, and proceeds until a pair of bytes
242+
* differs, or one sequence runs out of byte (is shorter). A shorter sequence is considered less
243+
* than a longer one.
244+
*
245+
* This method does not check the arguments passed to it.
246+
*
247+
* @since 1.2.0
248+
* @return comparison result
249+
*/
250+
private int compareToUnchecked(byte[] bytes, int offset, int len) {
251+
if (this.length == this.data.length && len == bytes.length) {
252+
int res = UnsignedBytes.lexicographicalComparator().compare(this.data, bytes);
253+
return UnsignedBytes.lexicographicalComparator().compare(this.data, bytes);
204254
} else {
205-
int minLen = Math.min(this.length, other.length);
206-
for (int i = this.offset, j = other.offset; i < minLen; i++, j++) {
255+
int minLen = Math.min(this.length, len);
256+
for (int i = this.offset, j = offset; i < minLen; i++, j++) {
207257
int a = (this.data[i] & 0xff);
208-
int b = (other.data[j] & 0xff);
209-
258+
int b = (bytes[j] & 0xff);
210259
if (a != b) {
211260
return a - b;
212261
}
213262
}
214-
return this.length - other.length;
263+
return this.length - len;
215264
}
216265
}
217266

@@ -228,15 +277,42 @@ public final boolean equals(Object other) {
228277
if (other instanceof Bytes) {
229278
Bytes ob = (Bytes) other;
230279

231-
if (length != ob.length) {
232-
return false;
233-
}
234-
235-
return compareTo(ob) == 0;
280+
return contentEqualsUnchecked(ob.data, ob.offset, ob.length);
236281
}
237282
return false;
238283
}
239284

285+
/**
286+
* Returns true if this Bytes object equals another.
287+
* @since 1.2.0
288+
*/
289+
public boolean contentEquals(byte[] bytes) {
290+
return contentEqualsUnchecked(bytes, 0, bytes.length);
291+
}
292+
293+
/**
294+
* Returns true if this Bytes object equals another.
295+
* This method checks it's arguments.
296+
* @since 1.2.0
297+
*/
298+
public boolean contentEquals(byte[] bytes, int offset, int len) {
299+
Preconditions.checkArgument(len >= 0 && offset >= 0 && offset + len <= bytes.length);
300+
return contentEqualsUnchecked(bytes, offset, len);
301+
}
302+
303+
/**
304+
* Returns true if this Bytes object equals another.
305+
* This method doesn't check it's arguments.
306+
* @since 1.2.0
307+
*/
308+
private boolean contentEqualsUnchecked(byte[] bytes, int offset, int len) {
309+
if (length != len) {
310+
return false;
311+
}
312+
313+
return compareToUnchecked(bytes, offset, len) == 0;
314+
}
315+
240316
@Override
241317
public final int hashCode() {
242318
if (hashCode == 0) {

modules/api/src/test/java/org/apache/fluo/api/data/BytesTest.java

+73
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.io.ByteArrayOutputStream;
1919
import java.io.IOException;
20+
import java.lang.IllegalArgumentException;
2021
import java.nio.ByteBuffer;
2122
import java.nio.ReadOnlyBufferException;
2223
import java.nio.charset.StandardCharsets;
@@ -108,6 +109,30 @@ public void testPrefixSuffix() {
108109
Assert.assertFalse(b1.subSequence(0, 2).endsWith(b1));
109110
}
110111

112+
@Test
113+
public void testContentEquals() {
114+
Bytes b1 = Bytes.of("a");
115+
byte[] b2 = b1.toArray();
116+
byte[] b3 = Bytes.of("b").toArray();
117+
Bytes b5 = Bytes.of("qwerty");
118+
byte[] b6 = b5.toArray();
119+
Bytes b7 = Bytes.of("");
120+
byte[] b8 = b7.toArray();
121+
122+
123+
Assert.assertTrue(b1.contentEquals(b2));
124+
Assert.assertTrue(b5.contentEquals(b6));
125+
Assert.assertTrue(b7.contentEquals(b8));
126+
127+
Assert.assertFalse(b1.contentEquals(b3));
128+
Assert.assertFalse(b1.contentEquals(b6));
129+
Assert.assertFalse(b5.contentEquals(b2));
130+
Assert.assertFalse(b1.contentEquals(b8));
131+
Assert.assertFalse(b5.contentEquals(b8));
132+
Assert.assertFalse(b7.contentEquals(b2));
133+
Assert.assertFalse(b7.contentEquals(b6));
134+
}
135+
111136
@Test
112137
public void testCompare() {
113138
Bytes b1 = Bytes.of("a");
@@ -118,6 +143,54 @@ public void testCompare() {
118143
Assert.assertEquals(0, b1.compareTo(b3));
119144
Assert.assertEquals(0, b1.compareTo(b1));
120145
Assert.assertEquals(1, b1.compareTo(Bytes.EMPTY));
146+
147+
byte[] b1Arr = b1.toArray();
148+
byte[] b2Arr = b2.toArray();
149+
byte[] b3Arr = b3.toArray();
150+
Assert.assertEquals(-1, b1.compareTo(b2Arr));
151+
Assert.assertEquals(1, b2.compareTo(b1Arr));
152+
Assert.assertEquals(0, b1.compareTo(b3Arr));
153+
Assert.assertEquals(0, b1.compareTo(b1Arr));
154+
Assert.assertEquals(1, b1.compareTo(Bytes.EMPTY));
155+
156+
Bytes b4 = Bytes.of("abc");
157+
byte[] b4Arr = b4.toArray();
158+
Bytes b5 = Bytes.of("baz");
159+
byte[] b5Arr = b5.toArray();
160+
Bytes b6 = Bytes.of("ab");
161+
byte[] b7Arr = Bytes.of("dabc").toArray();
162+
163+
Assert.assertEquals(0, b4.compareTo(b4Arr, 0, 3));
164+
Assert.assertTrue(b4.compareTo(b4Arr, 1, 2) < 0);
165+
Assert.assertTrue(b5.compareTo(b4Arr, 1, 2) < 0);
166+
Assert.assertTrue(b5.compareTo(b5Arr, 1, 2) > 0);
167+
Assert.assertTrue(b4.compareTo(b4Arr, 0, 2) > 0);
168+
Assert.assertTrue(b6.compareTo(b7Arr, 1, 3) < 0);
169+
Assert.assertTrue(b6.compareTo(b1Arr) > 0);
170+
}
171+
172+
@Test(expected = IllegalArgumentException.class)
173+
public void testCompareNegOffset() {
174+
Bytes b1 = Bytes.of("abc");
175+
byte[] b2 = b1.toArray();
176+
177+
b1.compareTo(b2, -4, 1);
178+
}
179+
180+
@Test(expected = IllegalArgumentException.class)
181+
public void testCompareNegLen() {
182+
Bytes b1 = Bytes.of("abc");
183+
byte[] b2 = b1.toArray();
184+
185+
b1.compareTo(b2, 0, -1);
186+
}
187+
188+
@Test(expected = IllegalArgumentException.class)
189+
public void testCompareBadArgs() {
190+
Bytes b1 = Bytes.of("abc");
191+
byte[] b2 = b1.toArray();
192+
193+
b1.compareTo(b2, 2, 2);
121194
}
122195

123196
@Test

0 commit comments

Comments
 (0)