Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Licensed to Metamarkets Group Inc. (Metamarkets) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Metamarkets 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.
*/

package io.druid.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;

public class JacksonExtremeDoubleValuesSerdeTest
{
@Test
public void testExtremeDoubleValuesSerde() throws IOException
{
ObjectMapper objectMapper = new ObjectMapper();
for (double value : new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}) {
String serialized = objectMapper.writeValueAsString(value);
Assert.assertEquals(new Double(value), objectMapper.readValue(serialized, Double.class));
}
String negativeInfinityString = objectMapper.writeValueAsString(Double.NaN);
Assert.assertTrue(objectMapper.readValue(negativeInfinityString, Double.class).isNaN());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ public boolean enclose()
{
boolean retVal = false;
float[] minCoords = new float[getNumDims()];
Arrays.fill(minCoords, Float.MAX_VALUE);
Arrays.fill(minCoords, Float.POSITIVE_INFINITY);
float[] maxCoords = new float[getNumDims()];
Arrays.fill(maxCoords, -Float.MAX_VALUE);
Arrays.fill(maxCoords, Float.NEGATIVE_INFINITY);

for (Node child : getChildren()) {
for (int i = 0; i < getNumDims(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ private Node buildRoot(boolean isLeaf)
{
float[] initMinCoords = new float[numDims];
float[] initMaxCoords = new float[numDims];
Arrays.fill(initMinCoords, -Float.MAX_VALUE);
Arrays.fill(initMaxCoords, Float.MAX_VALUE);
Arrays.fill(initMinCoords, Float.NEGATIVE_INFINITY);
Copy link
Copy Markdown
Contributor

@b-slim b-slim Jul 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not familiar with the code of Rtree but am not sure if this change really make sense. After this change any operation on the root node coordinate will always return infinity, while before i can have for instance an incremental change over the root coordinate.
Eg, node.getMinCoordinates()[0] [* or /] 100 will return Infinity if we use Float.NEGATIVE_INFINITY as oppose to it will have a defined value if we keep Float.MAX_VALUE

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be ok. I didn't check the full code around RTree in druid, but usually the min/max coordinates of an RTree node represents a minimum range covering all coordinates of the children nodes. It is used for early pruning when traversing the tree. So, I think the min/max coordinates of the root node shouldn't used for any computation.

Arrays.fill(initMaxCoords, Float.POSITIVE_INFINITY);

return new Node(initMinCoords, initMaxCoords, isLeaf, bitmapFactory);
}
Expand Down Expand Up @@ -178,7 +178,7 @@ private Node chooseLeaf(Node node, Point point)
return node;
}

double minCost = Double.MAX_VALUE;
double minCost = Double.POSITIVE_INFINITY;
Node optimal = node.getChildren().get(0);
for (Node child : node.getChildren()) {
double cost = RTreeUtils.getExpansionCost(child, point);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ public Node[] pickSeeds(List<Node> nodes)

double bestNormalized = 0.0;
for (int i = 0; i < numDims; i++) {
float minCoord = Float.MAX_VALUE;
float maxCoord = -Float.MAX_VALUE;
float highestLowSide = -Float.MAX_VALUE;
float lowestHighside = Float.MAX_VALUE;
float minCoord = Float.POSITIVE_INFINITY;
float maxCoord = Float.NEGATIVE_INFINITY;
float lowestHighside = Float.POSITIVE_INFINITY;
float highestLowSide = Float.NEGATIVE_INFINITY;
int highestLowSideIndex = 0;
int lowestHighSideIndex = 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public QuadraticGutmanSplitStrategy(int minNumChildren, int maxNumChildren, Bitm
@Override
public Node[] pickSeeds(List<Node> nodes)
{
double highestCost = Double.MIN_VALUE;
double highestCost = Double.NEGATIVE_INFINITY;
int[] highestCostIndices = new int[2];

for (int i = 0; i < nodes.size() - 1; i++) {
Expand All @@ -58,7 +58,7 @@ public Node[] pickSeeds(List<Node> nodes)
@Override
public Node pickNext(List<Node> nodes, Node[] groups)
{
double highestCost = Double.MIN_VALUE;
double highestCost = Double.NEGATIVE_INFINITY;
Node costlyNode = null;
int counter = 0;
int index = -1;
Expand Down
21 changes: 21 additions & 0 deletions codestyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,31 @@
<property name="illegalPattern" value="true"/>
<property name="message" value="Use Comparators.naturalNullsFirst() instead of Ordering.natural().nullsFirst()"/>
</module>

<module name="Regexp">
<property name="format" value="(Byte|Character|Short|Integer|Long|Float|Double)\.TYPE"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use primitive.class instead. But check twice that you don't actually need BoxedPrimitive.class instead of BoxedPrimitive.TYPE"/>
</module>
<module name="Regexp">
<property name="format" value="Float\.MAX_VALUE"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use Float.POSITIVE_INFINITY"/>
</module>
<module name="Regexp">
<property name="format" value="Float\.MIN_VALUE"/>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure how this check style will work. Does this means any usage of Float.MIN_VALUE is prohibited ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes; see #4496 (comment). I guess if anyone needs it for real then the checkstyle rule could be removed or altered.

<property name="illegalPattern" value="true"/>
<property name="message" value="Use Float.NEGATIVE_INFINITY"/>
</module>
<module name="Regexp">
<property name="format" value="Double\.MAX_VALUE"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use Double.POSITIVE_INFINITY"/>
</module>
<module name="Regexp">
<property name="format" value="Double\.MIN_VALUE"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Use Double.NEGATIVE_INFINITY"/>
</module>
</module>
</module>
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,11 @@ public void offer(float value)
// or merge existing bins before inserting the new one

int minPos = minDeltaIndex();
float minDelta = minPos >= 0 ? positions[minPos + 1] - positions[minPos] : Float.MAX_VALUE;
float minDelta = minPos >= 0 ? positions[minPos + 1] - positions[minPos] : Float.POSITIVE_INFINITY;

// determine the distance of new value to the nearest bins
final float deltaRight = insertAt < binCount ? positions[insertAt] - value : Float.MAX_VALUE;
final float deltaLeft = insertAt > 0 ? value - positions[insertAt - 1] : Float.MAX_VALUE;
final float deltaRight = insertAt < binCount ? positions[insertAt] - value : Float.POSITIVE_INFINITY;
final float deltaLeft = insertAt > 0 ? value - positions[insertAt - 1] : Float.POSITIVE_INFINITY;

boolean mergeValue = false;
if (deltaRight < minDelta) {
Expand Down Expand Up @@ -368,7 +368,7 @@ public void offer(float value)
protected int minDeltaIndex()
{
// determine minimum distance between existing bins
float minDelta = Float.MAX_VALUE;
float minDelta = Float.POSITIVE_INFINITY;
int minPos = -1;
for (int i = 0; i < binCount - 1; ++i) {
float delta = (positions[i + 1] - positions[i]);
Expand Down Expand Up @@ -886,9 +886,6 @@ private static void mergeBins(
while (i < numMerge) {
// find the smallest delta within the range used for bins

// pick minimum delta by scanning array
//int currentIndex = minIndex(deltas, lastValidIndex);

// pick minimum delta index using min-heap
int currentIndex = heap[0];

Expand All @@ -908,17 +905,13 @@ private static void mergeBins(
final float mm0 = (m0 - m1) * w + m1;

mergedPositions[currentIndex] = mm0;
//mergedPositions[nextIndex] = Float.MAX_VALUE; // for debugging

mergedBins[currentIndex] = sum | APPROX_FLAG_BIT;
//mergedBins[nextIndex] = -1; // for debugging

// update deltas and min-heap
if (nextIndex == lastValidIndex) {
// merged bin is the last => remove the current bin delta from the heap
heapSize = heapDelete(heap, reverseIndex, heapSize, reverseIndex[currentIndex], deltas);

//deltas[currentIndex] = Float.MAX_VALUE; // for debugging
} else {
// merged bin is not the last => remove the merged bin delta from the heap
heapSize = heapDelete(heap, reverseIndex, heapSize, reverseIndex[nextIndex], deltas);
Expand All @@ -938,9 +931,6 @@ private static void mergeBins(
siftDown(heap, reverseIndex, reverseIndex[prevIndex], heapSize - 1, deltas);
}

// mark the merged bin as invalid
// deltas[nextIndex] = Float.MAX_VALUE; // for debugging

// update last valid index if we merged the last bin
if (nextIndex == lastValidIndex) {
lastValidIndex = currentIndex;
Expand Down Expand Up @@ -1037,7 +1027,7 @@ private static int heapDelete(int[] heap, int[] reverseIndex, int count, int hea
private static int minIndex(float[] deltas, int lastValidIndex)
{
int minIndex = -1;
float min = Float.MAX_VALUE;
float min = Float.POSITIVE_INFINITY;
for (int k = 0; k < lastValidIndex; ++k) {
float value = deltas[k];
if (value < min) {
Expand Down
2 changes: 1 addition & 1 deletion hll/src/main/java/io/druid/hll/HyperLogLogCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public static double applyCorrection(double e, int zeroCount)
final double ratio = e / TWO_TO_THE_SIXTY_FOUR;
if (ratio >= 1) {
// handle very unlikely case that value is > 2^64
return Double.MAX_VALUE;
return Double.POSITIVE_INFINITY;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as comment above why this need to be +infinity and not just Max_value ?

} else {
return -TWO_TO_THE_SIXTY_FOUR * Math.log(1 - ratio);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ public void testHighBits() throws Exception
fillBuckets(collector, (byte) 0, (byte) 63);
collector.add(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});

Assert.assertEquals(Double.MAX_VALUE, collector.estimateCardinality(), 1000);
Assert.assertEquals(Double.POSITIVE_INFINITY, collector.estimateCardinality(), 1000);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,13 @@ public BufferAggregator factorizeBuffered(ColumnSelectorFactory metricFactory)

private FloatColumnSelector getFloatColumnSelector(ColumnSelectorFactory metricFactory)
{
return AggregatorUtil.getFloatColumnSelector(metricFactory, macroTable, fieldName, expression, Float.MIN_VALUE);
return AggregatorUtil.getFloatColumnSelector(
metricFactory,
macroTable,
fieldName,
expression,
Float.NEGATIVE_INFINITY
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ public BufferAggregator factorizeBuffered(ColumnSelectorFactory metricFactory)

private FloatColumnSelector getFloatColumnSelector(ColumnSelectorFactory metricFactory)
{
return AggregatorUtil.getFloatColumnSelector(metricFactory, macroTable, fieldName, expression, Float.MAX_VALUE);
return AggregatorUtil.getFloatColumnSelector(
metricFactory,
macroTable,
fieldName,
expression,
Float.POSITIVE_INFINITY
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ public Histogram(float[] breaks) {
this.breaks = breaks;
this.bins = new long[this.breaks.length + 1];
this.count = 0;
this.min = Float.MAX_VALUE;
this.max = Float.MIN_VALUE;
this.min = Float.POSITIVE_INFINITY;
this.max = Float.NEGATIVE_INFINITY;
}

public Histogram(float[] breaks, long[] bins, float min, float max) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ public void init(ByteBuffer buf, int position)

final long[] bins = new long[breaks.length + 1];
mutationBuffer.asLongBuffer().put(bins);
mutationBuffer.putFloat(position + minOffset, Float.MAX_VALUE);
mutationBuffer.putFloat(position + maxOffset, Float.MIN_VALUE);
mutationBuffer.putFloat(position + minOffset, Float.POSITIVE_INFINITY);
mutationBuffer.putFloat(position + maxOffset, Float.NEGATIVE_INFINITY);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ public Indexed<Float> getSortedIndexedValues()
@Override
public Float getMinValue()
{
return Float.MIN_VALUE;
return Float.NEGATIVE_INFINITY;
}

@Override
public Float getMaxValue()
{
return Float.MAX_VALUE;
return Float.POSITIVE_INFINITY;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,25 @@ public void testOffer() {
Assert.assertEquals("histogram matches expected histogram", hExpected, h);
}

/**
* This test differs from {@link #testOffer()} only in that it offers only negative values into Histogram. It's to
* expose the issue of using Float's MIN_VALUE that is actually positive as initial value for {@link Histogram#max}.
*/
@Test
public void testOfferOnlyNegative() {
final float[] values = {-0.3f, -.1f, -0.8f, -.7f, -.5f, -3f};
final float[] breaks = {-1f, -0.5f, 0.0f, 0.5f, 1f};

Histogram hExpected = new Histogram(breaks, new long[]{1,3,2,0,0,0}, -3f, -0.1f);

Histogram h = new Histogram(breaks);
for(float v : values) {
h.offer(v);
}

Assert.assertEquals("histogram matches expected histogram", hExpected, h);
}

@Test
public void testToFromBytes() {
float[] breaks = {-1f, -0.5f, 0.0f, 0.5f, 1f};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ public static Iterable<Object[]> compressionStrategies()
private final float values5[] = {123.16f, 1.12f, 62.00f, 462.12f, 517.71f, 56.54f, 971.32f, 824.22f, 472.12f, 625.26f};
private final float values6[] = {1000000f, 1000001f, 1000002f, 1000003f, 1000004f, 1000005f, 1000006f, 1000007f, 1000008f};
private final float values7[] = {
Float.MAX_VALUE, Float.MIN_VALUE, 12378.5734f, -12718243.7496f, -93653653.1f, 12743153.385534f, 21431.414538f,
65487435436632.123f, -43734526234564.65f
Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 12378.5734f, -12718243.7496f, -93653653.1f, 12743153.385534f,
21431.414538f, 65487435436632.123f, -43734526234564.65f
};

public CompressedFloatsSerdeTest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public void testNullDimensionTransform() throws IndexSizeExceededException
Lists.newArrayList("string", "float", "long"),
ImmutableMap.<String, Object>of(
"string", Arrays.asList("A", null, ""),
"float", Arrays.asList(Float.MAX_VALUE, null, ""),
"float", Arrays.asList(Float.POSITIVE_INFINITY, null, ""),
"long", Arrays.asList(Long.MIN_VALUE, null, "")
)
)
Expand All @@ -223,7 +223,7 @@ public void testNullDimensionTransform() throws IndexSizeExceededException
Row row = index.iterator().next();

Assert.assertEquals(Arrays.asList(new String[]{"", "", "A"}), row.getRaw("string"));
Assert.assertEquals(Arrays.asList(new String[]{"", "", String.valueOf(Float.MAX_VALUE)}), row.getRaw("float"));
Assert.assertEquals(Arrays.asList(new String[]{"", "", String.valueOf(Float.POSITIVE_INFINITY)}), row.getRaw("float"));
Assert.assertEquals(Arrays.asList(new String[]{"", "", String.valueOf(Long.MIN_VALUE)}), row.getRaw("long"));
}

Expand Down