Skip to content

Commit e958c7c

Browse files
committed
Added putValue and getValue to allow for optimal compression.
1 parent 6eff9cb commit e958c7c

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<groupId>com.github.jhg023</groupId>
1414
<artifactId>BitBuffer</artifactId>
15-
<version>1.0.0</version>
15+
<version>1.0.1</version>
1616
<packaging>jar</packaging>
1717

1818
<name>BitBuffer</name>

src/main/java/bitbuffer/BitBuffer.java

+48-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,32 @@ public BitBuffer putShort(int s, ByteOrder order) {
285285
var value = (short) s;
286286
return putBits(order == ByteOrder.BIG_ENDIAN ? Short.reverseBytes(value) : value, Short.SIZE);
287287
}
288-
288+
289+
/**
290+
* Given the specified {@code maxValue}, this method writes the specified value to this {@link BitBuffer}
291+
* using the optimal amount of bits, thus providing free compression.
292+
*
293+
* @param value the value to write to this {@link BitBuffer}.
294+
* @param maxValue the maximum possible value that {@code value} can be; a lower {@code maxValue} results in a
295+
* better compression ratio.
296+
* @return this {@link BitBuffer} to allow for the convenience of method-chaining.
297+
* @throws IllegalArgumentException if {@code maxValue} is negative or if the absolute value of {@code value} is
298+
* greater than {@code maxValue}.
299+
*/
300+
public BitBuffer putValue(long value, long maxValue) throws IllegalArgumentException {
301+
if (maxValue < 0) {
302+
throw new IllegalArgumentException("maxValue must be positive!");
303+
}
304+
305+
if (Math.abs(value) > maxValue) {
306+
throw new IllegalArgumentException("value must be less than or equal to maxValue!");
307+
}
308+
309+
int numBits = Long.SIZE - Long.numberOfLeadingZeros(maxValue) + 1;
310+
311+
return putBits(value, numBits);
312+
}
313+
289314
/**
290315
* After a series of relative {@code put} operations, flip the <i>cache</i> to prepare for a series of relative
291316
* {@code get} operations.
@@ -499,6 +524,28 @@ public short getShort(ByteOrder order) {
499524
return order == ByteOrder.BIG_ENDIAN ? Short.reverseBytes(value) : value;
500525
}
501526

527+
/**
528+
* Given the specified {@code maxValue}, this method reads a value from this {@link BitBuffer} using the optimal
529+
* amount of bits, thus providing free compression.
530+
* <br><br>
531+
* The value of {@code maxValue} should be the same as what was used when calling {@link #putValue(long, long)}.
532+
*
533+
* @param maxValue the maximum possible value that the value being read can be; a lower {@code maxValue} results
534+
* in a better compression ratio.
535+
* @return the value read from this {@link BitBuffer} as a {@code long}.
536+
* @throws IllegalArgumentException if {@code maxValue} is negative.
537+
*/
538+
public long getValue(long maxValue) {
539+
if (maxValue < 0) {
540+
throw new IllegalArgumentException("maxValue must be positive!");
541+
}
542+
543+
int numBits = Long.SIZE - Long.numberOfLeadingZeros(maxValue) + 1;
544+
int unused = Long.SIZE - numBits;
545+
546+
return getBits(numBits) << unused >> unused;
547+
}
548+
502549
/**
503550
* Gets the capacity of the backing {@link ByteBuffer}.
504551
*

src/test/java/bitbuffer/BitBufferTests.java

+9
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ void testReadDoubleLittleEndian(double value) {
115115
.flip().getDouble(ByteOrder.LITTLE_ENDIAN));
116116
}
117117

118+
@ParameterizedTest
119+
@ValueSource(longs = {Long.MIN_VALUE, -10L, -1L, 0L, 1L, 10L, Long.MAX_VALUE})
120+
void testReadValue(long value) {
121+
Assertions.assertEquals(value, buffer.putValue(value, Long.MAX_VALUE)
122+
.flip().getValue(Long.MAX_VALUE));
123+
}
124+
118125
/**
119126
* This method tests whether the {@code long} cache is cleared properly.
120127
*/
@@ -124,6 +131,8 @@ void testDoubleFlip() {
124131
Assertions.assertEquals(42, buffer.getInt());
125132
buffer.flip();
126133
buffer.flip();
134+
buffer.flip();
135+
buffer.flip();
127136
Assertions.assertEquals(26, buffer.getInt());
128137
}
129138

0 commit comments

Comments
 (0)