Skip to content

Implement compact CLTJ (no try-switching), benchmark vs the array LTJ, add the paper's RDF benchmark #66

Description

@matiastoro

Motivation

The current join engine is described as LTJ but is a simplified array implementation, not the compact CLTJ from the paper (Arroyuelo et al., VLDBJ 2025; C++ reference in cltj/). Implement the real compact structure, benchmark it head-to-head against the array version, and reproduce the paper's RDF benchmark.

Current state (feasibility)

  • TripleIndex (src/runtime/ltj/triple_index.rs) stores orderings: [Vec<IndexEntry>; 6] — six fully-materialized sorted arrays of (u32, u32, u32, u32) tuples (~172 MiB at SF0.1).
  • CLTJ in the paper is not a wavelet tree: cltj/include/trie/cltj_compact_trie.hpp is a LOUDS-style compact trie — a topology bit_vector (unary child-count encoding, one 0 per node) with succ0/select0 support, plus a bit-compressed int_vector of symbols. Navigation is child(it, n) = select0(it + gap + n), children(i) = succ0(i+1) − i; the leapfrog seek is a binary search over the symbol sequence within a node's child block (binary_search_seek).
  • The paper's index still keeps six orderings (SPO/SOP/POS/PSO/OSP/OPS), as compact tries, in two variants:
    • cltj_index_spo_basic — six full compact tries;
    • cltj_index_metatrie — the more compact variant: each ordering pair shares its root level (subject/object bitvectors with rank/succ; predicates are contiguous), so odd tries store only levels 1–2.
  • So the compaction win over our arrays is "6 sorted tuple-arrays → 6 LOUDS tries (or root-shared metatries) with bit-packed symbols", not "6 arrays → 1 wavelet tree".
  • Try-switching: run_join / run_concat_pattern (src/runtime/engine.rs) attempt LTJ and fall back to pairwise hash-join for non-decomposable patterns (undirected edges, unions, repetitions). This item asks for a pure CLTJ path (no fallback) to measure CLTJ in isolation.

Scope

  1. Compact CLTJ index: LOUDS compact tries (Rust rank/select bitvector + bit-packed symbol sequence). Two tiers: port cltj_index_spo_basic first (six full tries, direct analog of the array index, easiest to differential-test), then optionally the metatrie root-sharing.
  2. A no-fallback CLTJ execution path for measurement.
  3. Add the CLTJ paper's RDF / BGP benchmark (e.g. Wikidata triple-pattern queries, files in cltj/Queries/) — a different workload from the current LDBC property-graph harness (bench/cross-system/). Compare against the cltj/ C++ reference and the array LTJ.

Large. The succinct data structure is a substantial implementation effort; the RDF benchmark is a new bench workload.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performanceSpeed / memory optimizationresearchResearch / evaluation / spike

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions