Skip to content

[Engine] Implement Streaming HashAggregation for GROUP BY queries (Q8 bottleneck) #635

Closed

Description

@remiceres

Summary

Replace the current in-memory sort-based aggregation in Group.java with a streaming hash aggregation table to resolve the major query latency bottleneck identified on Q8.

Problem Description

On the Bowlogna benchmark (1.23M triples), Corese v5 executes 16 reference queries in 2,226 ms. Query Q8 alone takes 1,137 ms (51.1% of the entire benchmark runtime). While queries without massive grouping beat Apache Jena, Q8 severely lags due to sort-based aggregation which materializes and sorts all solutions in memory ((N \log N)$ time and large heap footprint).

Technical Scope & Objectives

  1. Accurate Profiling: Confirm the execution breakdown of Q8 (time in pattern join vs time in aggregation).
  2. Streaming HashAggregation:
    • Accumulate grouping keys directly in an on-the-fly hash map: GroupKey -> AccumulatorSet (Count/Sum/Avg/Min/Max).
    • Update accumulators iteratively as solution tuples arrive ((N)$ average time).
  3. SPARQL 1.1 Specification Conformance:
    • Preserve correct handling of unbound variables, empty groups, and multiple grouping expressions.
    • Support COUNT(DISTINCT ?var) with nested distinct value sets.
    • Ensure proper error state propagation during aggregate evaluation.

Acceptance Criteria

  • Profiling data on Q8 confirms aggregation cost before and after implementation.
  • Streaming HashAggregation operates with (N)$ time complexity on streaming inputs.
  • Q8 execution time on Bowlogna drops significantly (target: sub-300 ms).
  • 100% pass on all existing W3C SPARQL 1.1 aggregate test cases.

Activity

  1. added
    featureNew feature or capability
    refactoringInternal code restructuring and architecture cleanup
    on Oct 20, 2026
  2. self-assigned this
    on Oct 20, 2026
  3. remiceres commented on Oct 21, 2026

    @remiceres
    ContributorAuthor

    🚀 Step 1 Validée & Committée (eb1d19bc9)

    Remplacement de l'ordonnancement par arbre de Group.java par une table de hachage LinkedHashMap<GroupKey, Mappings> :

    • Clé de groupe immuable : encapsulation défensive d'un tuple Node[] avec equals et hashCode respectant strictement la spécification SPARQL 1.1 W3C (variables non liées null, datatypes, langues, blank nodes).
    • Complexité : passage d'un coût moyen d'insertion (N \log N)$ à (1)$.
    • Tests & Qualité :
      • 35/35 tests unitaires passés dans la nouvelle suite GroupTest.java.
      • 0 alerte SonarLint LSP.
      • Suite de tests corese-core 100% verte.
    • Résultats préliminaires Bowlogna : Q8 passe de 1 137 ms à 918 ms (-19%).
    • En cours : Step 2 (accumulateurs scalaires au fil de l'eau pour éliminer la matérialisation des mappings membres et passer sous les 300 ms).
  4. remiceres commented on Oct 21, 2026

    @remiceres
    ContributorAuthor

    ⚡ Step 2 Validée & Committée (da8e5cfba) : Direct Scalar Group Aggregation

    Introduction du composant DirectGroupAggregation.java dans Mappings.aggregate() pour les requêtes GROUP BY avec projections scalaires :

    Réalisations :

    • Accumulation en une seule passe : élimination de l'allocation des listes de mappings membres par groupe. Seul le premier mapping représentant et l'état scalaire des accumulateurs (COUNT, SUM, AVG, MIN, MAX) sont retenus par clé de groupe.
    • Gestion des types & Erreurs W3C : intégration avec NumericAccumulator pour les promotions numériques transparentes (integer $\rightarrow$ decimal $\rightarrow$ double) et isolation stricte des erreurs de type (une erreur d'évaluation sur une projection invalide cette projection sans impacter les autres).
    • Repli automatique sécurisé : vérification stricte d'éligibilité via isEligible(Query) pour préserver le chemin standard lors d'usage de modificateurs complexes.

    Résultats Bowlogna (1,23M triplets) :

    • Q8 (GROUP BY ?X + COUNT(?E)) : nouvelle baisse de latence à 760 ms (vs 918 ms après Step 1, et 1 830 ms sous Corese 4.6.5 $\rightarrow$ accélération de 2,4x / -58%).
    • Q9 : 207 ms (vs 650 ms sous 4.6.5 $\rightarrow$ 3,1x plus rapide).
    • Qualité & Tests : 0 alerte SonarLint LSP, suite unitaire dédiée DirectGroupAggregationTest 100% passante, et suite complète corese-core 100% verte.
  5. remiceres commented on Oct 21, 2026

    @remiceres
    ContributorAuthor

    Résolu et clôturé par le merge de la PR #639 dans feature/corese-next.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

featureNew feature or capabilityrefactoringInternal code restructuring and architecture cleanup

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions