digidem / osm-p2p-db

Peer-to-peer database for OpenStreetMap data
BSD 2-Clause "Simplified" License
237 stars 25 forks source link

Bugfix: Point deletions are not always registered #53

Closed hackergrrl closed 7 years ago

hackergrrl commented 7 years ago

Since Javascript uses 58-bit numbers (Number), using 32-bit floating point values will sometimes (often) result in rounding errors being introduced.

This has been happening to the numbers written to osm-p2p-db's kdb-tree-store. As a result, the value in the hyperlog doesn't actually necessarily match the value stored in the kdb index. This is usually fine: broad bounding box queries will return points within it even if there are small errors.

However, in the case of removing a point from the kdb index, the kdb tree relies on a certain amount of exactness: if the rounding error so happens to result in a value that is on the wrong side of a kdb tree split, the remove logic will recurse down the wrong branch and not delete the point. Such an error is idempotent: the rounding error will be the same each time and the point will essentially be undeletable.

These commits do two things:

  1. Use 64-bit floats for the value of points in the kdb index. This is a more precise data type than Javascript's 58-bit Number type, so that error cannot occur.

  2. Coerce all points from the hyperlog entering the kdb index into the Number type. Strange behaviour can occur if Strings are inserted.


I did some manual testing by looking over the Siekopai data with either index. Left is float32, right is float64. (Disregard the satellite tile that didn't load.)

mapeo float issue