From caf44f548f8ad5a4d981a0f316af339f7e8755f5 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Fri, 29 May 2026 13:50:23 +0200 Subject: [PATCH] feat(parity): expose the minDistance set-set distance functions in the parity-gap facade The parity-gap facade forwards to the public-surface MEOS functions that JMEOS binds and the tier-aware generator does not emit. The gap generator excludes the derived forwarder classes (MeosOpsParityGaps, MeosOpsSqlSurface) from its already-covered baseline so it reproduces idempotently, and reads its MEOS include directory from the MEOS_INCLUDE environment variable. The regenerated facade exposes mindistance_tgeo_tgeo and tgeoarr_tgeoarr_mindist, bringing the facade to 2153 of the 2153 JMEOS-bindable public MEOS functions. (cherry picked from commit 98ae6d52095a75037c47c9bfd4d108c16e995f27) --- flink-processor/docs/parity-status.md | 25 ++++------- .../flink/meos/MeosOpsParityGaps.java | 43 +++++-------------- .../tools/parity/emit_gap_methods.py | 7 ++- 3 files changed, 25 insertions(+), 50 deletions(-) diff --git a/flink-processor/docs/parity-status.md b/flink-processor/docs/parity-status.md index e26eba2..05a0797 100644 --- a/flink-processor/docs/parity-status.md +++ b/flink-processor/docs/parity-status.md @@ -1,10 +1,10 @@ # MobilityFlink parity status — MEOS surface audit -Generated 2026-05-28 by `tools/parity/parity_audit.py`. +Generated 2026-05-29 by `tools/parity/parity_audit.py`. The MobilityFlink MEOS facade (`org.mobilitydb.flink.meos.MeosOps*`) exposes MEOS C functions to Flink through JMEOS. This audit measures, per type family, the share of the **MEOS public C API** that the facade exposes and that JMEOS binds. -**Headline.** The facade exposes **2156 of 2156 public MEOS functions (100.0%)**. The MEOS public surface (`meos/include/meos*.h`, excluding internal headers) is 2156 functions; JMEOS binds 2156 of them. 0 bindable functions are not exposed (listed in §3). +**Headline.** The facade exposes **2153 of 2153 public MEOS functions (100.0%)**. The MEOS public surface (`meos/include/meos*.h`, excluding internal headers) is 2158 functions; JMEOS binds 2153 of them. 0 bindable functions are not exposed (listed in §3). Coverage is **static**: a function counts as covered when the facade declares a method of the same name and arity that delegates to a JMEOS export. @@ -22,13 +22,13 @@ Per-family runtime behaviour is asserted by `src/test/java/org/mobilitydb/flink/ | Family (header) | Public ∩ JMEOS | Exposed | Missing | Coverage | |---|---:|---:|---:|---:| -| core temporal / set / span / spanset / tbox (`meos.h`) | 1279 | 1279 | 0 | 100.0% | -| geo (tgeo / tpoint / stbox) (`meos_geo.h`) | 417 | 417 | 0 | 100.0% | +| core temporal / set / span / spanset / tbox (`meos.h`) | 1274 | 1274 | 0 | 100.0% | +| geo (tgeo / tpoint / stbox) (`meos_geo.h`) | 419 | 419 | 0 | 100.0% | | cbuffer (`meos_cbuffer.h`) | 173 | 173 | 0 | 100.0% | | npoint (`meos_npoint.h`) | 118 | 118 | 0 | 100.0% | | pose (`meos_pose.h`) | 101 | 101 | 0 | 100.0% | | rgeo (`meos_rgeo.h`) | 68 | 68 | 0 | 100.0% | -| **total** | **2156** | **2156** | **0** | **100.0%** | +| **total** | **2153** | **2153** | **0** | **100.0%** | ## 3. Bindable MEOS functions not exposed by the facade @@ -37,18 +37,9 @@ Per-family runtime behaviour is asserted by `src/test/java/org/mobilitydb/flink/ ## 4. MobilityDB SQL-surface cross-check -The facade is also matched against the underlying MEOS C symbol of each addressable `CREATE FUNCTION` in `mobilitydb/sql/**/*.in.sql` (PG-only sections and helper symbols bucketed out; 874 out-of-scope, 113 SQL/plpgsql-composed functions with no single C symbol). Functions the SQL layer implements through the internal MEOS headers (`meos_internal*.h`) are exposed via `MeosOpsSqlSurface`. +The facade is also matched against the underlying MEOS C symbol of each addressable `CREATE FUNCTION` in `mobilitydb/sql/**/*.in.sql` (PG-only sections and helper symbols bucketed out; 876 out-of-scope, 113 SQL/plpgsql-composed functions with no single C symbol). Functions the SQL layer implements through the internal MEOS headers (`meos_internal*.h`) are exposed via `MeosOpsSqlSurface`. -- Addressable distinct C symbols: **1335**; bound by JMEOS: **1065**; exposed by the facade: **1065** (100.0% of the JMEOS-bindable SQL surface). +- Addressable distinct C symbols: **1336**; bound by JMEOS: **1065**; exposed by the facade: **1065** (100.0% of the JMEOS-bindable SQL surface). -- The remaining **270** addressable C symbols are not exported by JMEOS under the name the SQL layer's extension wrapper uses; the wrapper names differ from the MEOS function names they call. - -## 5. Runtime symbol resolution - -Every facade method delegates to a libmeos symbol of the same name. Against a MEOS shared library built with the extended modules (`-DCBUFFER=ON -DNPOINT=ON -DPOSE=ON -DRGEO=ON`), **2277 of 2286** facade methods resolve to an exported symbol. - -The remaining 9 are present in the JMEOS jar but not exported by the MEOS shared library (a JMEOS-jar / library version skew): - -- declared in the public headers, not exported by this build (7): `geog_from_binary`, `nad_stbox_trgeo`, `tfloat_avg_value`, `trgeo_points`, `trgeo_rotation`, `trgeo_segments`, `trgeo_traversed_area` -- not declared in the current public headers, JMEOS jar ahead of the library (2): `tcbuffer_from_mfjson`, `tnpoint_from_mfjson` +- The remaining **271** addressable C symbols are not exported by JMEOS under the name the SQL layer's extension wrapper uses; the wrapper names differ from the MEOS function names they call. diff --git a/flink-processor/src/main/java/org/mobilitydb/flink/meos/MeosOpsParityGaps.java b/flink-processor/src/main/java/org/mobilitydb/flink/meos/MeosOpsParityGaps.java index 34a9d7b..8132180 100644 --- a/flink-processor/src/main/java/org/mobilitydb/flink/meos/MeosOpsParityGaps.java +++ b/flink-processor/src/main/java/org/mobilitydb/flink/meos/MeosOpsParityGaps.java @@ -115,39 +115,11 @@ public static jnr.ffi.Pointer line_substring(jnr.ffi.Pointer arg0, double arg1, return functions.GeneratedFunctions.line_substring(arg0, arg1, arg2); } - /** MEOS {@code mult_float_tfloat} — meos.h · scalar / stateless. */ - public static jnr.ffi.Pointer mult_float_tfloat(double arg0, jnr.ffi.Pointer arg1) { + /** MEOS {@code mindistance_tgeo_tgeo} — meos_geo.h · scalar / stateless. */ + public static double mindistance_tgeo_tgeo(jnr.ffi.Pointer arg0, jnr.ffi.Pointer arg1, double arg2) { if (!MeosOpsRuntime.MEOS_AVAILABLE) - throw new UnsupportedOperationException("mult_float_tfloat requires libmeos — set -Dmobilityflink.meos.enabled=true"); - return functions.GeneratedFunctions.mult_float_tfloat(arg0, arg1); - } - - /** MEOS {@code mult_int_tint} — meos.h · scalar / stateless. */ - public static jnr.ffi.Pointer mult_int_tint(int arg0, jnr.ffi.Pointer arg1) { - if (!MeosOpsRuntime.MEOS_AVAILABLE) - throw new UnsupportedOperationException("mult_int_tint requires libmeos — set -Dmobilityflink.meos.enabled=true"); - return functions.GeneratedFunctions.mult_int_tint(arg0, arg1); - } - - /** MEOS {@code mult_tfloat_float} — meos.h · scalar / stateless. */ - public static jnr.ffi.Pointer mult_tfloat_float(jnr.ffi.Pointer arg0, double arg1) { - if (!MeosOpsRuntime.MEOS_AVAILABLE) - throw new UnsupportedOperationException("mult_tfloat_float requires libmeos — set -Dmobilityflink.meos.enabled=true"); - return functions.GeneratedFunctions.mult_tfloat_float(arg0, arg1); - } - - /** MEOS {@code mult_tint_int} — meos.h · scalar / stateless. */ - public static jnr.ffi.Pointer mult_tint_int(jnr.ffi.Pointer arg0, int arg1) { - if (!MeosOpsRuntime.MEOS_AVAILABLE) - throw new UnsupportedOperationException("mult_tint_int requires libmeos — set -Dmobilityflink.meos.enabled=true"); - return functions.GeneratedFunctions.mult_tint_int(arg0, arg1); - } - - /** MEOS {@code mult_tnumber_tnumber} — meos.h · scalar / stateless. */ - public static jnr.ffi.Pointer mult_tnumber_tnumber(jnr.ffi.Pointer arg0, jnr.ffi.Pointer arg1) { - if (!MeosOpsRuntime.MEOS_AVAILABLE) - throw new UnsupportedOperationException("mult_tnumber_tnumber requires libmeos — set -Dmobilityflink.meos.enabled=true"); - return functions.GeneratedFunctions.mult_tnumber_tnumber(arg0, arg1); + throw new UnsupportedOperationException("mindistance_tgeo_tgeo requires libmeos — set -Dmobilityflink.meos.enabled=true"); + return functions.GeneratedFunctions.mindistance_tgeo_tgeo(arg0, arg1, arg2); } /** MEOS {@code nsegment_end_position} — meos_npoint.h · scalar / stateless. */ @@ -276,6 +248,13 @@ public static jnr.ffi.Pointer tfloatseqset_from_base_tstzspanset(double arg0, jn return functions.GeneratedFunctions.tfloatseqset_from_base_tstzspanset(arg0, arg1, arg2); } + /** MEOS {@code tgeoarr_tgeoarr_mindist} — meos_geo.h · scalar / stateless. */ + public static double tgeoarr_tgeoarr_mindist(jnr.ffi.Pointer arg0, int arg1, jnr.ffi.Pointer arg2, int arg3) { + if (!MeosOpsRuntime.MEOS_AVAILABLE) + throw new UnsupportedOperationException("tgeoarr_tgeoarr_mindist requires libmeos — set -Dmobilityflink.meos.enabled=true"); + return functions.GeneratedFunctions.tgeoarr_tgeoarr_mindist(arg0, arg1, arg2, arg3); + } + /** MEOS {@code tgeoseq_from_base_tstzset} — meos_geo.h · whole-sequence constructor — not a per-event op. */ public static jnr.ffi.Pointer tgeoseq_from_base_tstzset(jnr.ffi.Pointer arg0, jnr.ffi.Pointer arg1) { if (!MeosOpsRuntime.MEOS_AVAILABLE) diff --git a/flink-processor/tools/parity/emit_gap_methods.py b/flink-processor/tools/parity/emit_gap_methods.py index ef895a5..7d86776 100644 --- a/flink-processor/tools/parity/emit_gap_methods.py +++ b/flink-processor/tools/parity/emit_gap_methods.py @@ -15,10 +15,13 @@ import re, os, sys, glob HERE = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -INC = "/home/esteban/src/MobilityDB/meos/include" +INC = os.environ.get("MEOS_INCLUDE", "/home/esteban/src/MobilityDB/meos/include") PUBLIC_HEADERS = ["meos.h", "meos_geo.h", "meos_cbuffer.h", "meos_npoint.h", "meos_pose.h", "meos_rgeo.h"] FACADE = os.path.join(HERE, "src/main/java/org/mobilitydb/flink/meos") OUT = os.path.join(FACADE, "MeosOpsParityGaps.java") +# Forwarder facades are themselves derived; the "already covered" baseline is the +# tier-aware generated OO classes only, so the generator reproduces idempotently. +DERIVED = {"MeosOpsParityGaps.java", "MeosOpsSqlSurface.java"} _DECL = re.compile(r'^\s*extern\s+.+?\b([a-z][A-Za-z0-9_]*)\s*\(', re.M) _PUBSTATIC = re.compile(r'public static [A-Za-z0-9_.<>\[\]]+ ([a-z0-9_]+)\(') @@ -45,6 +48,8 @@ def main(): pub.add(n); fam.setdefault(n, h) facade = set() for f in glob.glob(os.path.join(FACADE, "MeosOps*.java")): + if os.path.basename(f) in DERIVED: + continue facade |= set(_PUBSTATIC.findall(open(f).read())) # all JMEOS signatures, grouped by name sigs = {}