Skip to content

Conversation

@gimlichael
Copy link
Member

@gimlichael gimlichael commented Nov 23, 2025

This pull request introduces significant refactoring and improvements to the DateSpan structure and the Fowler–Noll–Vo hash implementation. The main changes include extracting complex date difference calculations into helper methods for better readability and maintainability, improving hash code generation for DateSpan by using a more robust algorithm, and enhancing the Fowler–Noll–Vo hash to support multiple bit sizes and optimize performance for larger hashes.

DateSpan structure improvements

  • Refactored complex date difference logic in DateSpan by moving calculations for average days per year, month/day/hour/millisecond differences, and partial month/time differences into dedicated helper methods (CalculateAverageDaysPerYear, CalculateDifference, CalculatePartialMonthDifference, CalculateTimeDifference). This makes the code much easier to follow and maintain. [1] [2]
  • Improved hash code generation in DateSpan by switching to a Fowler–Noll–Vo 64-bit hash, incorporating calendar type identification, and using calendar IDs for equality checks. This ensures more robust and consistent hash codes and equality logic. [1] [2] [3]
  • Minor documentation and parameter name corrections for clarity, such as updating references from _calendar to Calendar in XML comments. [1] [2]

Fowler–Noll–Vo hash enhancements

  • Added support for multiple Fowler–Noll–Vo hash sizes (32, 64, 128, 256, 512, 1024 bits) and optimized handling for hashes larger than 64 bits using multi-word arithmetic. Throws an exception for unsupported sizes.
  • Refactored hash computation logic to use specialized methods for each supported hash size, improving performance and correctness. Includes explicit endianness handling and optimized byte array conversion.
  • Added helper methods for multi-word arithmetic (ToUInt32LittleEndian, MultiplyMod32) to support large hash sizes efficiently.

Codebase cleanup

  • Removed suppressions related to cognitive complexity and unused assignments in GlobalSuppressions.cs, reflecting improvements in code readability and maintainability.

Summary by CodeRabbit

  • New Features

    • Added configuration support for Fowler-Noll-Vo hashing options.
    • Introduced post-configuration interface for parameter objects.
  • Improvements

    • Optimized core hashing, date-span, encryption, and string utilities for performance.
    • Enhanced hashing to support extended bit-width variants.
  • Chores

    • Updated dependencies to latest compatible versions.
    • Added comprehensive benchmarking suite and CI matrix testing.

✏️ Tip: You can customize this high-level summary in your review settings.

@gimlichael gimlichael self-assigned this Nov 23, 2025
Copilot AI review requested due to automatic review settings November 23, 2025 17:20
@coderabbitai
Copy link

coderabbitai bot commented Nov 23, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Introduces comprehensive performance optimizations, multi-precision hashing support, and benchmarking infrastructure alongside new post-configuration capability for parameter objects. Updates core data structures, security implementations, package dependencies, and CI workflows while adding extensive test coverage and performance reports.

Changes

Cohort / File(s) Summary
Public API: Post-Configuration Framework
src/Cuemon.Core/Configuration/IPostConfigurableParameterObject.cs, src/Cuemon.Security/FowlerNollVoOptions.cs
Introduces post-configuration interface for parameter objects and adds FowlerNollVoOptions configuration class with Algorithm property.
Core Library Optimizations
src/Cuemon.Core/DateSpan.cs, src/Cuemon.Core/Generate.cs, src/Cuemon.Core/DelimitedString.cs, src/Cuemon.Core/Patterns.cs
Refactors internal logic: DateSpan replaces calendar object comparison with numeric IDs and optimizes hashing; Generate removes parallelization from RandomString; DelimitedString adds fast-path for single-char delimiters; Patterns replaces Activator.CreateInstance.
Cryptography Enhancements
src/Cuemon.Security.Cryptography/AesCryptor.cs, src/Cuemon.Security.Cryptography/KeyedCryptoHash.cs, src/Cuemon.Security.Cryptography/UnkeyedCryptoHash.cs, src/Cuemon.Security.Cryptography/SecureHashAlgorithm512.cs
Simplifies AES transform pipeline; adds null checks and using declarations to hash classes; makes SecureHashAlgorithm512 constructor parameter optional.
Multi-Precision FNV Hashing
src/Cuemon.Core/Security/FowlerNollVoHash.cs
Adds word-based state and support for 32/64/128/256/512/1024-bit hash sizes via dedicated compute methods.
CRC Infrastructure
src/Cuemon.Core/Security/CyclicRedundancyCheck.cs, src/Cuemon.Core/Security/CyclicRedundancyCheck32.cs, src/Cuemon.Core/Security/CyclicRedundancyCheck64.cs
Replaces List-based lookup with array-based caching; adds null checks to compute methods.
Validator & Configuration
src/Cuemon.Core/Validator.cs
Extends ThrowIfInvalidOptions to invoke PostConfigureOptions() before validation.
Build Infrastructure
Cuemon.sln, Directory.Build.props, Directory.Packages.props
Updates to VS 2018, adds benchmark and tooling project categories, updates xunit/Codebelt packages, adds BenchmarkDotNet dependencies.
CI/CD Updates
.github/workflows/ci-pipeline.yml, .github/copilot-instructions.md, .github/prompts/benchmark.prompt.md
Introduces matrix-driven OS selection; adds benchmark guidelines documentation.
Comprehensive Test Suites
test/Cuemon.Core.Tests/DateSpanTest.cs, test/Cuemon.Core.Tests/GenerateTest.cs, test/Cuemon.Core.Tests/Security/*Test.cs, test/Cuemon.Security.Cryptography.Tests/*Test.cs
Adds hash code validation, null handling, empty input, endianness, algorithm comparison, and cryptographic correctness tests across 20+ test files.
Benchmark Projects & Code
tuning/Cuemon.Core.Benchmarks/*, tuning/Cuemon.Security.Cryptography.Benchmarks/*
New benchmark projects with comprehensive performance tests for DateSpan, DelimitedString, Generate utilities, CRC, FNV, and AES encryption/decryption.
Benchmark Reports
reports/tuning/*-report-github.md
BenchmarkDotNet-generated performance data across .NET 9.0 and 10.0 for core utilities and cryptographic operations.
Release Notes & Documentation
.nuget/*/PackageReleaseNotes.txt (28 files), CHANGELOG.md
Adds v10.1.0 release entries noting dependency upgrades and performance improvements; updates main changelog.
Test Assets
test/Cuemon.Core.Tests/Assets/PostConfigurableOptions.cs, test/Cuemon.Core.Tests/Assets/FailPostConfigurableOptions.cs
Adds test fixtures for post-configuration validation scenarios.
Other Test Updates
test/Cuemon.Core.Tests/Reflection/AssemblyDecoratorExtensionsTest.cs, test/Cuemon.Core.Tests/ValidatorTest.cs
Updates assertion counts for new configuration types; adds post-configuration validation tests.
Cleanup
src/Cuemon.Core/GlobalSuppressions.cs
Removes two SonarQube suppressions on DateSpan constructor after refactoring.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • DateSpan refactoring (src/Cuemon.Core/DateSpan.cs): Dense internal rearchitecting with calendar ID mapping, new helper methods, hash/equality changes—requires careful verification of behavioral equivalence
  • FowlerNollVoHash multi-precision support (src/Cuemon.Core/Security/FowlerNollVoHash.cs): Adds substantial word-based logic and multiple compute methods for varying bit sizes; needs validation against reference implementations
  • Heterogeneous changes across domains: Mix of optimizations (Generate, DelimitedString), API changes (SecureHashAlgorithm512), and infrastructure (build/benchmarks) requires separate reasoning per area
  • Extensive test coverage: 20+ new test files with reference implementations and property-based checks; verify correctness of independent implementations and edge cases

Possibly related PRs

  • 👷 streamline pipeline #120: Modernizes GitHub Actions CI workflow with matrix-driven OS selection (ubuntu-24.04, windows-2025), similar to this PR's CI updates.
  • V10.0.1/xunit tweaks #132: Updates package versions in Directory.Packages.props for xunit and test dependencies, overlapping with this PR's package updates.

Poem

🐰 Hop through optimized spans and hashes so fine,
Multi-precision FNV in vectors align,
Benchmarks now measure each speedy refine,
Post-configuration flourishes—the code will shine!
With tests and reports, performance divine!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.86% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'V10.1.0/api improvements and features' is vague and overly broad, failing to convey the primary changes (DateSpan refactoring, FNV multi-precision hashing, performance optimizations). Revise title to be more specific about main changes, e.g., 'Refactor DateSpan with FNV hashing and add multi-precision FNV support' or 'Improve DateSpan and FNV hash with performance optimizations'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch v10.0.1/ai-assisted-performance-boost

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 and usage tips.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the DateSpan structure and FowlerNollVoHash implementation to improve code maintainability and performance. The changes extract complex date difference calculations into helper methods, implement a robust FNV-64 hash for DateSpan, and extend FowlerNollVoHash to support multiple bit sizes (32, 64, 128, 256, 512, 1024) with optimized multi-word arithmetic for larger hashes.

  • Refactored DateSpan constructor logic into dedicated helper methods for better readability
  • Replaced DateSpan.GetHashCode() with FNV-64 implementation and calendar type identification
  • Extended FowlerNollVoHash to support multiple bit sizes with specialized computation methods

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/Cuemon.Core/DateSpan.cs Refactored date calculation logic into helper methods; implemented FNV-64 hash code generation with calendar ID tracking
src/Cuemon.Core/Security/FowlerNollVoHash.cs Added multi-bit size support (32, 64, 128, 256, 512, 1024) with specialized computation methods and multi-word arithmetic
test/Cuemon.Core.Tests/DateSpanTest.cs Added hash code stability tests; removed hard-coded hash code assertions from existing tests
test/Cuemon.Core.Tests/Security/FowlerNollVoHashTest.cs New comprehensive test file covering various bit sizes, algorithms, and endianness configurations
src/Cuemon.Core/GlobalSuppressions.cs Removed suppressions for cognitive complexity and unused assignments, reflecting improved code quality
.github/copilot-instructions.md Added comprehensive guidelines for unit testing and XML documentation in the Cuemon codebase

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (6)
test/Cuemon.Core.Tests/Security/FowlerNollVoHashTest.cs (2)

49-115: Solid 32/64-bit FNV behavior coverage; consider adding LittleEndian non-empty cases

The 32-bit and 64-bit tests:

  • Correctly use standard FNV primes/offset bases.
  • Cross-check both Fnv1a and Fnv1 against independent reference implementations that mirror the production loops and endianness handling.
  • Verify empty-input behavior for both default BigEndian and explicitly configured LittleEndian (32-bit).

That gives strong confidence that the new ComputeHash32/ComputeHash64 logic and FowlerNollVoOptions.Algorithm/ByteOrder interplay are correct.

Optional improvement: Add non-empty LittleEndian expectation tests for 32- and/or 64-bit (e.g., hello with ByteOrder = Endianness.LittleEndian) to guard against future regressions in the manual byte layout code, similar to what you do for the empty-input case.

If you want to see exact reference values to lock into those extra assertions, you can reuse IndependentFNV32/IndependentFNV64 with byteOrder = Endianness.LittleEndian inside new tests.


117-187: Verify that LittleEndian coverage should be added to multi-word tests

The review comment is accurate. Current state:

  • 32-bit tests: Explicit LittleEndian variant exists (line 65: ComputeHash32_EmptyInput_ReturnsOffsetBasis_LittleEndianWhenConfigured)
  • 64-bit tests: No LittleEndian variant found
  • Multi-word tests: Both tests (lines 118 and 170) use default BigEndian only, despite the empty-input test being named WithSelectedEndianness

The constructor pattern for endianness configuration already works (demonstrated by the 32-bit test at line 69: o => o.ByteOrder = Endianness.LittleEndian), and the helper methods IndependentFNVMultiWord already support both endianness paths. Adding an explicit LittleEndian variant to at least one multi-word test would close this coverage gap and align with the 32-bit test pattern.

.github/copilot-instructions.md (2)

68-117: Fix mismatched summary in DateSpanTest example to avoid confusion

In the “Example Test” snippet, the XML summary says:

/// <summary>
/// Tests for the <see cref="DefaultCommand"/> class.
/// </summary>
public class DateSpanTest : Test

The class is DateSpanTest, not a test for DefaultCommand, and the rest of the example clearly focuses on DateSpan. This mismatch could be confusing for contributors using this as a template.

Consider aligning the summary and cref, e.g.:

-    /// <summary>
-    /// Tests for the <see cref="DefaultCommand"/> class.
-    /// </summary>
-    public class DateSpanTest : Test
+    /// <summary>
+    /// Tests for the <see cref="DateSpan"/> class.
+    /// </summary>
+    public class DateSpanTest : Test

144-151: Address markdownlint MD003 (heading style) or configure an exception

markdownlint-cli2 reports MD003 at Line 144 (“Heading style: Expected: atx; Actual: setext”). This is likely triggered by the second YAML front-matter block and subsequent heading style.

Two options:

  • Adjust the second document’s top-level heading to clearly use atx style and ensure there isn’t a setext-style underline nearby, or
  • Configure markdownlint to ignore this particular heading or file if the current format is intentional.

Given this is purely stylistic, it’s safe to defer, but fixing it will keep automated lint runs clean.

src/Cuemon.Core/DateSpan.cs (1)

203-213: Verify GetWeeks behavior for short ranges (≤ 7 days)

With the new GetWeeks logic, any span where range.Days <= 7 yields weeks == 2 (because totalDays becomes 1 or 2 and 1 + ((totalDays + 6) / 7) evaluates to 2), including the degenerate case of _lower == _upper. Please confirm whether “at least 2 calendar weeks” is the intended semantic; if the intent is “number of calendar weeks spanned” or “weeks-equivalent duration,” you may want a simpler and more explicit formulation for 0–7 day ranges (e.g., returning 1 for any non-empty span and possibly 0 for an empty span).

test/Cuemon.Core.Tests/DateSpanTest.cs (1)

1-6: New DateSpan hash-code tests are well-aligned with the revised implementation

The added tests:

  • Verify intra-instance stability (GetHashCode_IsStableForSameInstance).
  • Check the Equals/GetHashCode contract for equal values (GetHashCode_EqualInstances_HaveSameHashCode).
  • Sanity-check sensitivity to changing boundaries (GetHashCode_ChangingUpperBoundary_UsuallyChangesHashCode).
  • Ensure calendar identity is based on calendar type rather than instance (GetHashCode_TwoSameTypeCalendars_MustBeEqual / GetHashCode_TwoDifferentTypeCalendars_MustBeNotEqual).

These collectively exercise the new _calendarId mapping and FNV-based hash and give good coverage of the intended semantics. You might consider adding one or two focused tests for short spans with differing time-of-day once CalculateDifference is fixed, but the current hash-focused coverage looks solid.

Also applies to: 16-69

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 708798a and 37b24ac.

