Skip to content

feat(clp-s): Support per-archive min and max aggregation output to stdout and the results cache.#2345

Open
davemarco wants to merge 57 commits into
y-scope:mainfrom
davemarco:min-max
Open

feat(clp-s): Support per-archive min and max aggregation output to stdout and the results cache.#2345
davemarco wants to merge 57 commits into
y-scope:mainfrom
davemarco:min-max

Conversation

@davemarco

@davemarco davemarco commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Description

Adds --min and --max search aggregations, computing the minimum/maximum value of a numeric field and writing the result to stdout or the results cache. Continues the aggregation work from #2326 and #2342.

Outputs one document per archive, for both destinations:

{archive_id, field, min|max}

Changes

  • Adds --min FIELD / --max FIELD, supported by both the stdout and results-cache destinations.
  • New MinMaxAggregation reads the field from each matched record and tracks the running min/max
  • Compares int64_t and double operands exactly
  • Reworks aggregation output into a aggregator + sink design that scales as more aggregations/sinks are added

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

Validated a few queries on mongoDb dataset

Summary by CodeRabbit

  • New Features
    • Added search result aggregations: count, count-by-time (bucketed), and min/max for a selected numeric field.
    • Aggregation output can now be routed through output handlers, including writing results to both standard output and the results cache.
    • Command-line aggregation options are centralized, with clear validation for supported combinations.
  • Bug Fixes
    • Improved min/max evaluation for large integers and mixed numeric types, plus safer field descriptor handling.
    • Count and count-by-time now correctly handle zero/empty cases.
  • Other
    • Aggregation-not-supported remains non-fatal, allowing IR-stream searching to continue when applicable.

davemarco and others added 15 commits June 11, 2026 13:36
…e results cache.

Allows --count and --count-by-time to be used with the results-cache output handler, writing aggregation results directly to MongoDB via _id-keyed atomic $inc upserts so that partial results from multiple search processes merge correctly without a reducer.
…he search usage text outputs to the reducer.
…dout.

Adds `--count` and `--count-by-time` to the stdout output handler, emitting per-archive results as newline-delimited JSON. The options may be given without naming the `stdout` handler (e.g. `clp-s s <archives> <query> --count`), and the kv-ir search path now reports these aggregations as unsupported, consistent with the reducer and results-cache handlers.
… results cache.

Adds --min/--max <field> aggregations, extracting the field's numeric value from each matched record's marshalled JSON. Unifies the results-cache count handlers into a single AggregationToResultsCacheOutputHandler handling count, count-by-time, min, and max.
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds variant-based aggregation types, sinks, and CLI parsing for search. Replaces count-specific results-cache handlers with a single aggregation-aware output handler, updates runtime handler selection, and adds exact int/double comparison helpers plus shared MongoDB connection logic.

Changes

Aggregation Framework

Layer / File(s) Summary
Aggregation types and comparison helpers
components/core/src/clp_s/Aggregation.hpp, components/core/src/clp_s/IntFloatCompare.hpp, components/core/src/clp_s/archive_constants.hpp
Defines AggregationValue, AggregationResult, the Aggregation variant, CountAggregation, CountByTimeAggregation, MinMaxAggregation, the cMin/cMax/cField constants, and exact int64_t/double comparison overloads.
Aggregation implementations
components/core/src/clp_s/Aggregation.cpp
Implements cached result generation, min/max field-path parsing and record handling, extreme comparison, and aggregation capability queries.
Aggregation sinks and MongoDB connection helper
components/core/src/clp_s/AggregationSink.hpp, components/core/src/clp_s/AggregationSink.cpp, components/core/src/clp_s/ResultsCacheUtils.hpp, components/core/src/clp_s/ResultsCacheUtils.cpp
Declares the sink interface, implements stdout JSON output and MongoDB bulk result caching, and adds the shared connect_to_results_cache helper.
Command-line aggregation parsing and validation
components/core/src/clp_s/CommandLineArguments.hpp, components/core/src/clp_s/CommandLineArguments.cpp, components/core/src/clp_s/CMakeLists.txt
Replaces per-handler aggregation fields with a global aggregation option group, stores the parsed aggregation, enforces handler compatibility, and registers the new sources in the executable build list.
AggregationOutputHandler refactor
components/core/src/clp_s/OutputHandlerImpl.hpp, components/core/src/clp_s/OutputHandlerImpl.cpp
Replaces the count-specific results-cache handlers with a single aggregation-aware handler that forwards records into the active aggregation and writes final results through an AggregationSink.
Search runtime wiring
components/core/src/clp_s/clp-s.cpp, components/core/src/clp_s/kv_ir_search.hpp, components/core/src/clp_s/kv_ir_search.cpp
Updates search output-handler selection to use the parsed aggregation variant and simplifies the KV IR search aggregation guard to check get_aggregation() directly.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • y-scope/clp#2229: Changes CommandLineArguments.{cpp,hpp} around aggregation option parsing and output-handler routing, which overlaps with the global aggregation parsing changes here.
  • y-scope/clp#2326: Touches the same count/count-by-time results-cache path that is now replaced by AggregationOutputHandler and AggregationSink.

Suggested reviewers

  • gibber9809
  • davidlion
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 24.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding per-archive min/max aggregation output for stdout and the results cache.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@davidlion davidlion left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick pass to try and speed things up.

#include "../clp/type_utils.hpp"
#include "../reducer/types.hpp"
#include "FileReader.hpp"
#include "search/ast/SearchUtils.hpp"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include "search/ast/SearchUtils.hpp"
#include <clp_s/search/ast/SearchUtils.hpp>

For new include statements let's follow the new guidelines to always use <>.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was marked resolved, but the change was never applied...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry fixed

Comment thread components/core/src/clp_s/CommandLineArguments.cpp Outdated
std::map<std::string, po::options_description const*> const& subcommands,
std::vector<std::string> const& options
std::vector<std::string> const& options,
std::optional<std::string> const& default_subcommand = std::nullopt

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update doc string with this param + update description.


StdoutOutputHandlerOptions stdout_options{};
po::options_description stdout_output_handler_options("Stdout Output Handler Options");
// clang-format off

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How ugly is it if we just let clang-format do it now? I feel like this might be unnecessary since it is likely a from very early on.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see stdout pr

Comment thread components/core/src/clp_s/CommandLineArguments.hpp Outdated
Comment thread components/core/src/clp_s/CommandLineArguments.hpp Outdated
davemarco added 12 commits June 25, 2026 11:06
…ers.

- Take string_view for the results-cache handler uri/collection/dataset/archive_id
  params and materialize std::string only at the mongocxx call sites.
- Drop the redundant ::clp_s:: qualifier on the count handlers' base class.
- Rename the count-by-time write timestamp param to timestamp_ms to match the
  bucket size unit.
…n handler.

Merges the results-cache count work and applies the same review fixes to
AggregationToStdoutOutputHandler: take string_view for archive_id, drop the
redundant ::clp_s:: qualifier on the base class, rename the count-by-time
bucket size to count_by_time_bucket_size_ms, and rename the count-by-time
write timestamp param to timestamp_ms.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
components/core/src/clp_s/Aggregation.cpp (1)

95-100: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Handle number_unsigned before casting to int64_t.

is_number_integer() also matches unsigned JSON values here, so node->get<int64_t>() can turn a value above INT64_MAX into the wrong signed extreme and poison both --min and --max results. Please branch on is_number_unsigned(), range-check it, and skip or reject out-of-range values instead of narrowing them through int64_t.

