From 5a60249bffc07bc4aadd7c9b1f7a287a42bc6c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20Zim=C3=A1nyi?= Date: Fri, 2 Oct 2026 10:47:58 +0200 Subject: [PATCH] Keep MeosSetSetJoin in the benchmark module alone MeosSetSetJoin, the hand-written NxN set-set join over two arrays of temporal geometries, lives in the benchmark module, which calls it (BerlinMODSetSetJoinTest) and depends on no other module of the build. The binding module, a pure projection of the MEOS surface with no application or benchmark code as its pom states, carries no copy of it. GENERATION.md names the module the class lives in. Measured. Against MobilityDB 85ad3e2891, the catalog of MEOS-API 1c50d3611a and the generator and jar of JMEOS main 52432a1d, mvn clean test under Maven 3.9.16 builds both modules with no warning line and the 18 and 12 tests pass, the three BerlinMODSetSetJoinTest cases among them. --- GENERATION.md | 2 +- .../org/mobilitydb/meos/MeosSetSetJoin.java | 130 ------------------ 2 files changed, 1 insertion(+), 131 deletions(-) delete mode 100644 binding/src/main/java/org/mobilitydb/meos/MeosSetSetJoin.java diff --git a/GENERATION.md b/GENERATION.md index c3a6edc..64077f1 100644 --- a/GENERATION.md +++ b/GENERATION.md @@ -79,7 +79,7 @@ The `MeosOps*` facades are emitted at build time and are **not committed**: Mave `generate-sources` runs `tools/codegen_jvm.py --engine flink` into `target/generated-facades`, and `build-helper` adds it as a source root. Only the generator is tracked; the catalog and the JMEOS jar are all derived in CI, and the sole hand-written class under -`org.mobilitydb.meos` is `MeosSetSetJoin`. +`org.mobilitydb.meos` is `MeosSetSetJoin`, in the benchmark module. ## Surface match diff --git a/binding/src/main/java/org/mobilitydb/meos/MeosSetSetJoin.java b/binding/src/main/java/org/mobilitydb/meos/MeosSetSetJoin.java deleted file mode 100644 index 08ea2cb..0000000 --- a/binding/src/main/java/org/mobilitydb/meos/MeosSetSetJoin.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.mobilitydb.meos; - -import com.kenai.jffi.MemoryIO; -import functions.GeneratedFunctions; -import java.lang.ref.Reference; -import jnr.ffi.Memory; -import jnr.ffi.Pointer; -import jnr.ffi.Runtime; - -/** - * NxN cross-stream set-set join operator over two arrays of temporal geometries. - * - *

Each method marshals two Java {@code Pointer[]} (one per stream window) into native - * pointer arrays and calls the MEOS NxN array spatial-relationship functions, returning the - * matching {@code [i, j]} index pairs (and, for tDwithin, the per-pair intersection periods - * as hex-WKB span sets): - *

- * - *

The backing C functions take {@code (Temporal **arr1, int n1, Temporal **arr2, int n2, - * [double dist,] int *count [, SpanSet ***periods])} and return a flat {@code int *} of - * {@code 2*count} indices (caller frees). Native result buffers are freed through jffi's {@code MemoryIO}, which calls the system - * free MEOS allocates with. - */ -public final class MeosSetSetJoin { - private static final MemoryIO IO = MemoryIO.getInstance(); - - private MeosSetSetJoin() { - } - - public static int[][] eDwithinPairs(Pointer[] a, Pointer[] b, double dist) { - if (a == null || b == null || a.length == 0 || b.length == 0) { - return new int[0][]; - } - Runtime rt = Runtime.getSystemRuntime(); - Pointer arr1 = marshal(a, rt); - Pointer arr2 = marshal(b, rt); - Pointer countPtr = Memory.allocateDirect(rt, 4); - Pointer res = GeneratedFunctions.edwithin_tgeoarr_tgeoarr(arr1, a.length, arr2, b.length, dist, countPtr); - Reference.reachabilityFence(arr1); - Reference.reachabilityFence(arr2); - return readPairsAndFree(res, countPtr.getInt(0L)); - } - - public static int[][] aDisjointPairs(Pointer[] a, Pointer[] b) { - if (a == null || b == null || a.length == 0 || b.length == 0) { - return new int[0][]; - } - Runtime rt = Runtime.getSystemRuntime(); - Pointer arr1 = marshal(a, rt); - Pointer arr2 = marshal(b, rt); - Pointer countPtr = Memory.allocateDirect(rt, 4); - Pointer res = GeneratedFunctions.adisjoint_tgeoarr_tgeoarr(arr1, a.length, arr2, b.length, countPtr); - Reference.reachabilityFence(arr1); - Reference.reachabilityFence(arr2); - return readPairsAndFree(res, countPtr.getInt(0L)); - } - - public static TDwithin tDwithinPairs(Pointer[] a, Pointer[] b, double dist) { - if (a == null || b == null || a.length == 0 || b.length == 0) { - return new TDwithin(new int[0][], new String[0]); - } - Runtime rt = Runtime.getSystemRuntime(); - Pointer arr1 = marshal(a, rt); - Pointer arr2 = marshal(b, rt); - Pointer countPtr = Memory.allocateDirect(rt, 4); - Pointer periodsPtr = Memory.allocateDirect(rt, 8); - Pointer res = GeneratedFunctions.tdwithin_tgeoarr_tgeoarr(arr1, a.length, arr2, b.length, dist, countPtr, periodsPtr); - Reference.reachabilityFence(arr1); - Reference.reachabilityFence(arr2); - int cnt = countPtr.getInt(0L); - if (res == null || cnt == 0) { - return new TDwithin(new int[0][], new String[0]); - } - Pointer ssArr = periodsPtr.getPointer(0L); - int[][] pairs = new int[cnt][2]; - String[] periods = new String[cnt]; - for (int k = 0; k < cnt; ++k) { - pairs[k][0] = res.getInt((long) (2 * k) * 4L); - pairs[k][1] = res.getInt((long) (2 * k + 1) * 4L); - Pointer ss = ssArr == null ? null : ssArr.getPointer((long) k * 8L); - periods[k] = ss == null ? null : GeneratedFunctions.spanset_as_hexwkb(ss, (byte) 0); - free(ss); - } - free(ssArr); - free(res); - return new TDwithin(pairs, periods); - } - - private static Pointer marshal(Pointer[] xs, Runtime rt) { - Pointer buf = Memory.allocateDirect(rt, xs.length * 8); - for (int i = 0; i < xs.length; ++i) { - buf.putPointer((long) i * 8L, xs[i]); - } - return buf; - } - - private static int[][] readPairsAndFree(Pointer res, int cnt) { - if (res == null || cnt == 0) { - return new int[0][]; - } - int[][] out = new int[cnt][2]; - for (int k = 0; k < cnt; ++k) { - out[k][0] = res.getInt((long) (2 * k) * 4L); - out[k][1] = res.getInt((long) (2 * k + 1) * 4L); - } - free(res); - return out; - } - - private static void free(Pointer p) { - if (p != null) { - IO.freeMemory(p.address()); - } - } - - /** Result of {@link #tDwithinPairs}: matching index pairs + each pair's intersection periods (hex-WKB). */ - public static final class TDwithin { - public final int[][] pairs; - public final String[] periodsHexwkb; - - TDwithin(int[][] pairs, String[] periodsHexwkb) { - this.pairs = pairs; - this.periodsHexwkb = periodsHexwkb; - } - } -}