📒 Files selected for processing (6)
  • .github/copilot-instructions.md (1 hunks)
  • src/Cuemon.Core/DateSpan.cs (9 hunks)
  • src/Cuemon.Core/GlobalSuppressions.cs (0 hunks)
  • src/Cuemon.Core/Security/FowlerNollVoHash.cs (3 hunks)
  • test/Cuemon.Core.Tests/DateSpanTest.cs (2 hunks)
  • test/Cuemon.Core.Tests/Security/FowlerNollVoHashTest.cs (1 hunks)
💤 Files with no reviewable changes (1)
  • src/Cuemon.Core/GlobalSuppressions.cs
🧰 Additional context used
🧬 Code graph analysis (3)
src/Cuemon.Core/Security/FowlerNollVoHash.cs (1)
src/Cuemon.Core/Convertible.cs (2)
  • Convertible (14-487)
  • ReverseEndianness (456-469)
test/Cuemon.Core.Tests/DateSpanTest.cs (1)
src/Cuemon.Core/DateSpan.cs (9)
  • DateSpan (25-27)
  • DateSpan (34-36)
  • DateSpan (44-100)
  • DateSpan (294-297)
  • DateSpan (305-308)
  • DateSpan (317-320)
  • GetHashCode (223-241)
  • Equals (250-254)
  • Equals (261-265)
test/Cuemon.Core.Tests/Security/FowlerNollVoHashTest.cs (2)
src/Cuemon.Core/Security/FowlerNollVoHash.cs (2)
  • FowlerNollVoHash (9-249)
  • FowlerNollVoHash (22-46)
src/Cuemon.Core/Convertible.cs (2)
  • Convertible (14-487)
  • ReverseEndianness (456-469)
🪛 markdownlint-cli2 (0.18.1)
.github/copilot-instructions.md

144-144: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: CodeQL analysis (csharp)
  • GitHub Check: Agent
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (8)
src/Cuemon.Core/Security/FowlerNollVoHash.cs (4)

80-167: Single-word (32/64-bit) FNV implementations correctly handle both algorithms and endianness

ComputeHash32 and ComputeHash64:

  • Implement Fnv1a (xor then multiply) and Fnv1 (multiply then xor) exactly as per the standard FNV definitions.
  • Run in an unchecked context, giving the intended modulo-2^32 / modulo-2^64 behavior.
  • Serialize the final accumulator into 4 or 8 bytes with explicit branches for Endianness.LittleEndian vs BigEndian, independent of machine endianness.

The accompanying tests (ComputeHash32_NonEmpty_EqualsIndependentImplementation_Fnv1aAndFnv1, ComputeHash64_NonEmpty_EqualsIndependentImplementation) validate these code paths against independent reference implementations, so this looks robust.

If you ever need to regenerate known-answer test vectors, you can temporarily expose these methods or port the reference implementations from the test file into a small console utility.


209-248: ToUInt32LittleEndian and MultiplyMod32 correctly implement word-wise modular arithmetic

ToUInt32LittleEndian:

  • Interprets BigInteger values via ToByteArray() (little-endian, two’s complement).
  • Zero-extends when fewer bytes than unitCount * 4.
  • Extracts exactly unitCount 32-bit little-endian words, effectively taking the value modulo 2^(32 * unitCount).

MultiplyMod32:

  • Performs a standard schoolbook multiplication of two uint word arrays, accumulating into tmp with a 32-bit word size.
  • Ignores overflow beyond L words, which is exactly the desired modulo-2^(32L) behavior for the FNV state.
  • Skips work for zero words and reuses a caller-provided scratch buffer to avoid repeated allocations.

These helpers line up with the independent multi-word reference implementation used in the tests and look correct for the supported bit sizes (up to 1024 bits).

If you ever need to confirm behavior for edge primes/offset bases, you could compare results against a pure BigInteger-based implementation similar to IndependentFNVMultiWord across randomly generated inputs.


24-46: Bit-size validation confirmed—all instantiations use supported sizes

Verification of all callers in the codebase confirms that only supported bit sizes {32, 64, 128} are instantiated, plus a single test at line 26 that deliberately uses unsupported size 16 to verify the exception is thrown. The constructor's switch-based validation is properly enforced and correctly restricts usage. Multi-word initialization is well-scoped and correct.


71-78: Code is correct, no changes needed

The constructor validates that Bits can only be one of {32, 64, 128, 256, 512, 1024}, enforced via a switch statement that throws ArgumentOutOfRangeException for invalid values. The dispatcher in ComputeHash correctly routes all six supported bit-widths through their appropriate paths, and the final throw is indeed unreachable in normal operation, making it purely defensive.

test/Cuemon.Core.Tests/Security/FowlerNollVoHashTest.cs (1)

14-47: Test implementation and assertions are correct

All three assertions in the review comment have been verified against the production code at src/Cuemon.Core/Security/FowlerNollVoHash.cs:

  • Bit-size validation throws ArgumentOutOfRangeException for unsupported sizes (constructor lines 24–34)
  • Properties Bits, Prime, and OffsetBasis are correctly assigned in the constructor (lines 36–38)
  • ComputeHash(byte[]) validates null input with Validator.ThrowIfNull(input) (line 73), which throws ArgumentNullException

The test subclass and all three test methods accurately reflect the production behavior.

src/Cuemon.Core/DateSpan.cs (3)

17-20: FNV-based hashing and calendar ID equality look coherent

The introduction of _calendarId with explicit mappings for the built-in calendars and a fallback based on the calendar type, combined with the FNV-64-based GetHashCode that mixes _upper.Ticks, _lower.Ticks, and _calendarId, is consistent with the updated Equals(DateSpan other) implementation and the new tests. This maintains the required invariant: if two DateSpan instances are equal, they will always share the same hash code, and different calendar types are distinguishable in hashing while instances of the same type share the same identity.

Also applies to: 52-70, 225-240, 261-265


121-132: Average days-per-year helper is logically sound

CalculateAverageDaysPerYear correctly aggregates GetDaysInYear for each year from lower.Year up to but excluding upper.Year and averages over the computed years, with the years == 0 case falling back to the single-year day count. This matches the intended use in TotalYears and preserves existing leap-year behavior.


315-320: Parse overload XML comment clarification is correct

The updated XML comment for the culture parameter accurately reflects that the Calendar is resolved from the supplied CultureInfo, matching the implementation (culture.Calendar) and improving API documentation clarity.

@codecov
Copy link

codecov bot commented Nov 23, 2025

Codecov Report

❌ Patch coverage is 91.87500% with 26 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@708798a). Learn more about missing BASE report.

Files with missing lines Patch % Lines
src/Cuemon.Core/DateSpan.cs 86.59% 13 Missing ⚠️
src/Cuemon.Core/Security/FowlerNollVoHash.cs 92.71% 11 Missing ⚠️
src/Cuemon.Core/DelimitedString.cs 94.28% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #134   +/-   ##
=======================================
  Coverage        ?   80.37%           
=======================================
  Files           ?      595           
  Lines           ?    18485           
  Branches        ?     1895           
=======================================
  Hits            ?    14857           
  Misses          ?     3562           
  Partials        ?       66           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
tooling/Cuemon.Core.Benchmarks/reports/results/Cuemon.DateSpanBenchmark-report-github.md (1)

1-41: Generated benchmark report looks good.

This is a generated BenchmarkDotNet artifact documenting DateSpan performance metrics across .NET 9.0 and 10.0. The results provide valuable insights into the performance characteristics of the refactored DateSpan implementation.

The markdown linting hints (missing language specifier on line 1 and table spacing on line 14) are cosmetic. If you'd like to address them for consistency:

-```
+``` text

and add a blank line before line 14. These are optional improvements that don't affect the report's utility.

tooling/Cuemon.Core.Benchmarks/reports/results/Cuemon.Security.FowlerNollVoHashBenchmark-report-github.md (1)

1-86: Comprehensive FNV hash benchmark report.

This generated BenchmarkDotNet report documents the performance characteristics of the enhanced Fowler–Noll–Vo hash implementation across multiple bit sizes (32–1024) and algorithms (Fnv1, Fnv1a). The metrics provide valuable baseline data for the new multi-word arithmetic implementation.

Similar to the DateSpan report, the markdown linting hints are cosmetic and optional to address.

tooling/Cuemon.Core.Benchmarks/Security/FowlerNollVoHashBenchmark.cs (1)

1-44: Well-designed FNV hash benchmark setup.

The benchmark class properly covers both algorithm variants (Fnv1, Fnv1a) across all supported bit widths. The GlobalSetup creates realistic payload sizes for comprehensive performance measurement.

Lines 22-23 contain extra blank lines that could be removed for consistency:

         private FowlerNollVo1024 _fnv1024 = null!;
-
-
         [GlobalSetup]
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 37b24ac and e0903d5.