Proposed fix
-    Extreme const candidate{
-            node->is_number_integer() ? Extreme{node->get<int64_t>()} : Extreme{node->get<double>()}
-    };
+    Extreme candidate;
+    if (node->is_number_unsigned()) {
+        auto const value{node->get<uint64_t>()};
+        if (value > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
+            return;
+        }
+        candidate = static_cast<int64_t>(value);
+    } else if (node->is_number_integer()) {
+        candidate = node->get<int64_t>();
+    } else {
+        candidate = node->get<double>();
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/core/src/clp_s/Aggregation.cpp` around lines 95 - 100, The numeric
handling in `Aggregation::` currently treats unsigned JSON numbers as integers
via `is_number_integer()`, which can narrow values above `INT64_MAX` into the
wrong `Extreme` and corrupt min/max aggregation. Update the branch that builds
`candidate` to handle `is_number_unsigned()` explicitly before
`node->get<int64_t>()`, add a range check for values that cannot fit in
`int64_t`, and skip or reject those out-of-range values instead of casting them
through `int64_t`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@components/core/src/clp_s/Aggregation.cpp`:
- Around line 95-100: The numeric handling in `Aggregation::` currently treats
unsigned JSON numbers as integers via `is_number_integer()`, which can narrow
values above `INT64_MAX` into the wrong `Extreme` and corrupt min/max
aggregation. Update the branch that builds `candidate` to handle
`is_number_unsigned()` explicitly before `node->get<int64_t>()`, add a range
check for values that cannot fit in `int64_t`, and skip or reject those
out-of-range values instead of casting them through `int64_t`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 652926cd-0e0c-4348-a1a8-e1596dab4095

📥 Commits

Reviewing files that changed from the base of the PR and between 1a3b902 and e95f81b.

📒 Files selected for processing (7)
  • components/core/src/clp_s/Aggregation.cpp
  • components/core/src/clp_s/Aggregation.hpp
  • components/core/src/clp_s/AggregationSink.cpp
  • components/core/src/clp_s/AggregationSink.hpp
  • components/core/src/clp_s/IntFloatCompare.hpp
  • components/core/src/clp_s/OutputHandlerImpl.cpp
  • components/core/src/clp_s/ResultsCacheUtils.hpp
💤 Files with no reviewable changes (1)
  • components/core/src/clp_s/OutputHandlerImpl.cpp

…reducer dispatch, rename aggregation error.

- CountByTimeAggregation rejects non-positive bucket sizes.
- ResultsCacheSink clears its buffer after a successful flush to avoid duplicate inserts.
- Reducer output dispatch handles count-by-time explicitly and throws on unsupported aggregations.
- Rename KvIrSearchErrorEnum::CountSupportNotImplemented to AggregationSupportNotImplemented.
@davemarco davemarco requested a review from davidlion June 28, 2026 20:10
…er clang-tidy.

Make connect_to_results_cache a non-template function defined in
ResultsCacheUtils.cpp instead of a header-only template. The template existed
only to throw each caller's nested OperationFailed, but the call sites are caught
as std::exception and TraceableException::what() ignores the exception type, so
collapsing them into a single ResultsCacheConnectionError is behavior-preserving.

This also gives the header a sibling .cpp, so clang-tidy resolves the mongocxx
include path (header-only templates fall back to a non-mongo compile command and
fail with "mongocxx/client.hpp file not found"). Removes the now-dead nested
OperationFailed classes and the reducer parse-time comment.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/core/src/clp_s/ResultsCacheUtils.cpp`:
- Around line 20-22: The URI handling in the cache setup currently accepts a
missing database name and still returns a collection handle from
client[mongo_uri.database()], which can create an unusable empty database
reference. Update the helper that builds the mongocxx::uri and client to
validate mongo_uri.database() before accessing the collection, and fail fast
with ErrorCodeBadParamDbUri when the database component is empty. Keep the check
close to the return path so the function only returns a valid
client[database][collection] handle when the URI includes a database name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 359ca3f7-68ba-48b4-abd8-9345fb9add80

📥 Commits

Reviewing files that changed from the base of the PR and between 069a495 and f6b8b4f.

📒 Files selected for processing (9)
  • components/core/src/clp_s/AggregationSink.cpp
  • components/core/src/clp_s/AggregationSink.hpp
  • components/core/src/clp_s/CMakeLists.txt
  • components/core/src/clp_s/IntFloatCompare.hpp
  • components/core/src/clp_s/OutputHandlerImpl.cpp
  • components/core/src/clp_s/OutputHandlerImpl.hpp
  • components/core/src/clp_s/ResultsCacheUtils.cpp
  • components/core/src/clp_s/ResultsCacheUtils.hpp
  • components/core/src/clp_s/clp-s.cpp
💤 Files with no reviewable changes (3)
  • components/core/src/clp_s/clp-s.cpp
  • components/core/src/clp_s/AggregationSink.hpp
  • components/core/src/clp_s/OutputHandlerImpl.hpp

Comment thread components/core/src/clp_s/ResultsCacheUtils.cpp
Comment thread components/core/src/clp_s/ResultsCacheUtils.hpp
Comment on lines +22 to +24
#include "Aggregation.hpp"
#include "AggregationSink.hpp"
#include "CommandLineArguments.hpp"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swap to <clp_s/...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switched the new project headers to <clp_s/…>.

#include "../reducer/network_utils.hpp"
#include "../reducer/Record.hpp"
#include "archive_constants.hpp"
#include "ResultsCacheUtils.hpp"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<clp_s/...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switched the new project headers to <clp_s/…>.

Comment thread components/core/src/clp_s/Aggregation.hpp Outdated
Comment thread components/core/src/clp_s/aggregators.hpp
Comment on lines +24 to +31
// Destructor
virtual ~AggregationSink() = default;

// Explicitly disable copy and move constructor/assignment
AggregationSink(AggregationSink const&) = delete;
auto operator=(AggregationSink const&) -> AggregationSink& = delete;
AggregationSink(AggregationSink&&) = delete;
auto operator=(AggregationSink&&) -> AggregationSink& = delete;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this particular change/rule is new and my fault for not getting around to updating the guidelines yet.

Suggested change
// Destructor
virtual ~AggregationSink() = default;
// Explicitly disable copy and move constructor/assignment
AggregationSink(AggregationSink const&) = delete;
auto operator=(AggregationSink const&) -> AggregationSink& = delete;
AggregationSink(AggregationSink&&) = delete;
auto operator=(AggregationSink&&) -> AggregationSink& = delete;
// Delete copy constructor and assignment operator
AggregationSink(AggregationSink const&) = delete;
auto operator=(AggregationSink const&) -> AggregationSink& = delete;
// Delete move constructor and assignment operator
AggregationSink(AggregationSink&&) = delete;
auto operator=(AggregationSink&&) -> AggregationSink& = delete;
// Destructor
virtual ~AggregationSink() = default;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied the suggested ordering.

@davidlion davidlion left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all minor naming and style changes

#include <boost/program_options/variables_map.hpp>

#include "../reducer/types.hpp"
#include "Aggregation.hpp"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style nit, use <clp_s/...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment thread components/core/src/clp_s/aggregators.hpp
Comment on lines +64 to +65
static constexpr bool cNeedsMetadata = false;
static constexpr bool cNeedsMarshalledRecord = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style nit (shows up in other places too)

Suggested change
static constexpr bool cNeedsMetadata = false;
static constexpr bool cNeedsMarshalledRecord = false;
static constexpr bool cNeedsMetadata{false};
static constexpr bool cNeedsMarshalledRecord{false};

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment on lines +1218 to +1220
if (false == m_aggregation.has_value()
|| std::holds_alternative<MinMaxAggregation>(m_aggregation.value()))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai Please make a issue to remove the old reducer code that shouldn't be used anymore.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh repo view y-scope/clp --json nameWithOwner -q .nameWithOwner
fd . components/core/src/reducer -t f | head -50
rg -n "Count" components/core/src/reducer -l | head -30

Length of output: 2961


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="y-scope/clp"

body=$(cat <<'EOF'
## Summary

Follow-up from PR `#2345` (aggregation pipeline refactor for `clp-s`), as requested by `@davidlion` in this comment thread: https://github.com/y-scope/clp/pull/2345#discussion_r3526356325

PR `#2345` introduces a new variant-based `Aggregation`/`AggregationSink` design in `clp_s` (see `components/core/src/clp_s/Aggregation.hpp`, `Aggregation.cpp`, `AggregationSink.hpp`, `AggregationSink.cpp`) and reworks how aggregation results are produced and dispatched to output handlers (`components/core/src/clp_s/OutputHandlerImpl.hpp/.cpp`, `CommandLineArguments.cpp`, `clp-s.cpp`). The reducer output handler path currently still only supports `count` and `count-by-time` aggregations (see the validation added in `CommandLineArguments::parse_reducer_output_handler_options` in `components/core/src/clp_s/CommandLineArguments.cpp`), leaving older reducer-related code that predates this refactor and may no longer be needed now that `clp_s` computes aggregations internally.

## Required changes

- Audit the reducer output handler code path in `clp_s` (`components/core/src/clp_s/CommandLineArguments.cpp`, `components/core/src/clp_s/OutputHandlerImpl.hpp/.cpp`, `components/core/src/clp_s/clp-s.cpp`) to identify logic/classes that were only needed to support the pre-refactor count/count-by-time aggregation flow and are now superseded or redundant.
- Audit the standalone reducer service module (`components/core/src/reducer/`, e.g. `CountOperator.cpp/.hpp`, `Pipeline.cpp/.hpp`, `Operator.cpp/.hpp`) to determine which pieces are still required by `clp_s` versus code that was only used by the old aggregation design.
- Remove or refactor any code identified as dead/obsolete, keeping only what's needed to support the current reducer output handler (count and count-by-time) and any future extensions.
- Update or add tests as needed to reflect the removal.

## Affected areas

- `components/core/src/clp_s/CommandLineArguments.cpp` / `.hpp`
- `components/core/src/clp_s/OutputHandlerImpl.cpp` / `.hpp`
- `components/core/src/clp_s/clp-s.cpp`
- `components/core/src/reducer/` (e.g. `CountOperator.cpp/.hpp`, `Pipeline.cpp/.hpp`, `Operator.cpp/.hpp`)

## Acceptance criteria

- Old/unused reducer-related code paths that are no longer exercised after the aggregation refactor are identified and removed.
- Existing reducer output handler functionality (count, count-by-time) continues to work as before.
- No dead code remains referencing the pre-refactor aggregation approach.

## References

- PR: https://github.com/y-scope/clp/pull/2345
- Comment: https://github.com/y-scope/clp/pull/2345#discussion_r3526356325

Requested by: `@davidlion`
EOF
)

