Skip to content

Commit 4205cd1

Browse files
authored
Fix hash calculation in few cases, change Point internals to be more compact (#238)
1 parent 7812fd3 commit 4205cd1

File tree

15 files changed

+333
-261
lines changed

15 files changed

+333
-261
lines changed

src/main/java/com/esri/core/geometry/AttributeStreamOfDbl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ public boolean equals(AttributeStreamBase other, int start, int end) {
352352
end = size;
353353

354354
for (int i = start; i < end; i++)
355-
if (read(i) != _other.read(i))
355+
if (!NumberUtils.isEqualNonIEEE(read(i), _other.read(i)))
356356
return false;
357357

358358
return true;

src/main/java/com/esri/core/geometry/Envelope.java

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,20 @@ public Envelope(Envelope2D env2D) {
7070
public Envelope(VertexDescription vd) {
7171
if (vd == null)
7272
throw new IllegalArgumentException();
73+
7374
m_description = vd;
7475
m_envelope.setEmpty();
76+
_ensureAttributes();
7577
}
7678

7779
public Envelope(VertexDescription vd, Envelope2D env2D) {
7880
if (vd == null)
7981
throw new IllegalArgumentException();
82+
8083
m_description = vd;
8184
m_envelope.setCoords(env2D);
8285
m_envelope.normalize();
86+
_ensureAttributes();
8387
}
8488

8589
/**
@@ -331,8 +335,8 @@ void _setFromPoint(Point centerPoint, double width, double height) {
331335
}
332336

333337
void _setFromPoint(Point centerPoint) {
334-
m_envelope.setCoords(centerPoint.m_attributes[0],
335-
centerPoint.m_attributes[1]);
338+
mergeVertexDescription(centerPoint.getDescription());
339+
m_envelope.setCoords(centerPoint.getX(), centerPoint.getY());
336340
VertexDescription pointVD = centerPoint.m_description;
337341
for (int iattrib = 1, nattrib = pointVD.getAttributeCount(); iattrib < nattrib; iattrib++) {
338342
int semantics = pointVD._getSemanticsImpl(iattrib);
@@ -610,7 +614,6 @@ int getEndPointOffset(VertexDescription descr, int end_point) {
610614
throw new IllegalArgumentException();
611615

612616
int attribute_index = m_description.getAttributeIndex(semantics);
613-
_ensureAttributes();
614617
if (attribute_index >= 0) {
615618
return m_attributes[getEndPointOffset(m_description, end_point)
616619
+ m_description.getPointAttributeOffset_(attribute_index)
@@ -645,7 +648,6 @@ void setAttributeAsDblImpl_(int end_point, int semantics, int ordinate,
645648
throw new IllegalArgumentException();
646649

647650
addAttribute(semantics);
648-
_ensureAttributes();
649651
int attribute_index = m_description.getAttributeIndex(semantics);
650652
m_attributes[getEndPointOffset(m_description, end_point)
651653
+ m_description.getPointAttributeOffset_(attribute_index) - 2
@@ -655,32 +657,17 @@ void setAttributeAsDblImpl_(int end_point, int semantics, int ordinate,
655657
void _ensureAttributes() {
656658
_touch();
657659
if (m_attributes == null && m_description.getTotalComponentCount() > 2) {
658-
m_attributes = new double[(m_description.getTotalComponentCount() - 2) * 2];
660+
int halfLength = m_description.getTotalComponentCount() - 2;
661+
m_attributes = new double[halfLength * 2];
659662
int offset0 = _getEndPointOffset(m_description, 0);
660663
int offset1 = _getEndPointOffset(m_description, 1);
661-
662-
int j = 0;
663-
for (int i = 1, n = m_description.getAttributeCount(); i < n; i++) {
664-
int semantics = m_description.getSemantics(i);
665-
int nords = VertexDescription.getComponentCount(semantics);
666-
double d = VertexDescription.getDefaultValue(semantics);
667-
for (int ord = 0; ord < nords; ord++)
668-
{
669-
m_attributes[offset0 + j] = d;
670-
m_attributes[offset1 + j] = d;
671-
j++;
672-
}
673-
}
664+
System.arraycopy(m_description._getDefaultPointAttributes(), 2, m_attributes, offset0, halfLength);
665+
System.arraycopy(m_description._getDefaultPointAttributes(), 2, m_attributes, offset1, halfLength);
674666
}
675667
}
676668

677669
@Override
678670
protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
679-
if (m_attributes == null) {
680-
m_description = newDescription;
681-
return;
682-
}
683-
684671
if (newDescription.getTotalComponentCount() > 2) {
685672
int[] mapping = VertexDescriptionDesignerImpl.mapAttributes(newDescription, m_description);
686673

@@ -734,8 +721,6 @@ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
734721
throw new GeometryException(
735722
"This operation was performed on an Empty Geometry.");
736723

737-
// _ASSERT(endPoint == 0 || endPoint == 1);
738-
739724
if (semantics == Semantics.POSITION) {
740725
if (endPoint != 0) {
741726
return ordinate != 0 ? m_envelope.ymax : m_envelope.xmax;
@@ -750,7 +735,6 @@ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
750735

751736
int attributeIndex = m_description.getAttributeIndex(semantics);
752737
if (attributeIndex >= 0) {
753-
_ensureAttributes();
754738
return m_attributes[_getEndPointOffset(m_description, endPoint)
755739
+ m_description._getPointAttributeOffset(attributeIndex)
756740
- 2 + ordinate];
@@ -784,14 +768,10 @@ void _setAttributeAsDbl(int endPoint, int semantics, int ordinate,
784768
throw new IndexOutOfBoundsException();
785769

786770
if (!hasAttribute(semantics)) {
787-
if (VertexDescription.isDefaultValue(semantics, value))
788-
return;
789-
790771
addAttribute(semantics);
791772
}
792773

793774
int attributeIndex = m_description.getAttributeIndex(semantics);
794-
_ensureAttributes();
795775
m_attributes[_getEndPointOffset(m_description, endPoint)
796776
+ m_description._getPointAttributeOffset(attributeIndex) - 2
797777
+ ordinate] = value;
@@ -1015,7 +995,7 @@ public boolean equals(Object _other) {
1015995
return false;
1016996

1017997
for (int i = 0, n = (m_description.getTotalComponentCount() - 2) * 2; i < n; i++)
1018-
if (m_attributes[i] != other.m_attributes[i])
998+
if (!NumberUtils.isEqualNonIEEE(m_attributes[i], other.m_attributes[i]))
1019999
return false;
10201000

10211001
return true;
@@ -1030,7 +1010,7 @@ public boolean equals(Object _other) {
10301010
public int hashCode() {
10311011
int hashCode = m_description.hashCode();
10321012
hashCode = NumberUtils.hash(hashCode, m_envelope.hashCode());
1033-
if (!isEmpty() && m_attributes != null) {
1013+
if (!isEmpty()) {
10341014
for (int i = 0, n = (m_description.getTotalComponentCount() - 2) * 2; i < n; i++) {
10351015
hashCode = NumberUtils.hash(hashCode, m_attributes[i]);
10361016
}

src/main/java/com/esri/core/geometry/Envelope1D.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,13 @@ public boolean equals(Object _other)
225225

226226
@Override
227227
public int hashCode() {
228-
return NumberUtils.hash(NumberUtils.hash(vmin), vmax);
228+
if (isEmpty()) {
229+
return NumberUtils.hash(NumberUtils.TheNaN);
230+
}
231+
232+
int hash = NumberUtils.hash(vmin);
233+
hash = NumberUtils.hash(hash, vmax);
234+
return hash;
229235
}
230236

231237
}

src/main/java/com/esri/core/geometry/Envelope2D.java

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -699,23 +699,14 @@ public boolean equals(Object _other) {
699699

700700
@Override
701701
public int hashCode() {
702-
703-
long bits = Double.doubleToLongBits(xmin);
704-
int hc = (int) (bits ^ (bits >>> 32));
705-
706-
int hash = NumberUtils.hash(hc);
707-
708-
bits = Double.doubleToLongBits(xmax);
709-
hc = (int) (bits ^ (bits >>> 32));
710-
hash = NumberUtils.hash(hash, hc);
711-
712-
bits = Double.doubleToLongBits(ymin);
713-
hc = (int) (bits ^ (bits >>> 32));
714-
hash = NumberUtils.hash(hash, hc);
715-
716-
bits = Double.doubleToLongBits(ymax);
717-
hc = (int) (bits ^ (bits >>> 32));
718-
hash = NumberUtils.hash(hash, hc);
702+
if (isEmpty()) {
703+
return NumberUtils.hash(NumberUtils.TheNaN);
704+
}
705+
706+
int hash = NumberUtils.hash(xmin);
707+
hash = NumberUtils.hash(hash, xmax);
708+
hash = NumberUtils.hash(hash, ymin);
709+
hash = NumberUtils.hash(hash, ymax);
719710

720711
return hash;
721712
}

src/main/java/com/esri/core/geometry/Envelope3D.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,22 @@ public boolean equals(Object _other) {
320320
return true;
321321
}
322322

323+
324+
@Override
325+
public int hashCode() {
326+
if (isEmpty()) {
327+
return NumberUtils.hash(NumberUtils.TheNaN);
328+
}
329+
330+
int hash = NumberUtils.hash(xmin);
331+
hash = NumberUtils.hash(hash, xmax);
332+
hash = NumberUtils.hash(hash, ymin);
333+
hash = NumberUtils.hash(hash, ymax);
334+
hash = NumberUtils.hash(hash, zmin);
335+
hash = NumberUtils.hash(hash, zmax);
336+
return hash;
337+
}
338+
323339
public void construct(Envelope1D xinterval, Envelope1D yinterval,
324340
Envelope1D zinterval) {
325341
if (xinterval.isEmpty() || yinterval.isEmpty()) {

src/main/java/com/esri/core/geometry/Line.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,11 @@ public boolean equals(Object other) {
548548
return _equalsImpl((Segment)other);
549549
}
550550

551+
@Override
552+
public int hashCode() {
553+
return super.hashCode();
554+
}
555+
551556
boolean equals(Line other) {
552557
if (other == this)
553558
return true;

src/main/java/com/esri/core/geometry/MultiVertexGeometryImpl.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,6 @@ public void getPointByVal(int index, Point dst) {
168168

169169
Point outPoint = dst;
170170
outPoint.assignVertexDescription(m_description);
171-
if (outPoint.isEmpty())
172-
outPoint._setToDefault();
173171

174172
for (int attributeIndex = 0; attributeIndex < m_description
175173
.getAttributeCount(); attributeIndex++) {
@@ -933,9 +931,6 @@ void _interpolateTwoVertices(int vertex1, int vertex2, double f,
933931
_verifyAllStreams();
934932

935933
outPoint.assignVertexDescription(m_description);
936-
if (outPoint.isEmpty())
937-
outPoint._setToDefault();
938-
939934
for (int attributeIndex = 0; attributeIndex < m_description
940935
.getAttributeCount(); attributeIndex++) {
941936
int semantics = m_description._getSemanticsImpl(attributeIndex);
@@ -966,8 +961,6 @@ public Point getPoint(int index) {
966961

967962
Point outPoint = new Point();
968963
outPoint.assignVertexDescription(m_description);
969-
if (outPoint.isEmpty())
970-
outPoint._setToDefault();
971964

972965
for (int attributeIndex = 0; attributeIndex < m_description
973966
.getAttributeCount(); attributeIndex++) {

src/main/java/com/esri/core/geometry/NumberUtils.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,5 +136,18 @@ static int nextRand(int prevRand) {
136136
return (1103515245 * prevRand + 12345) & intMax(); // according to Wiki,
137137
// this is gcc's
138138
}
139+
140+
/**
141+
* Returns true if two values are equal (also can compare inf and nan).
142+
*/
143+
static boolean isEqualNonIEEE(double a, double b) {
144+
return a == b || (Double.isNaN(a) && Double.isNaN(b));
145+
}
139146

147+
/**
148+
* Returns true if two values are equal (also can compare inf and nan).
149+
*/
150+
static boolean isEqualNonIEEE(double a, double b, double tolerance) {
151+
return a == b || Math.abs(a - b) <= tolerance || (Double.isNaN(a) && Double.isNaN(b));
152+
}
140153
}

0 commit comments

Comments
 (0)