From 97dd5b4444147fb8f58563aa2f93754bfb6aac18 Mon Sep 17 00:00:00 2001 From: konard Date: Thu, 11 Sep 2025 14:38:56 +0300 Subject: [PATCH 1/3] Initial commit with task details for issue #359 Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/linksplatform/Data.Doublets/issues/359 --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..3546a9923 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +Issue to solve: https://github.com/linksplatform/Data.Doublets/issues/359 +Your prepared branch: issue-359-e5a050cc +Your prepared working directory: /tmp/gh-issue-solver-1757590603493 + +Proceed. \ No newline at end of file From 00a7118584e7955613f6fd1b6e77223039f3fdd7 Mon Sep 17 00:00:00 2001 From: konard Date: Thu, 11 Sep 2025 14:39:13 +0300 Subject: [PATCH 2/3] Remove CLAUDE.md - PR created successfully --- CLAUDE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 3546a9923..000000000 --- a/CLAUDE.md +++ /dev/null @@ -1,5 +0,0 @@ -Issue to solve: https://github.com/linksplatform/Data.Doublets/issues/359 -Your prepared branch: issue-359-e5a050cc -Your prepared working directory: /tmp/gh-issue-solver-1757590603493 - -Proceed. \ No newline at end of file From fa8ed496b3cba77ef60169b566f65b19d6b930af Mon Sep 17 00:00:00 2001 From: konard Date: Thu, 11 Sep 2025 14:47:15 +0300 Subject: [PATCH 3/3] Fix Count logic bug in C# and C++ implementations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves issue #359 where Count method had incorrect logic when either source or target was 'any'. The previous implementation used a single variable that got overwritten, causing incorrect results. Changes: - C#: Fixed SplitMemoryLinksBase.cs Count method (lines 393-406) - C++: Fixed SplitMemoryLinksBase.h Count and Each methods (3 locations) - Added example test demonstrating the fix The bug occurred when checking links with partial restrictions: - Before: Used single 'value' variable that got overwritten - After: Handle source==any and target==any cases separately 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../Split/Generic/SplitMemoryLinksBase.h | 45 +++++----- .../Split/Generic/SplitMemoryLinksBase.cs | 15 ++-- examples/count_logic_test.cs | 88 +++++++++++++++++++ 3 files changed, 120 insertions(+), 28 deletions(-) create mode 100644 examples/count_logic_test.cs diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.h index c180989c5..dda941aeb 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.h @@ -315,18 +315,19 @@ namespace Platform::Data::Doublets::Memory::Split::Generic } return LinkAddressType{0}; } - auto value = LinkAddressType{}; if ((source == any)) { - value = target; + if ((storedLinkValue.Target == target)) + { + return LinkAddressType{1}; + } } if ((target == any)) { - value = source; - } - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) - { - return LinkAddressType{1}; + if ((storedLinkValue.Source == source)) + { + return LinkAddressType{1}; + } } return LinkAddressType{0}; } @@ -528,18 +529,19 @@ namespace Platform::Data::Doublets::Memory::Split::Generic } return LinkAddressType{0}; } - auto value = LinkAddressType{0}; if ((source == any)) { - value = target; + if ((storedLinkValue.Target == target)) + { + return LinkAddressType{1}; + } } if ((target == any)) { - value = source; - } - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) - { - return LinkAddressType{1}; + if ((storedLinkValue.Source == source)) + { + return LinkAddressType{1}; + } } return LinkAddressType{0}; } @@ -724,18 +726,19 @@ namespace Platform::Data::Doublets::Memory::Split::Generic } return $continue; } - auto value = LinkAddressType{0}; if (source == any) { - value = target; + if ((storedLinkValue.Target == target)) + { + return handler(GetLinkStruct(index)); + } } if (target == any) { - value = source; - } - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) - { - return handler(GetLinkStruct(index)); + if ((storedLinkValue.Source == source)) + { + return handler(GetLinkStruct(index)); + } } return $continue; } diff --git a/csharp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.cs b/csharp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.cs index 9ab5ade78..e5603c8ad 100644 --- a/csharp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.cs +++ b/csharp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.cs @@ -390,18 +390,19 @@ public virtual TLinkAddress Count(IList? restriction) } return GetZero(); } - var value = default(TLinkAddress); if ((source == any)) { - value = target; + if ((storedLinkValue.Target == target)) + { + return GetOne(); + } } if ((target == any)) { - value = source; - } - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) - { - return GetOne(); + if ((storedLinkValue.Source == source)) + { + return GetOne(); + } } return GetZero(); } diff --git a/examples/count_logic_test.cs b/examples/count_logic_test.cs new file mode 100644 index 000000000..dc0b6d0ff --- /dev/null +++ b/examples/count_logic_test.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; + +namespace Platform.Data.Doublets.Examples +{ + /// + /// Test case to verify the Count logic fix for issue #359 + /// This demonstrates the corrected behavior where source==any or target==any + /// should be handled separately rather than with variable overwriting + /// + public class CountLogicTest + { + public class MockStoredLinkValue + { + public ulong Source { get; set; } + public ulong Target { get; set; } + } + + private const ulong any = 0; // Assuming 0 represents "any" + + /// + /// Old (buggy) logic that had the issue + /// + public static bool OldBuggyLogic(MockStoredLinkValue storedLinkValue, ulong source, ulong target) + { + var value = default(ulong); + if (source == any) + { + value = target; + } + if (target == any) // This overwrites value even if source was any! + { + value = source; + } + return (storedLinkValue.Source == value) || (storedLinkValue.Target == value); + } + + /// + /// New (fixed) logic that handles each case separately + /// + public static bool NewFixedLogic(MockStoredLinkValue storedLinkValue, ulong source, ulong target) + { + if (source == any) + { + if (storedLinkValue.Target == target) + { + return true; + } + } + if (target == any) + { + if (storedLinkValue.Source == source) + { + return true; + } + } + return false; + } + + public static void RunTests() + { + var testLink = new MockStoredLinkValue { Source = 1, Target = 2 }; + + // Test case 1: source=any, target=2 (should match target) + Console.WriteLine("Test 1: source=any, target=2, stored=(1,2)"); + Console.WriteLine($"Old logic: {OldBuggyLogic(testLink, any, 2)}"); + Console.WriteLine($"New logic: {NewFixedLogic(testLink, any, 2)}"); + Console.WriteLine(); + + // Test case 2: source=1, target=any (should match source) + Console.WriteLine("Test 2: source=1, target=any, stored=(1,2)"); + Console.WriteLine($"Old logic: {OldBuggyLogic(testLink, 1, any)}"); + Console.WriteLine($"New logic: {NewFixedLogic(testLink, 1, any)}"); + Console.WriteLine(); + + // Test case 3: source=any, target=any (edge case, neither should match in this context) + Console.WriteLine("Test 3: source=any, target=any, stored=(1,2)"); + Console.WriteLine($"Old logic: {OldBuggyLogic(testLink, any, any)}"); + Console.WriteLine($"New logic: {NewFixedLogic(testLink, any, any)}"); + Console.WriteLine(); + + // Test case 4: source=1, target=3 (no match expected) + Console.WriteLine("Test 4: source=1, target=3, stored=(1,2)"); + Console.WriteLine($"Old logic: {OldBuggyLogic(testLink, 1, 3)}"); + Console.WriteLine($"New logic: {NewFixedLogic(testLink, 1, 3)}"); + } + } +} \ No newline at end of file