issue_url=$(gh issue create \
  --repo "$repo" \
  --title "Remove obsolete reducer output handler code after aggregation refactor" \
  --body "$body" \
  --assignee davidlion)

echo "$issue_url"

Length of output: 3103


@davidlion, done — I've created #2366 to track removing the old reducer-related code that's no longer needed after this aggregation refactor, assigned to you with backlinks to this PR and comment.


🧬 Code Graph Analysis Results

components/core/src/clp_s/CommandLineArguments.hpp

Relevant for reducer-related CLI behavior removal (it exposes how the reducer output handler is represented/parsed):

  • Lines 118-120

    auto get_output_handler_options() const -> OutputHandlerOptionsVariant const& {
            return m_output_handler_options;
        }
  • Lines 188-192

    parse_reducer_output_handler_options(
                boost::program_options::options_description const& options_description,
                std::vector<std::string> const& options,
                ReducerOutputHandlerOptions& reducer_options
        )
  • Lines 179-179

    reject_aggregation_for_handler(std::string_view handler_name) const -> void
  • Lines 168-172

    parse_aggregation_options(
                boost::program_options::variables_map const& parsed_options,
                int64_t count_by_time_bucket_size_ms,
                std::string_view aggregation_field
        ) -> std::optional<Aggregation>

🧠 Learnings used
Learnt from: SharafMohamed
Repo: y-scope/clp PR: 1313
File: components/core/tests/test-SchemaSearcher.cpp:136-137
Timestamp: 2025-12-09T01:57:04.839Z
Learning: In C++ files under the components directory, keep forward declarations even when a definition follows in the same scope (such as in anonymous namespaces) to maintain consistency across multiple methods. This style reduces churn and aligns with the existing convention in this repository for both source and tests.

