forked from burmanm/gorilla-tsc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
405543d
commit 99eeb0a
Showing
7 changed files
with
743 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
src/main/java/fi/iki/yak/ts/compression/gorilla/Compressor32.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package fi.iki.yak.ts.compression.gorilla; | ||
|
||
/** | ||
* Implements the time series compression as described in the Facebook's Gorilla Paper. Value compression | ||
* is for floating points only. | ||
* | ||
* @author Michael Burman | ||
*/ | ||
public class Compressor32 { | ||
|
||
private int storedLeadingZeros = Integer.MAX_VALUE; | ||
private int storedTrailingZeros = 0; | ||
private int storedVal = 0; | ||
private boolean first = true; | ||
|
||
// public final static short FIRST_DELTA_BITS = 27; | ||
|
||
private BitOutput out; | ||
|
||
// We should have access to the series? | ||
public Compressor32(long timestamp, BitOutput output) { | ||
out = output; | ||
} | ||
|
||
/** | ||
* Adds a new long value to the series. Note, values must be inserted in order. | ||
* | ||
* @param timestamp Timestamp which is inside the allowed time block (default 24 hours with millisecond precision) | ||
* @param value next floating point value in the series | ||
*/ | ||
public void addValue(long timestamp, int value) { | ||
if(first) { | ||
writeFirst(timestamp, value); | ||
} else { | ||
compressValue(value); | ||
} | ||
} | ||
|
||
/** | ||
* Adds a new double value to the series. Note, values must be inserted in order. | ||
* | ||
* @param timestamp Timestamp which is inside the allowed time block (default 24 hours with millisecond precision) | ||
* @param value next floating point value in the series | ||
*/ | ||
public void addValue(long timestamp, float value) { | ||
if(first) { | ||
writeFirst(timestamp, Float.floatToRawIntBits(value)); | ||
} else { | ||
compressValue(Float.floatToRawIntBits(value)); | ||
} | ||
} | ||
|
||
private void writeFirst(long timestamp, int value) { | ||
first = false; | ||
storedVal = value; | ||
out.writeBits(storedVal, 32); | ||
} | ||
|
||
/** | ||
* Closes the block and writes the remaining stuff to the BitOutput. | ||
*/ | ||
public void close() { | ||
addValue(0, Float.NaN); | ||
out.skipBit(); | ||
out.flush(); | ||
} | ||
|
||
private void compressValue(int value) { | ||
// TODO Fix already compiled into a big method | ||
int xor = storedVal ^ value; | ||
|
||
if(xor == 0) { | ||
// Write 0 | ||
out.skipBit(); | ||
} else { | ||
int leadingZeros = Integer.numberOfLeadingZeros(xor); | ||
int trailingZeros = Integer.numberOfTrailingZeros(xor); | ||
|
||
// Check overflow of leading? Can't be 32! | ||
if(leadingZeros >= 32) { | ||
leadingZeros = 31; | ||
} | ||
|
||
// Store bit '1' | ||
out.writeBit(); | ||
|
||
if(leadingZeros >= storedLeadingZeros && trailingZeros >= storedTrailingZeros) { | ||
writeExistingLeading(xor); | ||
} else { | ||
writeNewLeading(xor, leadingZeros, trailingZeros); | ||
} | ||
} | ||
|
||
storedVal = value; | ||
} | ||
|
||
/** | ||
* If there at least as many leading zeros and as many trailing zeros as previous value, control bit = 0 (type a) | ||
* store the meaningful XORed value | ||
* | ||
* @param xor XOR between previous value and current | ||
*/ | ||
private void writeExistingLeading(int xor) { | ||
out.skipBit(); | ||
int significantBits = 32 - storedLeadingZeros - storedTrailingZeros; | ||
out.writeBits(xor >>> storedTrailingZeros, significantBits); | ||
} | ||
|
||
/** | ||
* store the length of the number of leading zeros in the next 5 bits | ||
* store length of the meaningful XORed value in the next 6 bits, | ||
* store the meaningful bits of the XORed value | ||
* (type b) | ||
* | ||
* @param xor XOR between previous value and current | ||
* @param leadingZeros New leading zeros | ||
* @param trailingZeros New trailing zeros | ||
*/ | ||
private void writeNewLeading(int xor, int leadingZeros, int trailingZeros) { | ||
out.writeBit(); | ||
out.writeBits(leadingZeros, 5); // Number of leading zeros in the next 5 bits | ||
|
||
int significantBits = 32 - leadingZeros - trailingZeros; | ||
out.writeBits(significantBits, 6); // Length of meaningful bits in the next 6 bits | ||
out.writeBits(xor >>> trailingZeros, significantBits); // Store the meaningful bits of XOR | ||
|
||
storedLeadingZeros = leadingZeros; | ||
storedTrailingZeros = trailingZeros; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.