source: josm/trunk/test/unit/org/openstreetmap/josm/data/imagery/ShapeTest.java@ 19052

Last change on this file since 19052 was 18777, checked in by taylor.smock, 2 years ago

Reduce allocations during startup from Shape

Shape#hashCode made between 8 and 24 MB of allocations at startup. This was
reduced by moving the math out of Arrays#hash and the default List#hash methods.
This additionally reduced the allocations from the Shape#equals method.

As an implementation note, the Shape#hashCode method returns exactly the same
hashcode as it did prior to this change. This may change in the future.

File size: 3.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import static org.junit.jupiter.api.Assertions.assertAll;
5import static org.junit.jupiter.api.Assertions.assertEquals;
6
7import java.awt.Polygon;
8import java.util.ArrayList;
9import java.util.Arrays;
10import java.util.Objects;
11
12import nl.jqno.equalsverifier.EqualsVerifier;
13import org.junit.jupiter.api.Test;
14import org.junit.jupiter.params.ParameterizedTest;
15import org.junit.jupiter.params.provider.ValueSource;
16
17/**
18 * Unit tests for class {@link Shape}.
19 */
20class ShapeTest {
21
22 /**
23 * Tests string conversion
24 */
25 @Test
26 void test() {
27 Shape shape = new Shape();
28 shape.addPoint("47.1", "11.1");
29 shape.addPoint("47.2", "11.2");
30 shape.addPoint("47.3", "11.3");
31 String shapeString = "47.1 11.1 47.2 11.2 47.3 11.3";
32 Shape fromString = new Shape(shapeString, " ");
33 assertEquals(shape, fromString);
34 assertEquals(shapeString, shape.encodeAsString(" "));
35 assertEquals("47.1//11.1//47.2//11.2//47.3//11.3", shape.encodeAsString("//"));
36 assertEquals("47.1,11.1,47.2,11.2,47.3,11.3;47.1,11.1,47.2,11.2,47.3,11.3", Shape.encodeAsString(Arrays.asList(shape, shape)));
37 }
38
39 /**
40 * Check double edge cases
41 * @param coordinate the coordinate to check
42 */
43 @ParameterizedTest
44 @ValueSource(doubles = {
45 // The double representation of 0.2575799 * 1e7 is 2575798.9999999995. Directly casting to int will round down.
46 0.2575799,
47 // Check that 2575798.0000000005 is rounded down
48 0.2575798
49 })
50 void testDoubleEdgeCases(final double coordinate) {
51 final Shape shape = new Shape();
52 shape.addPoint(Double.toString(1), Double.toString(coordinate));
53 shape.addPoint(Double.toString(coordinate), Double.toString(1));
54 shape.addPoint(Double.toString(coordinate), Double.toString(coordinate));
55 assertAll("Coordinates are not properly rounded on entry",
56 () -> assertEquals(coordinate, shape.getPoints().get(0).getLon()),
57 () -> assertEquals(coordinate, shape.getPoints().get(1).getLat()));
58 }
59
60 /**
61 * Ensure that the hashcode is semantically the same as what it previously was
62 */
63 @ParameterizedTest
64 @ValueSource(strings = {"47.1 11.1 47.2 11.2 47.3 11.3", "-47.1 -11.1 -47.2 -11.2 -47.3 -11.3"})
65 void testHashCode(String shapeString) {
66 final Shape shape = new Shape(shapeString, " ");
67 assertEquals(Objects.hash(shape.getPoints()), shape.hashCode(),
68 "The hashcode for shape should be the same as that for the point list (specific coord list)");
69 assertEquals(Objects.hash(new ArrayList<>(shape.getPoints())), shape.hashCode(),
70 "The hashcode for shape should be the same as that for the point list (non-specific)");
71 }
72
73 @Test
74 void testEqualsHashCodeContract() {
75 EqualsVerifier.simple().forClass(Shape.class)
76 .withNonnullFields("coords")
77 .withPrefabValues(Polygon.class, new Polygon(), new Polygon(new int[] {1, 2, 3}, new int[]{4, 5, 6}, 3))
78 .verify();
79 }
80}
Note: See TracBrowser for help on using the repository browser.