Skip to content

Commit

Permalink
Fix hash calculation in few cases, change Point internals to be more …
Browse files Browse the repository at this point in the history
…compact (#238)
  • Loading branch information
stolstov authored Aug 19, 2019
1 parent 7812fd3 commit 4205cd1
Show file tree
Hide file tree
Showing 15 changed files with 333 additions and 261 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ public boolean equals(AttributeStreamBase other, int start, int end) {
end = size;

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

return true;
Expand Down
44 changes: 12 additions & 32 deletions src/main/java/com/esri/core/geometry/Envelope.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,20 @@ public Envelope(Envelope2D env2D) {
public Envelope(VertexDescription vd) {
if (vd == null)
throw new IllegalArgumentException();

m_description = vd;
m_envelope.setEmpty();
_ensureAttributes();
}

public Envelope(VertexDescription vd, Envelope2D env2D) {
if (vd == null)
throw new IllegalArgumentException();

m_description = vd;
m_envelope.setCoords(env2D);
m_envelope.normalize();
_ensureAttributes();
}

/**
Expand Down Expand Up @@ -331,8 +335,8 @@ void _setFromPoint(Point centerPoint, double width, double height) {
}

void _setFromPoint(Point centerPoint) {
m_envelope.setCoords(centerPoint.m_attributes[0],
centerPoint.m_attributes[1]);
mergeVertexDescription(centerPoint.getDescription());
m_envelope.setCoords(centerPoint.getX(), centerPoint.getY());
VertexDescription pointVD = centerPoint.m_description;
for (int iattrib = 1, nattrib = pointVD.getAttributeCount(); iattrib < nattrib; iattrib++) {
int semantics = pointVD._getSemanticsImpl(iattrib);
Expand Down Expand Up @@ -610,7 +614,6 @@ int getEndPointOffset(VertexDescription descr, int end_point) {
throw new IllegalArgumentException();

int attribute_index = m_description.getAttributeIndex(semantics);
_ensureAttributes();
if (attribute_index >= 0) {
return m_attributes[getEndPointOffset(m_description, end_point)
+ m_description.getPointAttributeOffset_(attribute_index)
Expand Down Expand Up @@ -645,7 +648,6 @@ void setAttributeAsDblImpl_(int end_point, int semantics, int ordinate,
throw new IllegalArgumentException();

addAttribute(semantics);
_ensureAttributes();
int attribute_index = m_description.getAttributeIndex(semantics);
m_attributes[getEndPointOffset(m_description, end_point)
+ m_description.getPointAttributeOffset_(attribute_index) - 2
Expand All @@ -655,32 +657,17 @@ void setAttributeAsDblImpl_(int end_point, int semantics, int ordinate,
void _ensureAttributes() {
_touch();
if (m_attributes == null && m_description.getTotalComponentCount() > 2) {
m_attributes = new double[(m_description.getTotalComponentCount() - 2) * 2];
int halfLength = m_description.getTotalComponentCount() - 2;
m_attributes = new double[halfLength * 2];
int offset0 = _getEndPointOffset(m_description, 0);
int offset1 = _getEndPointOffset(m_description, 1);

int j = 0;
for (int i = 1, n = m_description.getAttributeCount(); i < n; i++) {
int semantics = m_description.getSemantics(i);
int nords = VertexDescription.getComponentCount(semantics);
double d = VertexDescription.getDefaultValue(semantics);
for (int ord = 0; ord < nords; ord++)
{
m_attributes[offset0 + j] = d;
m_attributes[offset1 + j] = d;
j++;
}
}
System.arraycopy(m_description._getDefaultPointAttributes(), 2, m_attributes, offset0, halfLength);
System.arraycopy(m_description._getDefaultPointAttributes(), 2, m_attributes, offset1, halfLength);
}
}

@Override
protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {
if (m_attributes == null) {
m_description = newDescription;
return;
}

if (newDescription.getTotalComponentCount() > 2) {
int[] mapping = VertexDescriptionDesignerImpl.mapAttributes(newDescription, m_description);

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

// _ASSERT(endPoint == 0 || endPoint == 1);

if (semantics == Semantics.POSITION) {
if (endPoint != 0) {
return ordinate != 0 ? m_envelope.ymax : m_envelope.xmax;
Expand All @@ -750,7 +735,6 @@ protected void _assignVertexDescriptionImpl(VertexDescription newDescription) {

int attributeIndex = m_description.getAttributeIndex(semantics);
if (attributeIndex >= 0) {
_ensureAttributes();
return m_attributes[_getEndPointOffset(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex)
- 2 + ordinate];
Expand Down Expand Up @@ -784,14 +768,10 @@ void _setAttributeAsDbl(int endPoint, int semantics, int ordinate,
throw new IndexOutOfBoundsException();

if (!hasAttribute(semantics)) {
if (VertexDescription.isDefaultValue(semantics, value))
return;

addAttribute(semantics);
}

int attributeIndex = m_description.getAttributeIndex(semantics);
_ensureAttributes();
m_attributes[_getEndPointOffset(m_description, endPoint)
+ m_description._getPointAttributeOffset(attributeIndex) - 2
+ ordinate] = value;
Expand Down Expand Up @@ -1015,7 +995,7 @@ public boolean equals(Object _other) {
return false;

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

return true;
Expand All @@ -1030,7 +1010,7 @@ public boolean equals(Object _other) {
public int hashCode() {
int hashCode = m_description.hashCode();
hashCode = NumberUtils.hash(hashCode, m_envelope.hashCode());
if (!isEmpty() && m_attributes != null) {
if (!isEmpty()) {
for (int i = 0, n = (m_description.getTotalComponentCount() - 2) * 2; i < n; i++) {
hashCode = NumberUtils.hash(hashCode, m_attributes[i]);
}
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/com/esri/core/geometry/Envelope1D.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,13 @@ public boolean equals(Object _other)

@Override
public int hashCode() {
return NumberUtils.hash(NumberUtils.hash(vmin), vmax);
if (isEmpty()) {
return NumberUtils.hash(NumberUtils.TheNaN);
}

int hash = NumberUtils.hash(vmin);
hash = NumberUtils.hash(hash, vmax);
return hash;
}

}
25 changes: 8 additions & 17 deletions src/main/java/com/esri/core/geometry/Envelope2D.java
Original file line number Diff line number Diff line change
Expand Up @@ -699,23 +699,14 @@ public boolean equals(Object _other) {

@Override
public int hashCode() {

long bits = Double.doubleToLongBits(xmin);
int hc = (int) (bits ^ (bits >>> 32));

int hash = NumberUtils.hash(hc);

bits = Double.doubleToLongBits(xmax);
hc = (int) (bits ^ (bits >>> 32));
hash = NumberUtils.hash(hash, hc);

bits = Double.doubleToLongBits(ymin);
hc = (int) (bits ^ (bits >>> 32));
hash = NumberUtils.hash(hash, hc);

bits = Double.doubleToLongBits(ymax);
hc = (int) (bits ^ (bits >>> 32));
hash = NumberUtils.hash(hash, hc);
if (isEmpty()) {
return NumberUtils.hash(NumberUtils.TheNaN);
}

int hash = NumberUtils.hash(xmin);
hash = NumberUtils.hash(hash, xmax);
hash = NumberUtils.hash(hash, ymin);
hash = NumberUtils.hash(hash, ymax);

return hash;
}
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/com/esri/core/geometry/Envelope3D.java
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,22 @@ public boolean equals(Object _other) {
return true;
}


@Override
public int hashCode() {
if (isEmpty()) {
return NumberUtils.hash(NumberUtils.TheNaN);
}

int hash = NumberUtils.hash(xmin);
hash = NumberUtils.hash(hash, xmax);
hash = NumberUtils.hash(hash, ymin);
hash = NumberUtils.hash(hash, ymax);
hash = NumberUtils.hash(hash, zmin);
hash = NumberUtils.hash(hash, zmax);
return hash;
}

public void construct(Envelope1D xinterval, Envelope1D yinterval,
Envelope1D zinterval) {
if (xinterval.isEmpty() || yinterval.isEmpty()) {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/esri/core/geometry/Line.java
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,11 @@ public boolean equals(Object other) {
return _equalsImpl((Segment)other);
}

@Override
public int hashCode() {
return super.hashCode();
}

boolean equals(Line other) {
if (other == this)
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,6 @@ public void getPointByVal(int index, Point dst) {

Point outPoint = dst;
outPoint.assignVertexDescription(m_description);
if (outPoint.isEmpty())
outPoint._setToDefault();

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

outPoint.assignVertexDescription(m_description);
if (outPoint.isEmpty())
outPoint._setToDefault();

for (int attributeIndex = 0; attributeIndex < m_description
.getAttributeCount(); attributeIndex++) {
int semantics = m_description._getSemanticsImpl(attributeIndex);
Expand Down Expand Up @@ -966,8 +961,6 @@ public Point getPoint(int index) {

Point outPoint = new Point();
outPoint.assignVertexDescription(m_description);
if (outPoint.isEmpty())
outPoint._setToDefault();

for (int attributeIndex = 0; attributeIndex < m_description
.getAttributeCount(); attributeIndex++) {
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/esri/core/geometry/NumberUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,18 @@ static int nextRand(int prevRand) {
return (1103515245 * prevRand + 12345) & intMax(); // according to Wiki,
// this is gcc's
}

/**
* Returns true if two values are equal (also can compare inf and nan).
*/
static boolean isEqualNonIEEE(double a, double b) {
return a == b || (Double.isNaN(a) && Double.isNaN(b));
}

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

0 comments on commit 4205cd1

Please sign in to comment.