Learnt from: ShangDanLuXian
Repo: y-scope/clp PR: 2010
File: components/core/src/clp_s/filter/FilterBuilder.cpp:24-33
Timestamp: 2026-02-20T15:19:43.528Z
Learning: In the components/core/src/clp_s module, FileWriter usage across multipleCpp files (e.g., JsonConstructor.cpp, SchemaMap.cpp, FilterBuilder.cpp) intentionally omits try-catch around write operations, and treats potential write failures as acceptable data loss. Do not add per-write try-catch in these files; instead, rely on the caller/integration layer to handle exceptions. Apply this pattern to similar FileWriter usage within this module, ensuring reviewers understand that error handling is deferred and that this behavior is consistent across related files.

Learnt from: Bill-hbrhbr
Repo: y-scope/clp PR: 2144
File: components/core/src/clp_s/search/ast/SearchUtils.cpp:10-11
Timestamp: 2026-03-29T20:05:44.816Z
Learning: In y-scope/clp, the include style is intentional within `components/core/src/clp_s/**`: use angle-bracket includes (e.g., `<clp_s/archive_constants.hpp>`) for headers that belong to external CMake targets, and use quoted relative includes (e.g., `"ConvertToExists.hpp"`) for headers within the same CMake target. Do not flag angle vs. quote include style as an inconsistency when it follows this rule.

