@Test public void addPointLong4BytesNegative() throws Exception { setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1356998400, -65537, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0x50, (byte) 0xE2, 0x27, 0, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {0, 3}); assertNotNull(value); assertEquals(-65537, Bytes.getInt(value)); }
@Test public void addPointFloatPrecision() throws Exception { setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1356998400, 42.5123459999F, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0x50, (byte) 0xE2, 0x27, 0, 0, 0, 1, 0, 0, 1}; final byte[] value = storage.getColumn(row, new byte[] {0, 11}); assertNotNull(value); // should have 7 digits of precision assertEquals(42.512345F, Float.intBitsToFloat(Bytes.getInt(value)), 0.0000001); }
@Test public void addPointBothSameTimeIntAndFloatMs() throws Exception { // this is an odd situation that can occur if the user puts an int and then // a float (or vice-versa) with the same timestamp. What happens in the // aggregators when this occurs? setupAddPointStorage(); HashMap<String, String> tags = new HashMap<String, String>(1); tags.put("host", "web01"); tsdb.addPoint("sys.cpu.user", 1356998400500L, 42, tags).joinUninterruptibly(); tsdb.addPoint("sys.cpu.user", 1356998400500L, 42.5F, tags).joinUninterruptibly(); final byte[] row = new byte[] {0, 0, 1, 0x50, (byte) 0xE2, 0x27, 0, 0, 0, 1, 0, 0, 1}; byte[] value = storage.getColumn(row, new byte[] {(byte) 0xF0, 0, 0x7D, 0}); assertEquals(2, storage.numColumns(row)); assertNotNull(value); assertEquals(42, value[0]); value = storage.getColumn(row, new byte[] {(byte) 0xF0, 0, 0x7D, 11}); assertNotNull(value); // should have 7 digits of precision assertEquals(42.5F, Float.intBitsToFloat(Bytes.getInt(value)), 0.0000001); }
/** * Extracts the value of a cell containing a data point. * * @param qualifier The qualifier of that cell, as returned by {@link #extractQualifier}. * @param kv The cell. * @return The value of the cell, as a {@code long}, since it's expected to be on 8 bytes at most. * If the cell contains a floating point value, the bits of the {@code long} represent some * kind of a floating point value. */ private static long extractLValue(final short qualifier, final KeyValue kv) { final byte[] value = kv.value(); if ((qualifier & Const.FLAG_FLOAT) != 0) { if ((qualifier & 0x3) != 0x3) { throw new AssertionError("Float value qualifier size != 4: " + kv); } else if (value.length != 8) { throw new AssertionError("Float value not on 8 bytes: " + kv); } else if (value[0] != 0 || value[1] != 0 || value[2] != 0 || value[3] != 0) { throw new AssertionError("Float value with nonzero byte MSBs: " + kv); } return Bytes.getInt(value, 4); } else { if ((qualifier & 0x7) != 0x7) { throw new AssertionError("Integer value qualifier size != 4: " + kv); } else if (value.length != 8) { throw new AssertionError("Integer value not on 8 bytes: " + kv); } return Bytes.getLong(value); } }