📒 Files selected for processing (14)
  • Cuemon.sln (4 hunks)
  • Directory.Build.props (5 hunks)
  • Directory.Packages.props (1 hunks)
  • src/Cuemon.Core/Generate.cs (2 hunks)
  • test/Cuemon.Core.Tests/DateSpanTest.cs (2 hunks)
  • test/Cuemon.Core.Tests/GenerateTest.cs (4 hunks)
  • tooling/Cuemon.Core.Benchmarks/.support/Program.cs (1 hunks)
  • tooling/Cuemon.Core.Benchmarks/Cuemon.Core.Benchmarks.csproj (1 hunks)
  • tooling/Cuemon.Core.Benchmarks/DateSpanBenchmark.cs (1 hunks)
  • tooling/Cuemon.Core.Benchmarks/GenerateBenchmark.cs (1 hunks)
  • tooling/Cuemon.Core.Benchmarks/Security/FowlerNollVoHashBenchmark.cs (1 hunks)
  • tooling/Cuemon.Core.Benchmarks/reports/results/Cuemon.DateSpanBenchmark-report-github.md (1 hunks)
  • tooling/Cuemon.Core.Benchmarks/reports/results/Cuemon.GenerateBenchmark-report-github.md (1 hunks)
  • tooling/Cuemon.Core.Benchmarks/reports/results/Cuemon.Security.FowlerNollVoHashBenchmark-report-github.md (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
test/Cuemon.Core.Tests/GenerateTest.cs (1)
src/Cuemon.Core/Generate.cs (2)
  • Generate (18-219)
  • ObjectPortrayal (46-70)
tooling/Cuemon.Core.Benchmarks/DateSpanBenchmark.cs (1)
src/Cuemon.Core/DateSpan.cs (1)
  • GetWeeks (200-214)
test/Cuemon.Core.Tests/DateSpanTest.cs (1)
src/Cuemon.Core/DateSpan.cs (9)
  • DateSpan (25-27)
  • DateSpan (34-36)
  • DateSpan (44-100)
  • DateSpan (294-297)
  • DateSpan (305-308)
  • DateSpan (317-320)
  • GetHashCode (223-241)
  • Equals (250-254)
  • Equals (261-265)
tooling/Cuemon.Core.Benchmarks/GenerateBenchmark.cs (1)
src/Cuemon.Core/Generate.cs (3)
  • Generate (18-219)
  • FixedString (132-135)
  • ObjectPortrayal (46-70)
🪛 markdownlint-cli2 (0.18.1)
tooling/Cuemon.Core.Benchmarks/reports/results/Cuemon.Security.FowlerNollVoHashBenchmark-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

tooling/Cuemon.Core.Benchmarks/reports/results/Cuemon.DateSpanBenchmark-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (20)
Cuemon.sln (1)

3-4: Verify Visual Studio version string format.

Line 4 shows VisualStudioVersion = 18.0.11217.181 d18.0 which appears to have unusual formatting with a space and "d18.0" suffix. Confirm this is the correct format for VS2022 solution files.

src/Cuemon.Core/Generate.cs (2)

79-89: LGTM! Proper null validation added.

The addition of Validator.ThrowIfNull(generator) with corresponding XML documentation is a good defensive programming practice that prevents potential null reference exceptions.


162-178: Simplified RandomString implementation removes parallelization.

The refactored implementation replaces the previous concurrent approach with a straightforward sequential loop. This is clearer and easier to maintain. The addition of the length guard (if (length <= 0) { return string.Empty; }) properly handles edge cases.

However, the removal of parallelization may have performance implications for large strings. Based on the benchmark results in the PR (showing improved performance on .NET 10), this appears to be an intentional optimization.

Note: The benchmark report shows this change improves performance, particularly on .NET 10 where RandomString (256 chars) went from ~7,353ns to ~4,668ns.

test/Cuemon.Core.Tests/GenerateTest.cs (4)

15-55: Excellent test coverage for RangeOf.

The tests comprehensively validate:

  • Correct sequence generation with transformation logic
  • Empty sequence for count=0 without invoking the generator
  • Index parameter correctness and ordering
  • Error handling for negative counts

58-102: Thorough validation of RandomString behavior.

These tests properly verify:

  • Output length matches input
  • Characters are drawn only from allowed sets
  • Zero-length input returns empty string
  • Null and empty value arrays throw appropriate exceptions

The test at lines 79-90 using custom values with distinct character validation is particularly good for ensuring the implementation respects the input character sets.


127-197: Comprehensive hash code testing.

The tests validate critical hash code properties:

  • Consistency between params and enumerable overloads
  • Determinism (same input → same hash)
  • Order sensitivity (different order → different hash)
  • Empty sequence handling across all overloads

This provides strong guarantees for the FNV-1a hash implementation used by these methods.


199-290: ObjectPortrayal tests validate complex behavior.

The tests effectively cover:

  • Null handling
  • Boolean lowercase conversion
  • ToString override detection and bypass
  • Property enumeration including write-only properties

The helper classes (WithToStringOverride, NoOverride, CallsObjectPortrayalFromToString) appropriately test different scenarios including the recursive call protection via BypassOverrideCheck.

test/Cuemon.Core.Tests/DateSpanTest.cs (1)

14-66: Excellent hash code test coverage for DateSpan.

These tests validate the critical properties of the new hash code implementation:

  • Stability: Multiple calls to GetHashCode return the same value (lines 14-25)
  • Equality contract: Equal instances produce equal hash codes (lines 27-35)
  • Sensitivity: Changes in data (boundaries) affect the hash (lines 37-44)
  • Calendar awareness: Same calendar types produce equal hashes, different types produce different hashes (lines 46-66)

This aligns well with the DateSpan.GetHashCode implementation that uses FNV-1a hashing with _calendarId as a discriminator.

Directory.Build.props (3)

4-4: LGTM! Consistent project type detection pattern.

The IsBenchmarkProject property follows the same pattern as IsTestProject, using the project name suffix to determine the project type. This is a clean and maintainable approach.


17-17: Proper conditional logic for benchmark project segregation.

The conditions correctly:

  • Line 17, 50: Exclude benchmark projects from production package settings using AND logic
  • Line 64: Include benchmark projects in test-like settings (no packaging, disabled analyzers) using OR logic

This ensures benchmark projects are treated appropriately—not packaged as libraries but configured similarly to test projects.

Also applies to: 50-50, 64-64


101-108: LGTM! Benchmark project configuration is appropriate.

The configuration:

  • Sets TargetFrameworks to net10.0;net9.0;net48 for cross-framework benchmarking
  • Includes BenchmarkDotNet and platform-specific diagnostics package

This aligns with standard BenchmarkDotNet project setup and the benchmark reports in the PR.

tooling/Cuemon.Core.Benchmarks/Cuemon.Core.Benchmarks.csproj (1)

1-19: LGTM! Standard benchmark project structure.

The project configuration is clean and follows best practices:

  • Uses SDK-style project format
  • Maintains consistent namespace with the main project (RootNamespace = Cuemon)
  • References the target library (Cuemon.Core) for benchmarking
  • Organizes entry point in .support\Program.cs
  • Includes folder for benchmark results

This aligns with the benchmark dependencies configured in Directory.Build.props and Directory.Packages.props.

tooling/Cuemon.Core.Benchmarks/reports/results/Cuemon.GenerateBenchmark-report-github.md (1)

1-104: Benchmark results validate performance improvements.

This generated report documents the performance characteristics of the refactored Generate methods. Key observations:

  • RandomString shows significant speedup on .NET 10 (e.g., 256-char strings: ~7.4μs → ~4.7μs)
  • RangeOf shows modest improvements across frameworks
  • HashCode operations maintain consistent performance

These results support the PR's objective of achieving AI-assisted performance boosts while maintaining correctness (validated by the comprehensive test suite).

tooling/Cuemon.Core.Benchmarks/DateSpanBenchmark.cs (2)

1-47: Well-structured benchmark setup.

The class configuration and GlobalSetup method are properly implemented. The use of ISO 8601 sortable format with InvariantCulture ensures consistent parsing behavior across benchmarks, and the variety of test data (short/medium/long spans) provides good coverage.


49-94: Comprehensive benchmark coverage of DateSpan operations.

The benchmark methods cover key scenarios including construction, parsing, formatting, week calculation, hashing, and equality checks. The equality benchmarks (lines 86-93) include the overhead of constructing new DateSpan instances, which represents realistic usage patterns rather than isolated comparison performance.

tooling/Cuemon.Core.Benchmarks/.support/Program.cs (2)

26-50: Solid BenchmarkDotNet configuration.

The configuration follows best practices from the dotnet/performance repository with appropriate customization. The job settings balance execution time and reliability, and the export/logging setup ensures comprehensive results documentation.

The artifacts path computation on line 29 uses relative directory navigation ("..", "..", ".."), which assumes the assembly location is three directories deep from the project root. Verify that this works correctly across different build configurations (Debug/Release) and deployment scenarios.


52-58: Clean benchmark execution logic.

The default argument handling provides sensible defaults (all benchmarks, .NET 9.0 and 10.0 runtimes) while preserving command-line override capability. The BenchmarkSwitcher approach enables flexible benchmark discovery and execution.

tooling/Cuemon.Core.Benchmarks/Security/FowlerNollVoHashBenchmark.cs (1)

46-92: Comprehensive benchmark coverage of FNV hash operations.

The benchmark methods systematically cover all combinations of hash bit widths (32, 64, 128, 256, 512, 1024) and payload sizes. The consistent structure and clear naming make the results easy to interpret.

tooling/Cuemon.Core.Benchmarks/GenerateBenchmark.cs (2)

1-36: Effective benchmark parameterization and setup.

The parameterized Count values (8, 256, 4096) enable performance measurement across different scales. The GlobalSetup prepares realistic test data including a sample object, string values, and convertibles collection for comprehensive coverage of Generate utility methods.


38-105: Thorough coverage of Generate utility methods.

The benchmark methods effectively cover the key Generate API surface including RangeOf, RandomNumber, string generation, ObjectPortrayal, and hash code computation. The RangeOf benchmark correctly uses a sink to prevent the compiler from optimizing away the enumeration. The Sample class provides appropriate test data for ObjectPortrayal benchmarking.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/Cuemon.Security.Cryptography/SecureHashAlgorithm512.cs (1)

22-25: Clarify XML docs for now-optional setup parameter

Making setup optional is a nice usability improvement and should be backward-compatible. Consider updating the <param name="setup"> doc (and possibly the summary) to state that the parameter is optional, may be null, and what behavior occurs when it is omitted (e.g., default conversion options / no custom configuration).

src/Cuemon.Security.Cryptography/KeyedCryptoHash.cs (1)

29-34: Consider removing the redundant override.

The ComputeHash implementation in KeyedCryptoHash<TAlgorithm> is identical to the base class UnkeyedCryptoHash<TAlgorithm> implementation. Since the base class already provides this exact functionality, the override appears unnecessary and adds maintenance burden.

If there's no specific reason to maintain this override (e.g., future extensibility plans or documentation purposes), consider removing it:

-    /// <summary>
-    /// Computes the hash value for the specified <see cref="T:byte[]" />.
-    /// </summary>
-    /// <param name="input">The <see cref="T:byte[]" /> to compute the hash code for.</param>
-    /// <returns>A <see cref="HashResult" /> containing the computed hash code of the specified <paramref name="input" />.</returns>
-    public override HashResult ComputeHash(byte[] input)
-    {
-        Validator.ThrowIfNull(input);
-        using var h = Initializer();
-        return new HashResult(h.ComputeHash(input));
-    }
Directory.Build.props (2)

80-82: WarningLevel=0 for tests outside VS may hide real compiler issues

The new test block:

<PropertyGroup Condition="'$(IsTestProject)' == 'true' AND '$(BuildingInsideVisualStudio)' != 'true'">
  <WarningLevel>0</WarningLevel>
</PropertyGroup>

completely disables C# compiler warnings for all test projects on non‑VS builds (e.g., dotnet build, CI). Given you already relax analyzers for tests, this is a pretty strong setting and can mask genuine problems (e.g., obsolete API usage, nullable issues) that only show up in tests.

If the intent is just to reduce noise in CI, you might consider a narrower approach (tweaking NoWarn or specific analyzer rules) rather than globally forcing WarningLevel to 0.

Please verify this is intentional for your pipelines; otherwise a follow‑up PR could dial this back to a more targeted suppression strategy.


4-4: Benchmark project wiring looks good; consider gating Windows diagnostics package

The IsBenchmarkProject flag and associated Property/ItemGroups are consistent with MSBuild string property functions and give benchmarks their own TFM set and package references:

<IsBenchmarkProject>$(MSBuildProjectName.EndsWith('Benchmarks'))</IsBenchmarkProject>

<PropertyGroup Condition="'$(IsBenchmarkProject)' == 'true'">
  <TargetFrameworks>net10.0;net9.0;netstandard2.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup Condition="'$(IsBenchmarkProject)' == 'true'">
  <PackageReference Include="BenchmarkDotNet" />
  <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" />
</ItemGroup>

One minor refinement: BenchmarkDotNet.Diagnostics.Windows is Windows‑specific. To avoid dragging this into non‑Windows environments where it can’t run, you could gate it on IsWindows:

-  <ItemGroup Condition="'$(IsBenchmarkProject)' == 'true'">
-    <PackageReference Include="BenchmarkDotNet" />
-    <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" />
-  </ItemGroup>
+  <ItemGroup Condition="'$(IsBenchmarkProject)' == 'true'">
+    <PackageReference Include="BenchmarkDotNet" />
+  </ItemGroup>
+
+  <ItemGroup Condition="'$(IsBenchmarkProject)' == 'true' AND '$(IsWindows)' == 'true'">
+    <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" />
+  </ItemGroup>

This keeps benchmarks cross‑platform while still enabling the Windows diagnostics when relevant.

Please confirm that all your benchmark projects either run only on Windows or that you’re okay pulling in the Windows‑only diagnostics package on other platforms as a no‑op dependency.

Also applies to: 112-119

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0903d5 and 6fbf13a.

📒 Files selected for processing (7)
  • Directory.Build.props (5 hunks)
  • src/Cuemon.Core/DelimitedString.cs (4 hunks)
  • src/Cuemon.Core/Patterns.cs (2 hunks)
  • src/Cuemon.Security.Cryptography/AesCryptor.cs (2 hunks)
  • src/Cuemon.Security.Cryptography/KeyedCryptoHash.cs (1 hunks)
  • src/Cuemon.Security.Cryptography/SecureHashAlgorithm512.cs (1 hunks)
  • src/Cuemon.Security.Cryptography/UnkeyedCryptoHash.cs (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/Cuemon.Security.Cryptography/AesCryptor.cs
🧰 Additional context used
🧬 Code graph analysis (2)
src/Cuemon.Security.Cryptography/KeyedCryptoHash.cs (2)
src/Cuemon.Core/Validator.cs (1)
  • Validator (15-1150)
src/Cuemon.Security.Cryptography/UnkeyedCryptoHash.cs (1)
  • HashResult (39-44)
src/Cuemon.Security.Cryptography/UnkeyedCryptoHash.cs (2)
src/Cuemon.Core/Validator.cs (1)
  • Validator (15-1150)
src/Cuemon.Security.Cryptography/KeyedCryptoHash.cs (1)
  • HashResult (29-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (10)
src/Cuemon.Core/Patterns.cs (2)

103-108: LGTM! Performance improvement by avoiding reflection.

Replacing Activator.CreateInstance<T>() with direct constructor new T() is more performant and equally correct given the new() constraint.


119-126: LGTM! Performance improvement by avoiding reflection.

Replacing Activator.CreateInstance<TOptions>() with direct constructor new TOptions() is more performant and equally correct given the new() constraint.

src/Cuemon.Security.Cryptography/KeyedCryptoHash.cs (1)

31-33: LGTM! Modern syntax and explicit validation improve the code.

The addition of explicit null validation and the migration to using declarations are both solid improvements that enhance readability and follow modern C# conventions.

src/Cuemon.Security.Cryptography/UnkeyedCryptoHash.cs (1)

41-43: LGTM! Consistent improvements to the base implementation.

The explicit null validation and using declaration mirror the pattern applied in the derived class, providing a consistent approach to resource management and input validation across the cryptographic hashing components.

Directory.Build.props (1)

5-6: Based on my verification, I can now provide the final assessment:

The review comment's technical analysis is incorrect; the current code actually works as intended.

The review claims that nested property expansion $($(MSBuildThisFileDirectory.ToLower())src) doesn't work and that the expressions only match literal strings "src" and "tooling". However, this misunderstands how MSBuild property functions operate:

  • MSBuild does expand property references in function arguments at evaluation time
  • When evaluating StartsWith('$(MSBuildThisFileDirectory.ToLower())src'), the inner $(MSBuildThisFileDirectory.ToLower()) is expanded to the actual directory path first
  • For a project at /repo/src/Cuemon.Core/, this becomes StartsWith('/repo/src'), which correctly matches
  • Evidence: The repository has successful builds, passing tests, and published packages (V10.0.0 launched successfully), which would fail if IsSourceProject never evaluated to true for src projects

However, the suggestion to use StringComparison.OrdinalIgnoreCase for clarity and efficiency is still potentially valid, though:

  • It's not required to fix an actual bug (the current code works)
  • The suggested syntax using StringComparison enum directly may not be compatible with all MSBuild versions or contexts
  • No existing uses of StringComparison in property functions appear in the codebase

The review comment conflates a style/efficiency suggestion with a critical bug that doesn't exist.

Likely an incorrect or invalid review comment.

src/Cuemon.Core/DelimitedString.cs (5)

14-14: LGTM: Improved cache key type safety.

Changing from a string-based key to a tuple key (string Delimiter, string Qualifier) improves type safety and better expresses the cache key's intent.


30-43: LGTM: Cleaner delimiter handling.

The refactor to handle the first element separately and then prepend delimiters for subsequent items is a cleaner pattern that avoids the need for trailing delimiter trimming. The early return for empty sources is also a good optimization.


67-67: LGTM: Good optimization for common case.

Adding a fast path for single-character delimiters and qualifiers should significantly improve performance for typical CSV scenarios.


69-72: I'll help you verify the review comment about Regex.Escape behavior with qualifiers in character classes. Let me start by exploring the codebase to understand how DelimitedString.Split is tested and what qualifiers are actually used.
<function_calls>

#!/bin/bash

Search for tests of DelimitedString.Split with various qualifiers

rg -n -C 5 'DelimitedString.*Split|DelimitedStringOptions.*Qualifier' --type=cs -g 'Test.cs' | head -100


</function_calls>

#!/bin/bash # Find test files related to DelimitedString fd -e cs -g '*Test*.cs' | xargs rg -l 'DelimitedString' | head -20 #!/bin/bash # Look at the DelimitedString implementation to understand the full context find . -name 'DelimitedString.cs' -type f

84-117: RFC-4180 conformance claim requires clarification regarding doubled qualifier interpretation.

The implementation at line 54 claims RFC-4180 conformance, but RFC-4180 section 2.7 specifies that doubled qualifiers ("") within quoted fields should represent a single literal qualifier. The SplitSingleCharCsv method toggles inQuotes on every qualifier without interpreting doubled qualifiers as escape sequences.

However, the test Split_ShouldSplitPreservingQualifierOfTypeDoubleQuote validates that the implementation correctly handles input containing doubled qualifiers through a round-trip test (split + rejoin = original). This works because raw field data is preserved, not because doubled qualifiers are interpreted as escaped quotes.

The question is: does RFC-4180 conformance in this library mean (1) preserving raw input format (currently working), or (2) interpreting and unescaping doubled qualifiers (not currently implemented)? The existing test suggests the former is intentional, but the RFC-4180 reference should be clarified in documentation.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (3)
test/Cuemon.Security.Cryptography.Tests/UnkeyedCryptoHashTest.cs (2)

30-36: Ctor guard test is precise; consider extending coverage if base validates more args

The ctor test correctly asserts both the exception type and ParamName for a null initializer, which tightly couples to the guard you care about. If UnkeyedCryptoHash also guards other parameters (e.g., algorithm name), you might later add a similar negative test for those to keep coverage symmetric.


38-55: Hash computation tests correctly cross-check against framework SHA256

Both tests validate HasValue and compare against SHA256.ComputeHash for non-empty and empty input, which is exactly what you want to ensure the wrapper stays in lockstep with the platform implementation. If you add more unkeyed-hash tests in future, consider extracting the “compute expected via SHA256 and compare GetBytes()” logic into a small helper to avoid duplication, but it’s not necessary for the current size.

Also applies to: 57-73

test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm512Test.cs (1)

1-68: LGTM! Comprehensive HMAC-SHA512 test coverage.

The test suite correctly validates HmacSecureHashAlgorithm512 against System.Security.Cryptography.HMACSHA512 with appropriate scenario coverage.

Optional: Consider reducing test code duplication.

The HMAC test files (256, 384, 512) share nearly identical structure. Consider extracting a common test base class or using theory/inline data to reduce duplication, though this is a minor maintainability suggestion and not required.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6fbf13a and 934327c.

📒 Files selected for processing (17)
  • src/Cuemon.Security.Cryptography/AesCryptor.cs (3 hunks)
  • test/Cuemon.Core.Tests/Security/HashResultTest.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/HashTest.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/AesCryptorTest.cs (2 hunks)
  • test/Cuemon.Security.Cryptography.Tests/HmacMessageDigest5Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm1Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm256Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm384Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm512Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/KeyedCryptoHashTest.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/MessageDigest5Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/SHA512256Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm1Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm256Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm384Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm512Test.cs (1 hunks)
  • test/Cuemon.Security.Cryptography.Tests/UnkeyedCryptoHashTest.cs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (12)
test/Cuemon.Security.Cryptography.Tests/AesCryptorTest.cs (1)
src/Cuemon.Security.Cryptography/AesCryptor.cs (4)
  • GenerateInitializationVector (109-116)
  • GenerateKey (123-131)
  • Encrypt (68-71)
  • Decrypt (79-82)
test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm512Test.cs (1)
test/Cuemon.Core.Tests/Security/HashResultTest.cs (13)
  • Fact (13-19)
  • Fact (21-32)
  • Fact (34-47)
  • Fact (49-57)
  • Fact (59-66)
  • Fact (68-78)
  • Fact (80-90)
  • Fact (92-98)
  • Fact (100-105)
  • Fact (107-112)
  • Fact (114-122)
  • Fact (124-132)
  • Fact (134-144)
test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm256Test.cs (1)
test/Cuemon.Core.Tests/Security/HashTest.cs (3)
  • Fact (34-40)
  • Fact (42-49)
  • Fact (51-58)
test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm1Test.cs (2)
test/Cuemon.Core.Tests/Security/HashResultTest.cs (13)
  • Fact (13-19)
  • Fact (21-32)
  • Fact (34-47)
  • Fact (49-57)
  • Fact (59-66)
  • Fact (68-78)
  • Fact (80-90)
  • Fact (92-98)
  • Fact (100-105)
  • Fact (107-112)
  • Fact (114-122)
  • Fact (124-132)
  • Fact (134-144)
test/Cuemon.Core.Tests/Security/HashTest.cs (3)
  • Fact (34-40)
  • Fact (42-49)
  • Fact (51-58)
test/Cuemon.Core.Tests/Security/HashTest.cs (1)
src/Cuemon.Core/Convertible.cs (1)
  • Convertible (14-487)
test/Cuemon.Security.Cryptography.Tests/KeyedCryptoHashTest.cs (2)
test/Cuemon.Core.Tests/Security/HashResultTest.cs (13)
  • Fact (13-19)
  • Fact (21-32)
  • Fact (34-47)
  • Fact (49-57)
  • Fact (59-66)
  • Fact (68-78)
  • Fact (80-90)
  • Fact (92-98)
  • Fact (100-105)
  • Fact (107-112)
  • Fact (114-122)
  • Fact (124-132)
  • Fact (134-144)
test/Cuemon.Core.Tests/Security/HashTest.cs (3)
  • Fact (34-40)
  • Fact (42-49)
  • Fact (51-58)
test/Cuemon.Security.Cryptography.Tests/HmacMessageDigest5Test.cs (1)
test/Cuemon.Core.Tests/Security/HashResultTest.cs (13)
  • Fact (13-19)
  • Fact (21-32)
  • Fact (34-47)
  • Fact (49-57)
  • Fact (59-66)
  • Fact (68-78)
  • Fact (80-90)
  • Fact (92-98)
  • Fact (100-105)
  • Fact (107-112)
  • Fact (114-122)
  • Fact (124-132)
  • Fact (134-144)
test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm384Test.cs (2)
test/Cuemon.Core.Tests/Security/HashResultTest.cs (13)
  • Fact (13-19)
  • Fact (21-32)
  • Fact (34-47)
  • Fact (49-57)
  • Fact (59-66)
  • Fact (68-78)
  • Fact (80-90)
  • Fact (92-98)
  • Fact (100-105)
  • Fact (107-112)
  • Fact (114-122)
  • Fact (124-132)
  • Fact (134-144)
test/Cuemon.Core.Tests/Security/HashTest.cs (3)
  • Fact (34-40)
  • Fact (42-49)
  • Fact (51-58)
test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm256Test.cs (2)
test/Cuemon.Core.Tests/Security/HashResultTest.cs (13)
  • Fact (13-19)
  • Fact (21-32)
  • Fact (34-47)
  • Fact (49-57)
  • Fact (59-66)
  • Fact (68-78)
  • Fact (80-90)
  • Fact (92-98)
  • Fact (100-105)
  • Fact (107-112)
  • Fact (114-122)
  • Fact (124-132)
  • Fact (134-144)
test/Cuemon.Core.Tests/Security/HashTest.cs (3)
  • Fact (34-40)
  • Fact (42-49)
  • Fact (51-58)
test/Cuemon.Security.Cryptography.Tests/UnkeyedCryptoHashTest.cs (1)
test/Cuemon.Core.Tests/Security/HashResultTest.cs (13)
  • Fact (13-19)
  • Fact (21-32)
  • Fact (34-47)
  • Fact (49-57)
  • Fact (59-66)
  • Fact (68-78)
  • Fact (80-90)
  • Fact (92-98)
  • Fact (100-105)
  • Fact (107-112)
  • Fact (114-122)
  • Fact (124-132)
  • Fact (134-144)
test/Cuemon.Core.Tests/Security/HashResultTest.cs (1)
test/Cuemon.Core.Tests/Security/HashTest.cs (18)
  • Fact (34-40)
  • Fact (42-49)
  • Fact (51-58)
  • Fact (60-67)
  • Fact (69-76)
  • Fact (78-85)
  • Fact (87-94)
  • Fact (96-103)
  • Fact (105-112)
  • Fact (114-121)
  • Fact (123-130)
  • Fact (132-139)
  • Fact (141-148)
  • Fact (150-157)
  • Fact (159-166)
  • Fact (168-175)
  • HashResult (20-23)
  • HashResult (235-239)
test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm384Test.cs (2)
test/Cuemon.Core.Tests/Security/HashResultTest.cs (13)
  • Fact (13-19)
  • Fact (21-32)
  • Fact (34-47)
  • Fact (49-57)
  • Fact (59-66)
  • Fact (68-78)
  • Fact (80-90)
  • Fact (92-98)
  • Fact (100-105)
  • Fact (107-112)
  • Fact (114-122)
  • Fact (124-132)
  • Fact (134-144)
test/Cuemon.Core.Tests/Security/HashTest.cs (3)
  • Fact (34-40)
  • Fact (42-49)
  • Fact (51-58)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (42)
test/Cuemon.Security.Cryptography.Tests/UnkeyedCryptoHashTest.cs (1)

15-28: Well-scoped test-only hash subclasses

The two sealed nested types cleanly separate the “happy path” (Sha256TestHash) from the guard-path (NullInitializerHash), making intent obvious and keeping production code untouched. This is a solid pattern for exercising base-class behavior from tests.

test/Cuemon.Security.Cryptography.Tests/MessageDigest5Test.cs (1)

1-70: LGTM! Comprehensive test coverage for MessageDigest5.

The test suite appropriately validates the MD5 implementation against System.Security.Cryptography.MD5, covers edge cases (empty input, null inputs), and follows consistent testing patterns seen across the codebase.

test/Cuemon.Core.Tests/Security/HashResultTest.cs (1)

1-146: LGTM! Thorough test coverage for HashResult.

The test suite comprehensively validates HashResult behavior including value semantics, independent byte array copying, multiple string representations, equality/hashing semantics, and converter patterns. The reference-based equality behavior is clearly documented in the tests.

test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm256Test.cs (1)

1-68: LGTM! Comprehensive HMAC-SHA256 test coverage.

The test suite correctly validates HmacSecureHashAlgorithm256 against System.Security.Cryptography.HMACSHA256 and covers standard test scenarios (non-empty input, empty input, null secret, null input exception).

test/Cuemon.Security.Cryptography.Tests/KeyedCryptoHashTest.cs (1)

1-75: LGTM! KeyedCryptoHash test coverage is solid.

The test suite validates KeyedCryptoHash<T> using HMAC-SHA256 and HMAC-MD5 implementations, correctly comparing against standard cryptographic libraries and covering null input handling.

test/Cuemon.Core.Tests/Security/HashTest.cs (1)

1-343: LGTM! Excellent comprehensive test coverage for Hash abstraction.

The test suite thoroughly validates the Hash abstraction across all supported types and scenarios. The PassthroughHash and TestHash test implementations are well-designed to isolate and verify specific behaviors. Coverage includes:

  • All primitive type overloads
  • String encoding configurations
  • Enum handling
  • Parameter and enumerable aggregation
  • Stream processing
  • Endianness configuration
  • Options initialization
test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm384Test.cs (1)

1-68: LGTM! Comprehensive HMAC-SHA384 test coverage.

The test suite correctly validates HmacSecureHashAlgorithm384 against System.Security.Cryptography.HMACSHA384 with appropriate scenario coverage.

test/Cuemon.Security.Cryptography.Tests/HmacMessageDigest5Test.cs (1)

1-68: LGTM! Comprehensive HMAC-MD5 test coverage.

The test suite correctly validates HmacMessageDigest5 against System.Security.Cryptography.HMACMD5 with appropriate scenario coverage. While MD5 is cryptographically broken for security purposes, maintaining test coverage for legacy compatibility is acceptable.

test/Cuemon.Security.Cryptography.Tests/HmacSecureHashAlgorithm1Test.cs (4)

1-12: LGTM! Clean test class structure.

The imports, namespace, class structure, and constructor are properly organized and follow standard xUnit patterns.


14-31: LGTM! Well-structured test with proper resource management.

The test correctly validates HMAC-SHA1 computation against the standard library reference implementation and properly disposes of the HMACSHA1 instance.


33-50: LGTM! Good edge case coverage.

Testing with an empty array ensures the implementation handles edge cases correctly. The test follows the same solid pattern as the previous test.


52-58: LGTM! Correct validation of null-secret handling.

The test properly verifies that the constructor accepts a null secret without throwing an exception using Record.Exception.

test/Cuemon.Security.Cryptography.Tests/SHA512256Test.cs (6)

1-11: LGTM!

Standard test class setup with appropriate dependencies.


13-18: LGTM!

Constructor test correctly verifies the hash size and properly disposes the instance.


20-36: LGTM!

The reflection-based test correctly verifies big-endian byte writing at a specific offset.


38-58: LGTM!

Good test coverage for bit rotation with both edge cases and arbitrary rotations.


156-171: LGTM!

Excellent test that verifies both the output length and deterministic behavior of the hash function with proper resource management.


173-184: LGTM!

Good edge-case test for empty input with proper resource management.

test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm512Test.cs (4)

14-18: BitSize test correctly validates 512 bits

The test targets SecureHashAlgorithm512.BitSize and the expected value matches the algorithm size.


20-27: Constructor options test is exercising the right behavior

The ctor-based setup correctly configures ByteOrder to BigEndian and asserts against sut.Options.


29-45: SHA‑512 hash test for non‑empty input is sound

The test compares ComputeHash("hello") against SHA512.Create().ComputeHash, which is the right oracle and ensures HasValue is true.


47-63: SHA‑512 hash test for empty input is correct

Empty array handling is validated against SHA512.Create().ComputeHash(Array.Empty<byte>()), which gives good coverage of the edge case.

test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm384Test.cs (4)

14-18: BitSize test correctly validates 384 bits

The test asserts SecureHashAlgorithm384.BitSize == 384, matching the algorithm’s width.


20-27: Constructor options test correctly wires ByteOrder

The setup delegate configures ByteOrder to BigEndian and verifies sut.Options accordingly.


29-45: SHA‑384 hash test for non‑empty input is well‑formed

The result of ComputeHash("hello") is compared to SHA384.Create().ComputeHash, giving a solid reference check.


47-63: SHA‑384 hash test for empty input covers the edge case

Empty input behavior is validated against the framework’s SHA‑384 implementation, mirroring the non‑empty case.

test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm256Test.cs (3)

14-18: BitSize test correctly validates 256 bits

The assertion on SecureHashAlgorithm256.BitSize matching 256 is appropriate.


29-45: SHA‑256 hash test for non‑empty input is correct

The test compares ComputeHash("hello") against SHA256.Create().ComputeHash, providing a reliable reference.


47-63: SHA‑256 hash test for empty input is appropriate

Empty array handling is verified against SHA256.Create().ComputeHash(Array.Empty<byte>()), giving good coverage.

test/Cuemon.Security.Cryptography.Tests/SecureHashAlgorithm1Test.cs (4)

14-18: BitSize test correctly validates 160 bits

The test asserts SecureHashAlgorithm1.BitSize == 160, which aligns with SHA‑1.


20-27: Constructor options test validates ByteOrder wiring

Using the setup delegate to set ByteOrder to BigEndian and asserting via sut.Options is correct.


29-45: SHA‑1 hash test for non‑empty input is sound

The algorithm output for "hello" is verified against SHA1.Create().ComputeHash, ensuring correctness.


47-63: SHA‑1 hash test for empty input correctly covers the edge case

Empty array hashing is validated against the framework SHA‑1 implementation, mirroring other tests.

src/Cuemon.Security.Cryptography/AesCryptor.cs (1)

96-100: Excellent refactoring to direct transform API.

The migration from a streaming approach (MemoryStream/CryptoStream) to the direct TransformFinalBlock pattern simplifies the code and eliminates unnecessary overhead for in-memory operations. This is the idiomatic .NET approach for encrypting/decrypting byte arrays that are already loaded in memory.

test/Cuemon.Security.Cryptography.Tests/AesCryptorTest.cs (8)

38-50: Comprehensive default constructor validation.

The test correctly validates that the default constructor produces cryptographically valid key and IV lengths (256-bit key for AES-256, 128-bit IV for block size). The inline comments and use of Convertible.BitsPerByte enhance readability.


52-63: Good validation of reference semantics.

Using Assert.Same to verify that the constructor stores the exact key and IV references (rather than defensive copies) is the right approach for confirming the expected reference semantics.


65-77: Proper null-argument validation coverage.

These tests correctly validate that the constructor throws ArgumentNullException for null key or IV parameters, ensuring proper precondition enforcement.


79-98: Thorough validation of size constraints.

These tests properly validate that invalid key or IV sizes throw CryptographicException with appropriate error messages, ensuring the constructor enforces AES size requirements (128/192/256-bit keys, 128-bit IV).


100-118: Essential end-to-end encryption validation.

This test provides critical validation of the core encrypt/decrypt functionality, confirming that encryption produces different output and decryption successfully recovers the original plaintext.


120-137: Good coverage of options configuration path.

Testing the options delegate overload with explicit parameters (even though they match defaults) ensures the options configuration mechanism works correctly. The inline comment clearly explains the test's intent.


139-152: Appropriate validation of IV generation.

The test correctly validates IV length and typical uniqueness between successive calls. The comment acknowledging the small collision probability demonstrates appropriate awareness of the probabilistic nature of randomness testing.


154-174: Comprehensive key generation validation.

This test thoroughly validates the GenerateKey method across multiple scenarios: default AES-256, explicit AES-128 size, and custom RandomStringProvider. The coverage ensures both default behavior and configurability work correctly.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
test/Cuemon.Core.Tests/Security/FowlerNollVo128Test.cs (1)

42-81: Duplicated helper method.

This IndependentFNVMultiWord implementation is identical to those in FowlerNollVo256Test, FowlerNollVo512Test, and FowlerNollVo1024Test. See the comment on FowlerNollVo1024Test for the refactoring suggestion.

test/Cuemon.Core.Tests/Security/FowlerNollVo512Test.cs (1)

38-77: Duplicated helper method.

Same IndependentFNVMultiWord duplication as noted in other multi-word FNV test files. See the comment on FowlerNollVo1024Test for the refactoring suggestion.

🧹 Nitpick comments (8)
test/Cuemon.Core.Tests/Security/FowlerNollVo64Test.cs (1)

19-37: Consider expanding test coverage for consistency with FowlerNollVo32Test.

Compared to FowlerNollVo32Test, this test file is missing:

  • FNV-1 algorithm validation (line 33 only sets Fnv1a)
  • Little-endian byte order test
  • Verification of actual offset basis bytes in the empty hash test (only checks length)

These gaps reduce confidence in the 64-bit implementation's correctness across all configuration options.

test/Cuemon.Core.Tests/Security/FowlerNollVo1024Test.cs (1)

38-77: Extract duplicated helper to shared test utility.

IndependentFNVMultiWord is duplicated verbatim across FowlerNollVo128Test, FowlerNollVo256Test, FowlerNollVo512Test, and FowlerNollVo1024Test. Consider extracting it to a shared test utility class (e.g., FowlerNollVoTestHelper) to reduce maintenance burden and ensure consistency.

-        private static byte[] IndependentFNVMultiWord(byte[] input, BigInteger prime, BigInteger offsetBasis, short bits, FowlerNollVoOptions options)
-        {
-            // ... implementation
-        }
+        // Move to: test/Cuemon.Core.Tests/Security/FowlerNollVoTestHelper.cs
+        // internal static class FowlerNollVoTestHelper
+        // {
+        //     public static byte[] IndependentFNVMultiWord(...) { ... }
+        // }
test/Cuemon.Core.Tests/Security/FowlerNollVo256Test.cs (2)

12-25: Strengthen empty-input test to actually verify the offset-basis value

ComputeHash_Empty_ReturnsOffsetBasis_LengthIs32Bytes currently only asserts the length of the hash. The name and FNV semantics suggest we should also verify that the bytes correspond to the offset basis for the configured options.

You can tighten this by using the existing independent implementation to compute the expected empty-hash and asserting equality:

         [Fact]
         public void ComputeHash_Empty_ReturnsOffsetBasis_LengthIs32Bytes()
         {
             var sut = new FowlerNollVo256();
             var result = sut.ComputeHash(Array.Empty<byte>()).GetBytes();
-            Assert.Equal(32, result.Length);
+            Assert.Equal(32, result.Length);
+
+            var expected = IndependentFNVMultiWord(Array.Empty<byte>(), sut.Prime, sut.OffsetBasis, sut.Bits, sut.Options);
+            Assert.Equal(expected, result);
         }

38-77: DRY up IndependentFNVMultiWord across FNV test variants

This helper is effectively identical to the versions in FowlerNollVo128Test and FowlerNollVo1024Test (and likely other bit-width tests). Duplicating this BigInteger implementation in each test file makes future fixes or tweaks error-prone.

Consider moving IndependentFNVMultiWord into a shared test helper (e.g., a static class in the test project) and reusing it across all FNV tests. While you’re there, you could also simplify the copy loop with Buffer.BlockCopy or Array.Copy instead of assigning each byte individually.

src/Cuemon.Core/Security/CyclicRedundancyCheck.cs (1)

12-41: Lookup-table refactor removes allocations and keeps initialization clear

The move to Lazy<ulong[]> plus an array-returning PolynomialTableInitializerCore nicely avoids the extra List + ToArray overhead while preserving the existing table semantics used by CyclicRedundancyCheck32/64 and the new tests. The protected LookupTable now exposes the backing array directly, which is fine for trusted derived types; if you ever want stronger immutability guarantees, you could later switch the property to an IReadOnlyList<ulong> or return a copy, but that’s not necessary for this change set.

Also applies to: 47-47

test/Cuemon.Core.Tests/Security/CyclicRedundancyCheck64Test.cs (1)

1-121: Comprehensive CRC64 coverage; minor test polish and import check

These tests give good confidence: they validate constructor defaults, both internal primitives via reflection, lookup-table contents against a recomputation, memoization across accesses, and the standard CRC‑64‑ECMA‑182 vector for "123456789".

Two small follow-ups you might consider:

  • Use nameof(CyclicRedundancyCheck64.PolynomialIndexInitializer) / nameof(CyclicRedundancyCheck64.PolynomialSlotCalculator) instead of string literals in GetMethod to make the reflection a bit more refactor‑friendly.
  • Optionally add a ComputeHash test that asserts ArgumentNullException is thrown for null input, to lock in the new Validator.ThrowIfNull(input) behavior.

Also, please confirm that ITestOutputHelper is available in this project via an existing using or global using (e.g., Xunit.Abstractions), since it’s referenced here but not explicitly imported in this file.

test/Cuemon.Core.Tests/Security/CyclicRedundancyCheckTest.cs (1)

1-82: Good focused tests for CRC lookup-table generation and memoization

The TestCrc helper cleanly isolates the table-generation behavior, and the tests around initial/final values, specific table entries, polynomial sensitivity, and repeated access all line up well with the new Lazy<ulong[]> implementation.

If you want to refine this further:

  • The inline comments already document the arithmetic; you could mirror that style in TestCrc itself (e.g., brief comment in PolynomialIndexInitializer) to keep behavior obvious where it’s defined.
  • As with the other test classes, please double‑check that ITestOutputHelper is in scope via an appropriate using/global using for the project configuration.

Overall, this is a solid white‑box test harness around the CRC base class.

test/Cuemon.Core.Tests/Security/CyclicRedundancyCheck32Test.cs (1)

1-113: Thorough CRC32 tests aligned with implementation and standard vector

This suite nicely exercises constructor defaults, internal index/slot behavior via reflection, the lookup table contents against a recomputation, and the canonical CRC‑32 (IEEE 802.3) value for "123456789" with input/output reflection enabled.

Possible light improvements:

  • Replace string literals in GetMethod with nameof(CyclicRedundancyCheck32.PolynomialIndexInitializer) / nameof(CyclicRedundancyCheck32.PolynomialSlotCalculator) to make the tests more resilient to refactors.
  • Optionally add a test that ComputeHash(null) throws ArgumentNullException to pin down the new Validator.ThrowIfNull(input) behavior.

As with the other test files, please verify that ITestOutputHelper is correctly brought into scope (e.g., via Xunit.Abstractions or a global using) given it’s referenced in the constructor.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 934327c and f77066c.

📒 Files selected for processing (12)
  • src/Cuemon.Core/Security/CyclicRedundancyCheck.cs (2 hunks)
  • src/Cuemon.Core/Security/CyclicRedundancyCheck32.cs (1 hunks)
  • src/Cuemon.Core/Security/CyclicRedundancyCheck64.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/CyclicRedundancyCheck32Test.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/CyclicRedundancyCheck64Test.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/CyclicRedundancyCheckTest.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/FowlerNollVo1024Test.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/FowlerNollVo128Test.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/FowlerNollVo256Test.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/FowlerNollVo32Test.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/FowlerNollVo512Test.cs (1 hunks)
  • test/Cuemon.Core.Tests/Security/FowlerNollVo64Test.cs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (10)
test/Cuemon.Core.Tests/Security/FowlerNollVo64Test.cs (1)
test/Cuemon.Core.Tests/Security/FowlerNollVo1024Test.cs (1)
  • Fact (12-17)
test/Cuemon.Core.Tests/Security/FowlerNollVo512Test.cs (1)
src/Cuemon.Core/Convertible.cs (2)
  • Convertible (14-487)
  • ReverseEndianness (456-469)
test/Cuemon.Core.Tests/Security/FowlerNollVo1024Test.cs (3)
test/Cuemon.Core.Tests/Security/FowlerNollVo128Test.cs (1)
  • IndependentFNVMultiWord (42-81)
test/Cuemon.Core.Tests/Security/FowlerNollVo256Test.cs (1)
  • IndependentFNVMultiWord (38-77)
test/Cuemon.Core.Tests/Security/FowlerNollVo512Test.cs (1)
  • IndependentFNVMultiWord (38-77)
src/Cuemon.Core/Security/CyclicRedundancyCheck32.cs (1)
src/Cuemon.Core/Validator.cs (1)
  • Validator (15-1150)
test/Cuemon.Core.Tests/Security/CyclicRedundancyCheck64Test.cs (2)
test/Cuemon.Core.Tests/Security/CyclicRedundancyCheck32Test.cs (5)
  • Fact (15-21)
  • Fact (23-37)
  • Fact (39-61)
  • Fact (63-95)
  • Fact (97-112)
test/Cuemon.Core.Tests/Security/CyclicRedundancyCheckTest.cs (4)
  • Fact (13-19)
  • Fact (21-33)
  • Fact (35-45)
  • Fact (47-55)
test/Cuemon.Core.Tests/Security/FowlerNollVo128Test.cs (3)
test/Cuemon.Core.Tests/Security/FowlerNollVo1024Test.cs (1)
  • IndependentFNVMultiWord (38-77)
test/Cuemon.Core.Tests/Security/FowlerNollVo256Test.cs (1)
  • IndependentFNVMultiWord (38-77)
src/Cuemon.Core/Convertible.cs (2)
  • Convertible (14-487)
  • ReverseEndianness (456-469)
test/Cuemon.Core.Tests/Security/CyclicRedundancyCheckTest.cs (2)
test/Cuemon.Core.Tests/Security/CyclicRedundancyCheck32Test.cs (5)
  • Fact (15-21)
  • Fact (23-37)
  • Fact (39-61)
  • Fact (63-95)
  • Fact (97-112)
test/Cuemon.Core.Tests/Security/CyclicRedundancyCheck64Test.cs (6)
  • Fact (15-21)
  • Fact (23-37)
  • Fact (39-61)
  • Fact (63-95)
  • Fact (97-108)
  • Fact (110-121)
src/Cuemon.Core/Security/CyclicRedundancyCheck64.cs (1)
src/Cuemon.Core/Validator.cs (1)
  • Validator (15-1150)
src/Cuemon.Core/Security/CyclicRedundancyCheck.cs (2)
src/Cuemon.Core/Security/CyclicRedundancyCheck32.cs (2)
  • PolynomialIndexInitializer (46-49)
  • PolynomialSlotCalculator (28-39)
src/Cuemon.Core/Security/CyclicRedundancyCheck64.cs (2)
  • PolynomialIndexInitializer (28-31)
  • PolynomialSlotCalculator (38-49)
test/Cuemon.Core.Tests/Security/FowlerNollVo256Test.cs (3)
test/Cuemon.Core.Tests/Security/FowlerNollVo1024Test.cs (1)
  • IndependentFNVMultiWord (38-77)
test/Cuemon.Core.Tests/Security/FowlerNollVo128Test.cs (1)
  • IndependentFNVMultiWord (42-81)
src/Cuemon.Core/Convertible.cs (2)
  • Convertible (14-487)
  • ReverseEndianness (456-469)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (7)
test/Cuemon.Core.Tests/Security/FowlerNollVo32Test.cs (1)

1-94: Well-structured tests with comprehensive coverage.

This test file provides excellent coverage for the 32-bit FNV implementation, validating both FNV-1 and FNV-1a algorithms, as well as both big-endian and little-endian byte ordering. The independent reference implementation is a good approach for verifying correctness.

test/Cuemon.Core.Tests/Security/FowlerNollVo1024Test.cs (1)

12-36: Test logic is correct; consider adding FNV-1 and endianness coverage.

The constructor, empty hash, and non-empty hash tests are well-implemented and validate correctness against the independent reference. For consistency with FowlerNollVo32Test, consider adding tests for the FNV-1 algorithm variant and little-endian byte order.

test/Cuemon.Core.Tests/Security/FowlerNollVo128Test.cs (1)

19-40: Good endianness coverage; FNV-1 algorithm test would complete the suite.

The empty hash test validates both big-endian (default) and little-endian configurations, which is better coverage than some other bit-width tests. Adding a test case for FowlerNollVoAlgorithm.Fnv1 would ensure both algorithm variants work correctly for 128-bit hashes.

test/Cuemon.Core.Tests/Security/FowlerNollVo512Test.cs (1)

12-36: Tests validate core functionality correctly.

The constructor, empty hash length, and non-empty hash tests properly verify the 512-bit FNV implementation against the independent reference. The test structure follows the established pattern across the FNV test suite.

test/Cuemon.Core.Tests/Security/FowlerNollVo256Test.cs (1)

27-36: Good coverage of the 256-bit multi-word implementation vs. independent reference

The non-empty hash test correctly configures FNV-1a, runs the production FowlerNollVo256 implementation, and verifies the result against an independent BigInteger-based reference. This is a solid oracle-style test that should catch regressions in the 256-bit multi-word path.

src/Cuemon.Core/Security/CyclicRedundancyCheck32.cs (1)

59-63: Defensive null-check and Length-based iteration look solid

Using Validator.ThrowIfNull(input) gives a clear ArgumentNullException for null inputs, and switching to input.Length is idiomatic and equivalent for byte[] while keeping the loop simple and efficient.

src/Cuemon.Core/Security/CyclicRedundancyCheck64.cs (1)

59-63: Consistent null-guard and loop bound with CRC32 implementation

Mirroring CRC32 by adding Validator.ThrowIfNull(input) and iterating with input.Length keeps the 64-bit implementation defensive and idiomatic without altering the hash for valid inputs.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
.github/copilot-instructions.md (1)

59-59: Minor wording improvement.

"Exact same" is slightly wordy; consider using "the same" or "identical" instead.

- then the corresponding unit test class must use the exact same namespace:
+ then the corresponding unit test class must use the same namespace:
test/Cuemon.Core.Tests/Security/HashFactoryTest.cs (2)

258-266: Default FNV factory test is clear; small assertion-ordering nit

This nicely pins down that CreateFnv() maps to the 32‑bit implementation. For slightly clearer failure messages, consider using CreateFnv32 as the expected value and CreateFnv as the actual in Assert.Equal (expected first, actual second in xUnit), but behavior is fine as‑is.


268-290: Good coverage of NonCryptoAlgorithm→factory mapping; could be DRY’d with a theory

This test thoroughly verifies that each NonCryptoAlgorithm.Fnv* case returns the same result as its dedicated factory. If you want to reduce repetition, consider a [Theory] with (NonCryptoAlgorithm, Func<IHashFactory>) pairs, but that’s optional and the current explicit form is perfectly readable.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f77066c and cb33dc4.

📒 Files selected for processing (5)
  • .github/copilot-instructions.md (1 hunks)
  • .github/prompts/benchmark.prompt.md (1 hunks)
  • .github/workflows/ci-pipeline.yml (2 hunks)
  • Directory.Packages.props (2 hunks)
  • test/Cuemon.Core.Tests/Security/HashFactoryTest.cs (1 hunks)
🧰 Additional context used
🪛 LanguageTool
.github/copilot-instructions.md

[style] ~59-~59: ‘exact same’ might be wordy. Consider a shorter alternative.
Context: ...responding unit test class must use the exact same namespace: ```csharp namespace ...

(EN_WORDINESS_PREMIUM_EXACT_SAME)

🪛 markdownlint-cli2 (0.18.1)
.github/prompts/benchmark.prompt.md

33-33: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

.github/copilot-instructions.md

156-156: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


157-157: Spaces inside emphasis markers

(MD037, no-space-in-emphasis)


169-169: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


183-183: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


184-184: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


185-185: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


186-186: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


187-187: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


250-250: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (7)
.github/workflows/ci-pipeline.yml (3)

65-99: YAML structure and matrix inheritance look correct.

The matrix strategy is properly defined, job dependencies are correctly declared, and the dynamic runs-on substitution uses correct GitHub Actions syntax. Once runner availability is confirmed, this change will enable broader cross-platform test coverage.


88-88: The Windows runner names windows-2025 and windows-11-arm are both valid and officially available on GitHub Actions. No issues found.

The verification confirms that both runner labels are legitimate and documented in the official GitHub Actions runner reference:

  • windows-2025 is an x64-based runner (Windows Server 2025)
  • windows-11-arm is an ARM64-based runner

The original concerns about these runners being unavailable or non-standard are incorrect. The workflow configuration is valid and will not fail due to runner name issues.


71-71: The specified runner names are all valid and available as GitHub-hosted runners — no issue exists.

Based on verification:

  • ubuntu-24.04-arm and windows-11-arm are official GitHub-hosted arm64 runners (generally available since August 7, 2025) for public repositories
  • windows-2025 is an official GitHub-hosted x64 Windows runner
  • No custom runner configuration exists in the repository; all referenced runners are standard GitHub-hosted options

The repository (codebeltnet/cuemon) is public, so these runners are available and will not cause pipeline failures.

.github/copilot-instructions.md (1)

543-582: Comprehensive and well-documented FowlerNollVoOptions example.

The FowlerNollVoOptions example demonstrates proper XML documentation for the new configuration class introduced in this PR. The documentation clearly outlines the default constructor behavior, property descriptions, and a useful table documenting initial property values. This aligns well with the PR's objective to add public FowlerNollVoOptions and support multiple FNV hash variants.

test/Cuemon.Core.Tests/Security/HashFactoryTest.cs (1)

292-303: CRC64 parameterized/preset parity test looks solid

This is a good safeguard to ensure the explicit polynomial/initial/xor/reflect configuration stays in lockstep with CreateCrc64GoIso(). The use of the same input and normalized hex casing makes the intent clear; no issues from my side.

Directory.Packages.props (1)

7-8: LGTM! Package updates support the new benchmarking infrastructure.

The addition of BenchmarkDotNet packages (v0.15.6) aligns with the PR objectives to introduce performance benchmarking capabilities, and the xunit patch version updates (3.2.0 → 3.2.1) are routine maintenance.

Also applies to: 19-20

.github/prompts/benchmark.prompt.md (1)

1-165: Excellent benchmark documentation!

This comprehensive guide provides clear conventions for writing performance benchmarks in Cuemon. The structure covers all essential aspects: naming conventions, BenchmarkDotNet configuration, best practices, and concrete examples. This will serve as valuable reference documentation for the new benchmarking infrastructure introduced in this PR.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb33dc4 and ce113e8.

📒 Files selected for processing (6)
  • src/Cuemon.Core/Configuration/IPostConfigurableParameterObject.cs (1 hunks)
  • src/Cuemon.Core/Validator.cs (1 hunks)
  • test/Cuemon.Core.Tests/Assets/FailPostConfigurableOptions.cs (1 hunks)
  • test/Cuemon.Core.Tests/Assets/PostConfigurableOptions.cs (1 hunks)
  • test/Cuemon.Core.Tests/Reflection/AssemblyDecoratorExtensionsTest.cs (1 hunks)
  • test/Cuemon.Core.Tests/ValidatorTest.cs (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • test/Cuemon.Core.Tests/Reflection/AssemblyDecoratorExtensionsTest.cs
🧰 Additional context used
🧬 Code graph analysis (5)
test/Cuemon.Core.Tests/Assets/PostConfigurableOptions.cs (2)
src/Cuemon.Core/Configuration/IPostConfigurableParameterObject.cs (1)
  • PostConfigureOptions (11-11)
src/Cuemon.Core/Validator.cs (1)
  • Validator (15-1151)
src/Cuemon.Core/Validator.cs (3)
src/Cuemon.Core/Configuration/IPostConfigurableParameterObject.cs (1)
  • PostConfigureOptions (11-11)
test/Cuemon.Core.Tests/Assets/FailPostConfigurableOptions.cs (1)
  • PostConfigureOptions (13-15)
test/Cuemon.Core.Tests/Assets/PostConfigurableOptions.cs (1)
  • PostConfigureOptions (14-17)
src/Cuemon.Core/Configuration/IPostConfigurableParameterObject.cs (2)
test/Cuemon.Core.Tests/Assets/FailPostConfigurableOptions.cs (1)
  • PostConfigureOptions (13-15)
test/Cuemon.Core.Tests/Assets/PostConfigurableOptions.cs (1)
  • PostConfigureOptions (14-17)
test/Cuemon.Core.Tests/Assets/FailPostConfigurableOptions.cs (2)
test/Cuemon.Core.Tests/Assets/PostConfigurableOptions.cs (3)
  • PostConfigurableOptions (6-23)
  • PostConfigurableOptions (8-10)
  • PostConfigureOptions (14-17)
src/Cuemon.Core/Configuration/IPostConfigurableParameterObject.cs (1)
  • PostConfigureOptions (11-11)
test/Cuemon.Core.Tests/ValidatorTest.cs (3)
test/Cuemon.Core.Tests/Assets/PostConfigurableOptions.cs (2)
  • PostConfigurableOptions (6-23)
  • PostConfigurableOptions (8-10)
src/Cuemon.Core/Validator.cs (2)
  • Validator (15-1151)
  • ThrowIfInvalidOptions (90-103)
test/Cuemon.Core.Tests/Assets/FailPostConfigurableOptions.cs (2)
  • FailPostConfigurableOptions (5-16)
  • FailPostConfigurableOptions (7-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (4)
src/Cuemon.Core/Validator.cs (1)

95-95: LGTM! Post-configuration integration is clean.

The post-configuration step is correctly integrated into the validation flow, executing before ValidateOptions() and within the existing exception handling.

test/Cuemon.Core.Tests/ValidatorTest.cs (1)

187-202: LGTM! Tests validate post-configuration lifecycle.

Both tests appropriately cover the post-configuration behavior: one verifying successful initialization and validation, the other confirming that failure to initialize results in the expected exception.

src/Cuemon.Core/Configuration/IPostConfigurableParameterObject.cs (1)

1-13: LGTM! Interface design is clean and well-documented.

The interface appropriately extends IParameterObject and provides a clear lifecycle hook for post-configuration logic. The documentation clearly explains its purpose.

test/Cuemon.Core.Tests/Assets/PostConfigurableOptions.cs (1)

6-23: LGTM! Clean test asset demonstrating post-configuration pattern.

The class effectively demonstrates the post-configuration lifecycle: PostConfigureOptions() initializes required state (Id), and ValidateOptions() verifies that initialization occurred. The virtual modifier on PostConfigureOptions() appropriately allows derived test classes to override the behavior.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
.github/copilot-instructions.md (2)

156-187: Resolve outstanding markdown formatting violations.

These markdown style issues were flagged in the previous review and remain unfixed:

  • Line 160: Use atx-style heading (##) instead of setext underline
  • Line 169: Add language identifier to fenced code block (should be ```csharp)
  • Lines 183–187: Change 4-space indentation to 2-space for list items

Apply this diff to fix the heading and code block:

- # Writing Performance Tests in Cuemon
- This document provides guidance for writing performance tests (benchmarks) in the Cuemon codebase using BenchmarkDotNet. Follow these guidelines to keep benchmarks consistent, readable, and comparable.
+ ## Writing Performance Tests in Cuemon
+ 
+ This document provides guidance for writing performance tests (benchmarks) in the Cuemon codebase using BenchmarkDotNet. Follow these guidelines to keep benchmarks consistent, readable, and comparable.

For the code block language identifier:

- ```
- namespace Cuemon.Security.Cryptography
+ ```csharp
+ namespace Cuemon.Security.Cryptography

For the list indentation (lines 183–187):

- - Use `BenchmarkDotNet` attributes to express intent and collect relevant metrics:
-     - `[MemoryDiagnoser]` to capture memory allocations.
-     - `[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]` to group related benchmarks.
-     - `[Params]` for input sizes or variations to exercise multiple scenarios.
-     - `[GlobalSetup]` for one-time initialization that's not part of measured work.
-     - `[Benchmark]` on methods representing measured operations; consider `Baseline = true` and `Description` to improve report clarity.
+ - Use `BenchmarkDotNet` attributes to express intent and collect relevant metrics:
+   - `[MemoryDiagnoser]` to capture memory allocations.
+   - `[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]` to group related benchmarks.
+   - `[Params]` for input sizes or variations to exercise multiple scenarios.
+   - `[GlobalSetup]` for one-time initialization that's not part of measured work.
+   - `[Benchmark]` on methods representing measured operations; consider `Baseline = true` and `Description` to improve report clarity.

254-254: Fix setext-style heading at line 254 to match atx convention.

Line 254 uses a setext-style heading (underline), which should be converted to an atx-style heading (##) for consistency with the document.

- # Writing XML documentation in Cuemon
- 
- This document provides instructions for writing XML documentation.
+ ## Writing XML documentation in Cuemon
+ 
+ This document provides instructions for writing XML documentation.
🧹 Nitpick comments (4)
.nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt (1)

1-5: Document significant enhancements and refactoring in release notes.

The release notes for Version 10.1.0 currently document only dependency upgrades. However, per the PR objectives, this release includes significant changes:

  • DateSpan structure refactoring with improved hash/equality logic and extracted helper methods
  • Fowler–Noll–Vo hash implementation enhancements supporting multiple bit sizes (32–1024)
  • Codebase cleanup (GlobalSuppressions.cs modifications)

While dependency updates are important, the release notes should also highlight these key improvements to inform users about enhancements and any potential impact. Consider adding relevant entries to the # Improvements or # New Features sections if these changes are visible to Cuemon.AspNetCore consumers, or clarify whether these changes are internal-only.

.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt (1)

1-6: Release notes entry is minimal; consider adding details about notable changes.

The new 10.1.0 entry follows the established format and is consistent with 10.0.0. However, the ALM-only note omits the feature and refactoring improvements mentioned in the PR summary (DateSpan refactoring, FNV hash enhancements, and internal optimizations).

Consider adding a new category (e.g., # IMPROVED or # CHANGED - Internal) to document these changes for clarity and completeness, especially if they may affect users' performance characteristics or upgrade considerations.

Optionally, you may add a section like:

 Version 10.1.0
 Availability: .NET 10, .NET 9 and .NET Standard 2.0
 
 # ALM
 - CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)
+
+# IMPROVED
+- REFACTORED DateSpan structure to improve maintainability and readability
+- ENHANCED Fowler–Noll–Vo hash implementation with support for multiple bit sizes (32, 64, 128, 256, 512, 1024)

This is optional and depends on your release notes documentation policy.

.github/copilot-instructions.md (1)

59-59: Remove redundant wording in line 59.

The phrase "exact same namespace" is redundant; "same namespace" is sufficient.

- then the corresponding unit test class must use the exact same namespace:
+ then the corresponding unit test class must use the same namespace:
src/Cuemon.Security.Cryptography/AesCryptor.cs (1)

86-101: AES TransformFinalBlock refactor looks sound; consider behavior verification and a small refactor

The new path that configures Aes, selects an encryptor/decryptor, and calls TransformFinalBlock(value, 0, value.Length) is correct for a byte[]‑based API and should be faster and simpler than the previous MemoryStream/CryptoStream orchestration.

A couple of follow‑ups to consider:

  • If earlier implementations trimmed trailing zeros after decryption (as hinted in the PR summary), this refactor now returns the raw decrypted bytes as produced by AES + Padding. That is generally more correct, but it is an observable behavior change. Please double‑check callers (and tests) that might have relied on implicit trimming, especially when using non‑default paddings (e.g., PaddingMode.Zeros or PaddingMode.None).
  • For readability, you can remove one nesting level by switching to using var and an early return:
-            using (var transform = mode == AesMode.Encrypt
-                       ? aes.CreateEncryptor()
-                       : aes.CreateDecryptor())
-            {
-                return transform.TransformFinalBlock(value, 0, value.Length);
-            }
+            using var transform = mode == AesMode.Encrypt
+                ? aes.CreateEncryptor()
+                : aes.CreateDecryptor();
+
+            return transform.TransformFinalBlock(value, 0, value.Length);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ce113e8 and 7f2f009.

📒 Files selected for processing (46)
  • .github/copilot-instructions.md (1 hunks)
  • .nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Core.App/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Core/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Data/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.IO/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Net/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Resilience/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Threading/PackageReleaseNotes.txt (1 hunks)
  • .nuget/Cuemon.Xml/PackageReleaseNotes.txt (1 hunks)
  • CHANGELOG.md (1 hunks)
  • Directory.Packages.props (2 hunks)
  • src/Cuemon.Security.Cryptography/AesCryptor.cs (2 hunks)
✅ Files skipped from review due to trivial changes (15)
  • .nuget/Cuemon.Resilience/PackageReleaseNotes.txt
  • .nuget/Cuemon.Core.App/PackageReleaseNotes.txt
  • .nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt
  • .nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt
  • .nuget/Cuemon.Threading/PackageReleaseNotes.txt
  • .nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt
  • .nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt
  • .nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt
  • .nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt
  • .nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt
  • .nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt
  • .nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt
  • .nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt
  • .nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt
  • .nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt
🧰 Additional context used
🪛 LanguageTool
.nuget/Cuemon.Core/PackageReleaseNotes.txt

[grammar] ~15-~15: Ensure spelling is correct
Context: ...fiers, reducing overhead and allocations - OPTMIZED CyclicRedundancyCheck class in the Cuem...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

.github/copilot-instructions.md

[style] ~59-~59: ‘exact same’ might be wordy. Consider a shorter alternative.
Context: ...responding unit test class must use the exact same namespace: ```csharp namespace ...

(EN_WORDINESS_PREMIUM_EXACT_SAME)

🪛 markdownlint-cli2 (0.18.1)
.github/copilot-instructions.md

156-156: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


157-157: Spaces inside emphasis markers

(MD037, no-space-in-emphasis)


169-169: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


183-183: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


184-184: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


185-185: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


186-186: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


187-187: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


250-250: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (26)
.nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt (1)

1-6: Release notes update is consistent and appropriate.

The new Version 10.1.0 section is well-formatted, follows the established structure of existing entries, and accurately documents the dependency upgrades that accompany this release. The availability and ALM information align with the PR objectives.

.nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt (1)

1-6: Version 10.1.0 entry is well-formatted and consistent.

The new release notes entry follows the established format and properly documents the dependency upgrades for this package. The availability statement and ALM section align with the PR's broader package update scope.

.nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt (1)

1-5: Clarify version numbering: PR branch names v10.0.1 but release notes show 10.1.0.

The release notes entry uses semantic versioning 10.1.0 (minor version bump), while the PR branch is named v10.0.1/ai-assisted-performance-boost (patch version). Given the scope of changes (DateSpan refactoring, FNV multi-width hash support, CI enhancements, unit tests), a minor version bump (10.1.0) is more appropriate than a patch (10.0.1). However, verify this is intentional and consistent with your versioning strategy.

Format and content are otherwise well-structured and consistent with the rest of the release notes document.

.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt (1)

1-2: Verify version numbering alignment with PR branch.

The release notes show version 10.1.0, but the PR branch is named "v10.0.1/ai-assisted-performance-boost". Confirm that version 10.1.0 is the intended release version for this PR and that version numbering aligns with your semantic versioning strategy.

.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt (1)

1-5: Release notes entry is well-formatted and accurate.

The new Version 10.1.0 entry follows the established format, correctly states the supported TFMs (.NET 10, .NET 9, and .NET Standard 2.0), and appropriately documents the dependency upgrade. The minimal content aligns with the AI summary indicating no functional or public API changes to the Threading package itself.

.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt (1)

1-5: Release notes entry is well-formatted and consistent.

The new Version 10.1.0 entry follows the established format, includes proper availability information, and correctly documents the dependency upgrade. The entry is properly positioned (newest version first) with consistent spacing.

.nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt (1)

1-5: Release notes format and structure look good.

The new 10.1.0 entry follows the established convention and accurately documents the dependency upgrades. Ensure that the DateSpan and FNV hash enhancements mentioned in the PR don't include user-facing API changes for this specific package that should be documented here.

Please confirm that the DateSpan refactoring and FNV hash enhancements from this PR don't affect the public API surface of Cuemon.Extensions.Runtime.Caching, or if they do, consider adding a brief note to the release notes (e.g., under a separate category like # IMPROVED or # CHANGED).

.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt (1)

1-6: Release notes format and placement are correct; verify completeness of documented changes.

The new Version 10.1.0 entry follows the established format, is properly placed in reverse-chronological order, and documents dependency upgrades. However, the PR objectives mention significant changes to DateSpan and FNV hashing elsewhere in the codebase. Please verify whether any of these changes directly impact this package's public API or functionality, and if so, ensure they are documented in the release notes beyond the generic dependency upgrade note.

.nuget/Cuemon.IO/PackageReleaseNotes.txt (1)

1-5: No action needed. The release notes adequately document the changes in Cuemon.IO for version 10.1.0—specifically, dependency upgrades to the latest compatible versions. The notes clearly identify the scope (ALM section) and the action taken. Without evidence of code-level modifications to Cuemon.IO itself, the current entry is sufficient.

.nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt (1)

1-5: The release notes for this package are accurate.

The mentioned features (FNV hash enhancements, DateSpan refactoring, post-configuration support) are part of the Cuemon.Core 10.1.0 release, not Cuemon.AspNetCore.Razor.TagHelpers. This package is a tag helper utility library with no source code changes in 10.1.0—only dependency upgrades, which are correctly documented. Adding unrelated features to the release notes would mislead users about what actually changed in this package.

Likely an incorrect or invalid review comment.

.nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt (1)

1-6: Approved: Consistent 10.1.0 release notes addition.

Properly formatted release notes block for Version 10.1.0 with correct availability statement and ALM note indicating dependency upgrades.

.nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt (1)

1-6: Approved: Consistent 10.1.0 release notes addition.

Properly formatted release notes with correct availability statement (including .NET Standard 2.1 support appropriate for IO extensions) and coordinated dependency upgrade note.

.nuget/Cuemon.Net/PackageReleaseNotes.txt (1)

1-6: Approved: Consistent 10.1.0 release notes addition.

Properly formatted release notes block with appropriate availability statement and coordinated dependency upgrade note.

.nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt (1)

1-6: Approved: Consistent 10.1.0 release notes addition.

Properly formatted release notes with correct availability and coordinated dependency upgrade note. Existing 9.0.1 breaking change entry correctly preserved.

.nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt (1)

1-6: Approved: Consistent 10.1.0 release notes addition.

Properly formatted release notes with correct availability statement and coordinated dependency upgrade note.

.nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt (1)

1-6: Approved: Consistent 10.1.0 release notes addition.

Properly formatted release notes with appropriate availability statement (limited to .NET versions, suitable for AspNetCore packages) and coordinated dependency upgrade note.

.nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt (1)

1-6: Approved: Consistent 10.1.0 release notes addition.

Properly formatted release notes with correct availability statement and coordinated dependency upgrade note.

.nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt (1)

1-6: Approved: Consistent 10.1.0 release notes addition.

Properly formatted release notes with correct availability and coordinated dependency upgrade note. Existing 9.0.0 breaking change entry correctly preserved.

.nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt (1)

1-6: 10.1.0 entry matches established release-notes pattern.

Availability TFMs and the ALM note about dependency upgrades are consistent with prior entries and the PR’s dependency bumping scope.

.nuget/Cuemon.Xml/PackageReleaseNotes.txt (1)

1-6: Consistent 10.1.0 release header for Cuemon.Xml.

New entry cleanly advertises TFMs and dependency refresh in line with other packages; no additional notes needed here.

.nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt (1)

1-6: 10.1.0 notes for Cuemon.Data.SqlClient are clear and minimal.

The new version header and ALM bullet accurately scope this as a dependency-alignment release without implying behavioral changes.

.nuget/Cuemon.Data/PackageReleaseNotes.txt (1)

1-6: Service update wording for 10.1.0 is aligned with the rest of the suite.

Availability and “dependencies upgraded” ALM entry match the cross-package narrative for this minor release.

.nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt (1)

1-6: RazorPages 10.1.0 entry is TFM-consistent.

Limiting Availability to .NET 10/9 and stating dependency upgrades matches prior entries for this package and the overall 10.1.0 story.

.nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt (1)

1-6: Diagnostics 10.1.0 release block is coherent with CHANGELOG messaging.

States TFMs and dependency refresh without overspecifying behavior, which fits the per-assembly release-notes convention.

CHANGELOG.md (1)

9-33: 10.1.0 changelog entry is detailed and matches the code-level intent.

The new section clearly calls out IPostConfigurableParameterObject, Validator post-configuration behavior, and the targeted performance changes (FowlerNollVoHash, DateSpan, RandomString, DelimitedString, AesCryptor, CRC, Patterns, SHA-512), giving consumers a precise view of impact for a minor version.

Directory.Packages.props (1)

7-8: Centralized test/benchmark dependency bumps look coherent.

BenchmarkDotNet (core + Diagnostics.Windows) are kept in sync at 0.15.8, and xUnit core/console runner are aligned at 3.2.1, which should avoid version skew across tests and new benchmarks. Just ensure all benchmark and test projects consume these centrally managed versions without local overrides.

Also applies to: 19-20

@gimlichael gimlichael changed the title V10.0.1/ai assisted performance boost V10.1.0/api improvements and features Dec 6, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f2f009 and 83fde7e.

📒 Files selected for processing (3)
  • .github/prompts/benchmark.prompt.md (1 hunks)
  • .nuget/Cuemon.Core/PackageReleaseNotes.txt (1 hunks)
  • test/Cuemon.Core.Tests/Security/HashResultTest.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • .nuget/Cuemon.Core/PackageReleaseNotes.txt
  • test/Cuemon.Core.Tests/Security/HashResultTest.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: Analyze (csharp)

@github-advanced-security
Copy link

This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (7)
Directory.Build.props (1)

80-82: Use selective warning suppression instead of blanket-disabling for test projects

Setting <WarningLevel>0</WarningLevel> globally suppresses all compiler warnings in CI/CLI builds. Instead, suppress specific noisy rules using <NoWarn> or <WarningsNotAsErrors> for test-specific diagnostics. This preserves visibility of real issues—such as deprecated APIs or breaking changes—while avoiding noise from test-specific patterns. Document which warnings are suppressed and why so technical debt remains visible.

reports/tuning/Cuemon.DelimitedStringBenchmark-report-github.md (1)

1-16: Tweak fenced block and spacing to satisfy markdownlint (MD040/MD058).

To quiet markdownlint without affecting rendering, you can annotate the code fence with a language and insert a blank line before the table:

-```
+```text
@@
-PowerPlanMode=00000000-0000-0000-0000-000000000000  IterationTime=250ms  MaxIterationCount=20  
-MinIterationCount=15  WarmupCount=1  
-
-```
-| Method | Job       | Runtime   | Count | Mean        | Error       | StdDev      | Median      | Min         | Max         | Ratio | RatioSD | Gen0   | Gen1   | Allocated | Alloc Ratio |
+PowerPlanMode=00000000-0000-0000-0000-000000000000  IterationTime=250ms  MaxIterationCount=20  
+MinIterationCount=15  WarmupCount=1  
+
+```text
+
+| Method | Job       | Runtime   | Count | Mean        | Error       | StdDev      | Median      | Min         | Max         | Ratio | RatioSD | Gen0   | Gen1   | Allocated | Alloc Ratio |

If these files are regenerated by tooling, alternatively consider excluding reports/tuning/** from markdownlint.

reports/tuning/Cuemon.Security.FowlerNollVoHashBenchmark-report-github.md (1)

1-16: Align fenced block and table spacing with markdownlint rules.

Same as the other reports, you can either fix the markdown or relax linting for generated artifacts:

-```
+```text
@@
-MinIterationCount=15  WarmupCount=1  
-
-```
-| Method                    | Job       | Runtime   | Algorithm | Mean              | Error             | StdDev            | Median            | Min               | Max               | Ratio | RatioSD | Gen0   | Allocated | Alloc Ratio |
+MinIterationCount=15  WarmupCount=1  
+
+```text
+
+| Method                    | Job       | Runtime   | Algorithm | Mean              | Error             | StdDev            | Median            | Min               | Max               | Ratio | RatioSD | Gen0   | Allocated | Alloc Ratio |

If this file is regenerated by BenchmarkDotNet, excluding reports/tuning/** from markdownlint may be simpler.

reports/tuning/Cuemon.Security.CyclicRedundancyCheckBenchmark-report-github.md (1)

1-16: Consider small markdown fixes or lint exclusions for generated CRC report.

Markdownlint’s MD040/MD058 warnings can be addressed with minimal edits:

-```
+```text
@@
-MinIterationCount=15  WarmupCount=1  
-
-```
-| Method                           | Job       | Runtime   | Size    | Mean           | Error         | StdDev        | Median         | Min            | Max            | Ratio | RatioSD | Gen0     | Gen1     | Gen2     | Allocated | Alloc Ratio |
+MinIterationCount=15  WarmupCount=1  
+
+```text
+
+| Method                           | Job       | Runtime   | Size    | Mean           | Error         | StdDev        | Median         | Min            | Max            | Ratio | RatioSD | Gen0     | Gen1     | Gen2     | Allocated | Alloc Ratio |

Otherwise, consider configuring markdownlint to ignore these generated reports.

reports/tuning/Cuemon.GenerateBenchmark-report-github.md (1)

1-16: Keep generated GenerateBenchmark report markdownlint‑clean with minor tweaks.

To align with MD040/MD058 while preserving layout:

-```
+```text
@@
-MinIterationCount=15  WarmupCount=1  
-
-```
-| Method                           | Job       | Runtime   | Count | Mean           | Error         | StdDev        | Median         | Min           | Max            | Ratio | RatioSD | Gen0   | Allocated | Alloc Ratio |
+MinIterationCount=15  WarmupCount=1  
+
+```text
+
+| Method                           | Job       | Runtime   | Count | Mean           | Error         | StdDev        | Median         | Min           | Max            | Ratio | RatioSD | Gen0   | Allocated | Alloc Ratio |

If these reports are frequently regenerated, excluding reports/tuning/** from markdownlint might be more maintainable.

reports/tuning/Cuemon.Security.Cryptography.Sha512256Benchmark-report-github.md (1)

1-36: Align fenced block and table spacing with markdownlint rules

The content looks fine, but markdownlint’s MD040/MD058 findings are valid here:

  • Line 1: Fence has no language (```). Consider specifying one (e.g., text) so linters and renderers can treat it correctly.
  • Lines 13–14: The table header immediately follows the closing fence. Add a blank line between the closing ``` and the | Method ... line so the table isn’t considered part of the fence and MD058 is satisfied.

Example patch:

-```
+```text
 ...
-```
+```
+
 | Method                                                             | Job       | Runtime   | Variant          | Mean           | Error        | StdDev       | Median         | Min            | Max            | Ratio    | RatioSD  | Gen0   | Allocated | Alloc Ratio |
tuning/Cuemon.Security.Cryptography.Benchmarks/Sha512256Benchmark.cs (1)

14-105: Avoid re-running explicit benchmarks for Variant values they don’t use

Right now AlgorithmVariant Variant is marked with [Params], but only ParamBased_ComputeHash actually branches on Variant. BenchmarkDotNet will still run all benchmark methods (CustomSHA512256_* and BuiltInSHA512_Truncated_*) for each Variant value, even though those methods hard‑code the algorithm via _factories[...].

That means:

  • The “Custom”/“Built-in” benchmarks are effectively duplicated for each Variant, inflating run time.
  • Result tables can be misleading, since the Variant column changes while the underlying implementation doesn’t.

Consider one of these options:

  • Move Variant + ParamBased_ComputeHash into a separate benchmark class that’s grouped by params, and keep this class for the explicit small/large methods without [Params]; or
  • Remove [Params] from Variant here and drive the param-based comparisons through a dedicated param-only benchmark type.

This keeps the explicit benchmarks single-sourced per algorithm and avoids confusing Variant groupings in the reports.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 83fde7e and 27a9d0e.

📒 Files selected for processing (21)
  • Cuemon.sln (4 hunks)
  • Directory.Build.props (5 hunks)
  • Directory.Packages.props (1 hunks)
  • reports/tuning/Cuemon.DateSpanBenchmark-report-github.md (1 hunks)
  • reports/tuning/Cuemon.DelimitedStringBenchmark-report-github.md (1 hunks)
  • reports/tuning/Cuemon.GenerateBenchmark-report-github.md (1 hunks)
  • reports/tuning/Cuemon.Security.Cryptography.AesCryptorBenchmarks-report-github.md (1 hunks)
  • reports/tuning/Cuemon.Security.Cryptography.Sha512256Benchmark-report-github.md (1 hunks)
  • reports/tuning/Cuemon.Security.CyclicRedundancyCheckBenchmark-report-github.md (1 hunks)
  • reports/tuning/Cuemon.Security.FowlerNollVoHashBenchmark-report-github.md (1 hunks)
  • reports/tuning/Cuemon.Security.HashResultBenchmark-report-github.md (1 hunks)
  • tuning/Cuemon.Core.Benchmarks/Cuemon.Core.Benchmarks.csproj (1 hunks)
  • tuning/Cuemon.Core.Benchmarks/DateSpanBenchmark.cs (1 hunks)
  • tuning/Cuemon.Core.Benchmarks/DelimitedStringBenchmark.cs (1 hunks)
  • tuning/Cuemon.Core.Benchmarks/GenerateBenchmark.cs (1 hunks)
  • tuning/Cuemon.Core.Benchmarks/Security/CyclicRedundancyCheckBenchmark.cs (1 hunks)
  • tuning/Cuemon.Core.Benchmarks/Security/FowlerNollVoHashBenchmark.cs (1 hunks)
  • tuning/Cuemon.Core.Benchmarks/Security/HashResultBenchmark.cs (1 hunks)
  • tuning/Cuemon.Security.Cryptography.Benchmarks/AesCryptorBenchmarks.cs (1 hunks)
  • tuning/Cuemon.Security.Cryptography.Benchmarks/Cuemon.Security.Cryptography.Benchmarks.csproj (1 hunks)
  • tuning/Cuemon.Security.Cryptography.Benchmarks/Sha512256Benchmark.cs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
tuning/Cuemon.Core.Benchmarks/DateSpanBenchmark.cs (1)
src/Cuemon.Core/DateSpan.cs (1)
  • GetWeeks (200-214)
tuning/Cuemon.Core.Benchmarks/DelimitedStringBenchmark.cs (1)
src/Cuemon.Core/DelimitedString.cs (2)
  • DelimitedString (12-118)
  • Split (60-82)
tuning/Cuemon.Security.Cryptography.Benchmarks/AesCryptorBenchmarks.cs (1)
src/Cuemon.Security.Cryptography/AesCryptor.cs (2)
  • Encrypt (68-71)
  • Decrypt (79-82)
tuning/Cuemon.Core.Benchmarks/GenerateBenchmark.cs (1)
src/Cuemon.Core/Generate.cs (3)
  • Generate (18-219)
  • FixedString (132-135)
  • ObjectPortrayal (46-70)
tuning/Cuemon.Core.Benchmarks/Security/FowlerNollVoHashBenchmark.cs (1)
tuning/Cuemon.Core.Benchmarks/Security/HashResultBenchmark.cs (2)
  • MemoryDiagnoser (7-61)
  • GlobalSetup (17-24)
🪛 LanguageTool
reports/tuning/Cuemon.Security.HashResultBenchmark-report-github.md

[grammar] ~15-~15:
Context: ... | |------------------------------------ |---------- |---------- |----- |--------...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~15-~15:
Context: ...---------------------------- |---------- |---------- |----- |---------------:|---...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~15-~15:
Context: ...---------------- |---------- |---------- |----- |---------------:|--------------:...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~15-~15:
Context: ...--------- |---------- |---------- |----- |---------------:|--------------:|------...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~15-~15:
Context: ...------ |---------- |----- |---------------:|--------------:|--------------:|------...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~15-~15:
Context: ...-- |----- |---------------:|--------------:|--------------:|---------------:|-----...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~15-~15:
Context: ...----------:|--------------:|--------------:|---------------:|---------------:|----...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~15-~15:
Context: ...---------:|--------------:|---------------:|---------------:|---------------:|----...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~15-~15:
Context: ...--------:|---------------:|---------------:|---------------:|------:|--------:|---...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~15-~15:
Context: ...--------:|---------------:|---------------:|------:|--------:|-------:|-------:|--...

(QB_NEW_NL_OTHER_ERROR_IDS_UNNECESSARY_CONTRACTION)


[grammar] ~16-~16: Zin met fouten
Context: ...-:| | 'HashResult.GetBytes - copy bytes' | .NET 10.0 | .NET 10.0 | **...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~17-~17: Interpunctie toevoegen
Context: ...| - | NA | | 'HashResult.GetBytes - copy bytes' | .NET 9.0 ...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~17-~17: Zin met fouten
Context: ...A** | | 'HashResult.GetBytes - copy bytes' | .NET 9.0 | .NET 9.0 | 0 | ...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~31-~31: Interpunctie toevoegen
Context: ... | | | | 'HashResult.To<string> (converter)' | .NET...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~34-~34: Interpunctie toevoegen
Context: ... | | | | 'HashResult.GetBytes - copy bytes' | **.NET 1...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~34-~34: Zin met fouten
Context: ... | | 'HashResult.GetBytes - copy bytes' | .NET 10.0 | .NET 10.0 | **...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~35-~35: Zin met fouten
Context: ...0** | | 'HashResult.GetBytes - copy bytes' | .NET 9.0 | .NET 9.0 | 8 | ...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~49-~49: Interpunctie toevoegen
Context: ... | | | | 'HashResult.To<string> (converter)' | .NET...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~52-~52: Interpunctie toevoegen
Context: ... | | | | 'HashResult.GetBytes - copy bytes' | **.NET 1...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~52-~52: Zin met fouten
Context: ... | | 'HashResult.GetBytes - copy bytes' | .NET 10.0 | .NET 10.0 | **...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~53-~53: Zin met fouten
Context: ...0** | | 'HashResult.GetBytes - copy bytes' | .NET 9.0 | .NET 9.0 | 32 | ...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~67-~67: Interpunctie toevoegen
Context: ... | | | | 'HashResult.To<string> (converter)' | .NET...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~70-~70: Interpunctie toevoegen
Context: ... | | | | 'HashResult.GetBytes - copy bytes' | **.NET 1...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~70-~70: Zin met fouten
Context: ... | | 'HashResult.GetBytes - copy bytes' | .NET 10.0 | .NET 10.0 | **...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~71-~71: Zin met fouten
Context: ...0** | | 'HashResult.GetBytes - copy bytes' | .NET 9.0 | .NET 9.0 | 256 | 3...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~82-~82: Interpunctie toevoegen
Context: ... | | | | | HashResult.ToBinaryString | .NET 10.0 | ....

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~85-~85: Interpunctie toevoegen
Context: ... | | | | 'HashResult.To<string> (converter)' | .NET...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~88-~88: Interpunctie toevoegen
Context: ... | | | | 'HashResult.GetBytes - copy bytes' | **.NET 1...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~88-~88: Zin met fouten
Context: ... | | 'HashResult.GetBytes - copy bytes' | .NET 10.0 | .NET 10.0 | **...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~89-~89: Zin met fouten
Context: ...0** | | 'HashResult.GetBytes - copy bytes' | .NET 9.0 | .NET 9.0 | 1024 | 15...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~103-~103: Interpunctie toevoegen
Context: ... | | | | 'HashResult.To<string> (converter)' | .NET...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)

🪛 markdownlint-cli2 (0.18.1)
reports/tuning/Cuemon.Security.HashResultBenchmark-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

reports/tuning/Cuemon.Security.CyclicRedundancyCheckBenchmark-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

reports/tuning/Cuemon.Security.Cryptography.Sha512256Benchmark-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

reports/tuning/Cuemon.DateSpanBenchmark-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

reports/tuning/Cuemon.DelimitedStringBenchmark-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

reports/tuning/Cuemon.GenerateBenchmark-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

reports/tuning/Cuemon.Security.Cryptography.AesCryptorBenchmarks-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

reports/tuning/Cuemon.Security.FowlerNollVoHashBenchmark-report-github.md

1-1: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: call-build (Release) / 🛠️ Build
  • GitHub Check: call-build (Debug) / 🛠️ Build
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (13)
tuning/Cuemon.Core.Benchmarks/Cuemon.Core.Benchmarks.csproj (1)

1-9: Benchmark project wiring looks correct

Minimal SDK project with only a RootNamespace and a reference to Cuemon.Core is appropriate here; TFMs and BenchmarkDotNet dependencies are correctly delegated to shared build props via IsBenchmarkProject.

Cuemon.sln (2)

3-4: Visual Studio version bump is benign but verify team tooling

Updating the solution header to # Visual Studio Version 18 / VisualStudioVersion = 18.0... is fine, but it may cause older VS installations to prompt for an upgrade path. Confirm this is intentional for your team’s supported tooling.


173-178: New tuning benchmark projects are consistently wired into the solution

The tuning solution folder, the two benchmark projects, their configuration mappings, and NestedProjects entries are all consistent (paths, GUIDs, and parent folder). This should integrate the new benchmark projects cleanly into the solution.

Also applies to: 501-508, 593-594

tuning/Cuemon.Core.Benchmarks/Security/HashResultBenchmark.cs (1)

1-61: HashResult benchmark covers the right surface and setup is correct

GlobalSetup, parameterization, and the set of benchmarked APIs (GetBytes, To* variants, converter-based To) are coherent and side‑effect free; this is a solid benchmark fixture.

Directory.Build.props (2)

112-119: Benchmark project configuration via IsBenchmarkProject is cleanly separated

Conditioning benchmark TFMs (net10.0;net9.0) and BenchmarkDotNet PackageReferences on IsBenchmarkProject keeps benchmark concerns isolated from main source/test projects and works well with the new *.Benchmarks projects.


4-6: Fix IsSourceProject/IsToolingProject property definitions and correct directory reference

The IsSourceProject and IsToolingProject conditions use unnecessary nested .ToLower() calls and can be simplified. More critically, IsToolingProject references a non-existent "tooling" directory; the actual directory is named "tuning" and is reserved for benchmarks (already handled by IsBenchmarkProject). Either rename the directory to "tooling" if intended for tool projects, or remove the IsToolingProject definition if no tooling projects are planned.

For simplification without behavioral change:

-    <IsSourceProject>$(MSBuildProjectDirectory.ToLower().StartsWith('$(MSBuildThisFileDirectory.ToLower())src'))</IsSourceProject>
-    <IsToolingProject>$(MSBuildProjectDirectory.ToLower().StartsWith('$(MSBuildThisFileDirectory.ToLower())tooling'))</IsToolingProject>
+    <IsSourceProject>$(MSBuildProjectDirectory.StartsWith('$(MSBuildThisFileDirectory)src'))</IsSourceProject>
+    <IsToolingProject>$(MSBuildProjectDirectory.StartsWith('$(MSBuildThisFileDirectory)tooling'))</IsToolingProject>

If a tooling/ directory is not planned, remove the IsToolingProject definition and its associated PropertyGroup at line 84–88 to avoid dead code.

tuning/Cuemon.Security.Cryptography.Benchmarks/Cuemon.Security.Cryptography.Benchmarks.csproj (1)

1-9: Crypto benchmarks project is correctly minimal

Root namespace and a single reference to Cuemon.Security.Cryptography are all that’s needed; TFMs and BenchmarkDotNet dependencies are rightly centralized via shared props for *.Benchmarks projects.

tuning/Cuemon.Core.Benchmarks/DelimitedStringBenchmark.cs (1)

12-53: DelimitedString benchmarks look correct and representative.

Setup correctly exercises both quoted and unquoted CSV‑like fields, and the Create/Split benchmarks use DelimitedString.Create/Split with appropriate Delimiter/Qualifier configuration. The null‑forgiving initialization plus [GlobalSetup] pattern is standard for BenchmarkDotNet; no functional issues stand out here.

tuning/Cuemon.Security.Cryptography.Benchmarks/AesCryptorBenchmarks.cs (1)

11-38: AesCryptor benchmarks are well‑structured and isolate crypto costs.

The GlobalSetup correctly derives a key/IV, seeds deterministic plaintext, and precomputes ciphertext so Encrypt and Decrypt each benchmark a single operation. Resource handling (using var aes) is safe, and the BenchmarkDotNet pattern is idiomatic. No changes needed.

tuning/Cuemon.Core.Benchmarks/DateSpanBenchmark.cs (1)

26-92: DateSpanBenchmark provides solid coverage of the updated DateSpan API.

The setup fixes a single _now point, derives varied span lengths, and uses ISO‑sortable strings with CultureInfo.InvariantCulture, which aligns with the DateSpan.Parse overloads. The benchmarks cleanly cover construction, parsing, formatting, GetWeeks, hashing, and equality/operator behavior without hidden side effects.

tuning/Cuemon.Core.Benchmarks/Security/CyclicRedundancyCheckBenchmark.cs (1)

8-52: CRC benchmarks look clean and deterministic

The setup and benchmark methods are well-structured:

  • Fixed RNG seed in Setup ensures deterministic payloads across runs.
  • Warm-up calls on _crc32/_crc64 keep lazy initialization out of the measured path.
  • Stream benchmarks correctly wrap the shared payload in a non-writable MemoryStream per invocation, avoiding accidental mutation.

No changes requested here.

tuning/Cuemon.Core.Benchmarks/Security/FowlerNollVoHashBenchmark.cs (1)

7-90: FNV benchmarks are wired correctly to the Algorithm parameter

The benchmark wiring looks solid:

  • Algorithm is exposed via [Params] and consumed in GlobalSetup when constructing each FowlerNollVoXX instance, so both Fnv1 and Fnv1a are covered.
  • Payload construction is done once in GlobalSetup, and all benchmark methods are thin wrappers over ComputeHash on the appropriate hasher, which is ideal for BenchmarkDotNet.

No issues from my side.

tuning/Cuemon.Core.Benchmarks/GenerateBenchmark.cs (1)

8-103: Generate benchmarks are representative and side‑effect safe

This benchmark class nicely exercises the Generate APIs:

  • Count covers small/mid/large cases.
  • RangeOf_Enumerate uses a private _sink to keep enumeration work from being optimized away.
  • Other benchmarks call straight into Generate helpers with fixed inputs, making results easy to compare across runs.

I don’t see any functional or structural issues here.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 6, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
7.1% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@gimlichael gimlichael merged commit 2b046e9 into main Dec 6, 2025
304 of 305 checks passed
@gimlichael gimlichael deleted the v10.0.1/ai-assisted-performance-boost branch December 6, 2025 22:17
@gimlichael gimlichael restored the v10.0.1/ai-assisted-performance-boost branch December 7, 2025 00:22
@gimlichael gimlichael deleted the v10.0.1/ai-assisted-performance-boost branch December 7, 2025 10:36
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