#include "../clp/type_utils.hpp"
#include "../reducer/types.hpp"
#include "FileReader.hpp"
#include "search/ast/SearchUtils.hpp"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was marked resolved, but the change was never applied...


namespace clp_s {
/**
* A single typed value in an aggregation result document.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think with the way Aggregation is used in other places it should be possessive here (you also wrote it this way in another place too).

Suggested change
* A single typed value in an aggregation result document.
* A single typed value in an aggregation's result document.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

using AggregationValue = std::variant<int64_t, double, std::string>;

/**
* One aggregation result document: an ordered list of typed key-value pairs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* One aggregation result document: an ordered list of typed key-value pairs.
* One aggregation's result document: an ordered list of typed key-value pairs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment on lines +56 to +57
// The tokenizer strips the namespace prefix out of the path, but namespaced fields live
// under a top-level object keyed by that namespace. Prepend it back so the path matches.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The tokenizer strips the namespace prefix out of the path, but namespaced fields live
// under a top-level object keyed by that namespace. Prepend it back so the path matches.

I think this counts as an implementation detail, so it goes above the function definition.

Comment thread components/core/src/clp_s/int_float_compare.hpp
Comment thread components/core/src/clp_s/int_float_compare.hpp
davemarco and others added 4 commits July 6, 2026 12:47
- Rename the per-record aggregator classes and their variant from
  `*Aggregation`/`Aggregation` to `*Aggregator`/`Aggregator`, keeping
  "aggregation" for the operation's data/output (value, result, sink,
  output handler).
- Rename ambiguous `_ms` identifiers to `_millisecs`.
- Use `<clp_s/...>` includes, brace-init constexpr members, and tidy
  doc-comments (possessive wording, hoist implementation notes).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@davemarco davemarco requested a review from davidlion July 7, 2026 19:08

@davidlion davidlion left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very small changes and lgtm

Comment thread components/core/src/clp_s/aggregators.hpp
Comment thread components/core/src/clp_s/int_float_compare.hpp
Comment thread components/core/src/clp_s/aggregators.hpp
Comment thread components/core/src/clp_s/int_float_compare.hpp
@davidlion

Copy link
Copy Markdown
Member

I didn't think of this for the previous PRs, but what do you think of the title:

feat(clp-s): Support per-archive min and max aggregation output to stdout and the results cache.

@davemarco davemarco changed the title feat(clp-s): Support min and max aggregation output to stdout and the results cache. feat(clp-s): Support per-archive min and max aggregation output to stdout and the results cache. Jul 9, 2026
@davemarco davemarco requested a review from davidlion July 9, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants