Skip to content

Feature/add sort #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 2, 2025
Merged

Feature/add sort #35

merged 4 commits into from
Apr 2, 2025

Conversation

kimkulling
Copy link
Owner

@kimkulling kimkulling commented Apr 2, 2025

  • Add QuickSort
  • Add isSorted
  • Add Bin<search

Summary by CodeRabbit

  • New Features
    • Introduced advanced sorting and searching utilities—including quicksort, binary search, and swap operations—for improved data processing.
    • Enhanced cross-platform stack memory allocation for more consistent performance.
  • Tests
    • Expanded test coverage to validate the new sorting functionalities.
  • Chores
    • Refreshed licensing details.

Copy link
Contributor

coderabbitai bot commented Apr 2, 2025

Walkthrough

This pull request introduces a new sorting module with its associated test file and integrates them into the project’s build system via CMake. In addition, the update enhances cross-platform support by incorporating a new macro for stack allocation and performs widespread copyright updates to reflect the current year. Minor formatting and declaration adjustments were also applied to some test files.

Changes

Files Change Summary
CMakeLists.txt, include/cppcore/Common/Sort.h, test/common/SortTest.cpp Added new source and test files for sorting functionality (including quicksort, binary search, and swap operations).
include/cppcore/CPPCoreCommon.h Added #include <malloc.h> and defined the CPPCORE_STACK_ALLOC macro for stack allocation (platform-specific handling).
code/cppcore.cpp, include/cppcore/Common/{TBitField.h, TOptional.h, TStringBase.h, Variant.h}, include/cppcore/Container/{TArray.h, THashMap.h, TList.h, TQueue.h, TStaticArray.h}, include/cppcore/Memory/{MemUtils.h, TDefaultAllocator.h, TPoolAllocator.h, TStackAllocator.h}, include/cppcore/Random/RandomGenerator.h, test/{CPPCoreCommonTest.cpp, common/{HashTest.cpp, TBitFieldTest.cpp, TOptionalTest.cpp, VariantTest.cpp}, container/{TArrayTest.cpp, TListTest.cpp, TQueueTest.cpp, TStaticArrayTest.cpp}, io/FileSystemTest.cpp, memory/{TStackAllocatorTest.cpp}, random/RandomGeneratorTest.cpp} Updated copyright notices from 2024 to 2025 across multiple files.
test/container/THashMapTest.cpp Simplified the test class declaration by removing extraneous comments and empty braces.
test/memory/{TPoolAllocatorTest.cpp, TScratchAllocatorTest.cpp} Reformatted code and updated variable declarations to use static constexpr for compile-time evaluation.

Sequence Diagram(s)

sequenceDiagram
    participant Test as SortTest
    participant Sort as Sort.h
    participant Alloc as CPPCORE_STACK_ALLOC

    Test->>Sort: Call quicksort(data, num, stride, comp)
    Sort->>Alloc: Allocate memory for pivot
    Sort->>Sort: Invoke quicksortImpl recursively
    Sort-->>Test: Return sorted data

    Test->>Sort: Call binSearch(key, sorted_array, num, comp)
    Sort-->>Test: Return index or error code
Loading

Possibly related PRs

  • Feature/add algo #33: Addresses modifications to the CMake files and integration of new testing functionalities for algorithm implementations.

Poem

I'm a rabbit, quick on my feet,
Hopping over code with a rhythm so sweet.
Sorting arrays and swapping with flair,
With new tests in place, there's magic in the air.
Carrots and bytes, a merry blend – code and nature, friends till the end!
🥕🐇

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@kimkulling kimkulling merged commit 2c7cd0b into master Apr 2, 2025
1 check passed
Copy link
Contributor

@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: 5

🔭 Outside diff range comments (4)
include/cppcore/Common/TStringBase.h (1)

189-190: ⚠️ Potential issue

Incomplete Implementation: TStringView::data()
The implementation of the data() method in TStringView is currently empty and does not return a value. To ensure correct functionality and avoid undefined behavior, it should return the member pointer mPtr.

Suggested change:

-inline TCharType *TStringView<TCharType>::data() const {
-}
+inline TCharType *TStringView<TCharType>::data() const {
+    return mPtr;
+}
include/cppcore/Common/TOptional.h (1)

107-117: ⚠️ Potential issue

Incorrect Member Access in operator==
Within the operator== implementation, the code compares mInited with rhs.isInited instead of comparing against the mInited member variable (or by invoking the accessor function with parentheses). This likely leads to an unintended function pointer comparison. It is recommended to update the comparison as shown below.

Suggested change:

-    if (mInited == rhs.isInited) {
+    if (mInited == rhs.mInited) {
include/cppcore/Container/TQueue.h (1)

138-146: ⚠️ Potential issue

Typo in Assignment Operator
Within the operator= implementation, the code uses rhs.m_QueueData (line 143) whereas the member is declared as mQueueData. This mismatch will likely cause compile errors. Please update rhs.m_QueueData to rhs.mQueueData.

include/cppcore/Memory/TPoolAllocator.h (1)

202-212: 🛠️ Refactor suggestion

Potential Memory Leak in reserve() Function.
Within the reserve() method, the code first creates a new pool via the Pool constructor—which already allocates memory for mPool—and then immediately assigns a new allocation to mCurrent->mPool, overwriting the original pointer. This redundancy may result in a memory leak.

Consider removing the redundant allocation lines. For example, update the function as follows:

-    mCurrent->mPool = new T[size];
-    mCurrent->mPoolsize = size;

since the Pool(size_t, Pool*) constructor already handles the allocation.

🧹 Nitpick comments (10)
include/cppcore/Common/TBitField.h (1)

100-103: Enhance Bit Shift Expression
In the getBit method, consider replacing 1 << pos with static_cast<T>(1) << pos to ensure correct type handling for different instantiations of T. This change would improve the robustness of the bitwise operations when T is not an int.

test/container/TListTest.cpp (1)

122-156: Test Coverage Enhancement Suggestion:
The tests in this file provide good coverage for the TList functionalities (construction, add, copy, and iteration). However, there is currently no test for the removeBack() method. Adding unit tests for removeBack() would improve coverage and help ensure that all path functionalities of TList are validated.

include/cppcore/Memory/TStackAllocator.h (2)

127-150: Allocator Memory Allocation Implementation
The alloc function correctly calculates the required memory (including header overhead) and updates internal state accordingly.

Suggestion: For improved type-safety and clarity, consider replacing the C-style cast on line 140 with reinterpret_cast. For example:

-    Header *header = (Header *)(&mData[mTop]);
+    Header *header = reinterpret_cast<Header*>(&mData[mTop]);

219-220: Namespace Comment Consistency
The closing comment for the namespace shows a typo. It currently reads:

} // Namespace cppcorecppcore

Consider correcting it to match the declared namespace:

- } // Namespace cppcorecppcore
+ } // Namespace cppcore
test/io/FileSystemTest.cpp (1)

35-39: Hard-Coded Filesystem Path Warning.
The test case uses the hard-coded path "c:\\" to obtain free disk space. This could cause issues on non-Windows platforms. Consider parameterizing the filesystem root or using a platform-independent directory for testing to ensure cross-platform compatibility.

include/cppcore/CPPCoreCommon.h (2)

32-32: Consider using <stdlib.h> instead of <malloc.h>.

While <malloc.h> provides the necessary declarations for alloca, it's considered obsolete in some systems. <stdlib.h> is more portable and standard-compliant.

-#include <malloc.h>
+#include <stdlib.h>

57-57: Add safety warnings for the stack allocation macro.

The CPPCORE_STACK_ALLOC macro is a good addition for cross-platform support, but stack allocations can be dangerous:

  1. Stack space is limited, and large allocations may cause stack overflow
  2. No size checks are performed before allocation
  3. Allocations don't check for failure

Consider adding a maximum size check or documentation warning.

Also applies to: 60-60

test/common/SortTest.cpp (1)

53-58: Verify sorting order in quicksortTest.

The test sorts the array using compDescending but then verifies it's sorted using the same compDescending function. This will always pass regardless of whether the sort works correctly. Consider using different comparison functions for sorting and verification.

-    quicksort(arr, 5, sizeof(int32_t), compDescending<int32_t>);
-    bool sorted = isSorted(arr, 5, sizeof(int32_t), compDescending<int32_t>);
+    quicksort(arr, 5, sizeof(int32_t), compAscending<int32_t>);
+    bool sorted = isSorted(arr, 5, sizeof(int32_t), compAscending<int32_t>);
include/cppcore/Common/Sort.h (2)

31-36: Improve readability of comparison function.

The comparison expression (_lhs > _rhs) - (_lhs < _rhs) is clever but not immediately obvious. Consider using a more explicit implementation for better readability.

template<class T>
inline int32_t compAscending(const void *lhs, const void *rhs)  {
    const T _lhs = *static_cast<const T *>(lhs);
    const T _rhs = *static_cast<const T *>(rhs);
-    return (_lhs > _rhs) - (_lhs < _rhs);
+    if (_lhs < _rhs) return -1;
+    if (_lhs > _rhs) return 1;
+    return 0;
}

65-95: Improve quicksort pivot selection to avoid worst-case performance.

The current implementation always uses the first element as the pivot, which can lead to O(n²) performance for already-sorted arrays. Consider implementing median-of-three or randomized pivot selection.

inline void quicksortImpl(void *pivot, void *_data, size_t num, size_t stride, ComparisonFn func) {
    if (num < 2) {
        return;
    }

    if (_data == nullptr) {
        return;
    }

    uint8_t *data = (uint8_t*) _data;
-    memcpy(pivot, &data[0], stride);
+    // Use median-of-three pivot selection to avoid worst-case behavior
+    size_t mid = num / 2;
+    size_t last = num - 1;
+    // Swap middle element with first if necessary
+    if (func(&data[0], &data[mid * stride]) > 0) {
+        swap(&data[0], &data[mid * stride], stride);
+    }
+    // Swap first with last if necessary
+    if (func(&data[0], &data[last * stride]) > 0) {
+        swap(&data[0], &data[last * stride], stride);
+    }
+    // Swap middle with last if necessary
+    if (func(&data[mid * stride], &data[last * stride]) > 0) {
+        swap(&data[mid * stride], &data[last * stride], stride);
+    }
+    // Use middle element as pivot
+    memcpy(pivot, &data[mid * stride], stride);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 095eec4 and 579710f.

📒 Files selected for processing (34)
  • CMakeLists.txt (2 hunks)
  • code/cppcore.cpp (1 hunks)
  • include/cppcore/CPPCoreCommon.h (2 hunks)
  • include/cppcore/Common/Sort.h (1 hunks)
  • include/cppcore/Common/TBitField.h (1 hunks)
  • include/cppcore/Common/TOptional.h (1 hunks)
  • include/cppcore/Common/TStringBase.h (1 hunks)
  • include/cppcore/Common/Variant.h (1 hunks)
  • include/cppcore/Container/TArray.h (1 hunks)
  • include/cppcore/Container/THashMap.h (1 hunks)
  • include/cppcore/Container/TList.h (1 hunks)
  • include/cppcore/Container/TQueue.h (1 hunks)
  • include/cppcore/Container/TStaticArray.h (1 hunks)
  • include/cppcore/Memory/MemUtils.h (1 hunks)
  • include/cppcore/Memory/TDefaultAllocator.h (1 hunks)
  • include/cppcore/Memory/TPoolAllocator.h (1 hunks)
  • include/cppcore/Memory/TStackAllocator.h (1 hunks)
  • include/cppcore/Random/RandomGenerator.h (1 hunks)
  • test/CPPCoreCommonTest.cpp (1 hunks)
  • test/common/HashTest.cpp (1 hunks)
  • test/common/SortTest.cpp (1 hunks)
  • test/common/TBitFieldTest.cpp (1 hunks)
  • test/common/TOptionalTest.cpp (1 hunks)
  • test/common/VariantTest.cpp (1 hunks)
  • test/container/TArrayTest.cpp (1 hunks)
  • test/container/THashMapTest.cpp (2 hunks)
  • test/container/TListTest.cpp (1 hunks)
  • test/container/TQueueTest.cpp (1 hunks)
  • test/container/TStaticArrayTest.cpp (1 hunks)
  • test/io/FileSystemTest.cpp (1 hunks)
  • test/memory/TPoolAllocatorTest.cpp (3 hunks)
  • test/memory/TScratchAllocatorTest.cpp (2 hunks)
  • test/memory/TStackAllocatorTest.cpp (1 hunks)
  • test/random/RandomGeneratorTest.cpp (1 hunks)
🔇 Additional comments (39)
include/cppcore/Common/TStringBase.h (1)

4-4: Textual Update: Copyright Year
The copyright notice has been updated to reflect the period 2014-2025. This is a purely legal/textual change and is consistent with similar updates across the codebase.

code/cppcore.cpp (1)

1-5: Textual Update: Copyright Year
The license header has been updated with the new period (2014-2025). This update is purely cosmetic and does not affect any functionality.

include/cppcore/Container/TStaticArray.h (1)

1-4: Textual Update: Copyright Year
According to the PR objectives, the header comment has been updated from "2014-2024" to "2014-2025". This change is purely textual and is applied consistently with other files.

include/cppcore/Common/TOptional.h (1)

4-4: Textual Update: Copyright Year
The header has been updated to reflect the new copyright period (2014-2025). No functional changes are involved.

test/common/TOptionalTest.cpp (1)

1-5: Textual Update: Copyright Year
The header comment has been updated to the current period (2014-2025). This change is purely textual and does not impact the functionality of the tests.

test/container/TQueueTest.cpp (1)

5-5: Updated Copyright Notice
The copyright year has been updated from 2024 to 2025, which is consistent with other files.

include/cppcore/Container/TQueue.h (1)

4-4: Updated Copyright Notice
The license header now reflects the updated copyright year (2025).

include/cppcore/Common/TBitField.h (1)

4-4: Updated Copyright Notice
The license header update to include the current year (2025) is correctly applied.

test/container/TArrayTest.cpp (2)

5-5: Updated Copyright Notice
The license header has been updated to reflect the new year (2025), ensuring consistency across the project.


59-75: Comprehensive Array Test Coverage
The test cases within this file thoroughly validate array construction, element access, modification, iteration, and removal. The use of descriptive messages and varied scenarios helps ensure that the TArray implementation is robust.

test/container/TStaticArrayTest.cpp (1)

5-5: Updated Copyright Notice
The license header now correctly reflects the current year (2025), which aligns with the recent updates across the codebase.

test/common/HashTest.cpp (1)

1-10: License Header Update:
The license comment has been updated to reflect the current year (2025). This change is consistent with other parts of the codebase and does not impact functionality.

include/cppcore/Container/TList.h (1)

1-7: License Header Consistency:
The copyright notice is now updated to “2014-2025”. This update improves consistency across the codebase with no side effects on container functionality.

test/CPPCoreCommonTest.cpp (1)

1-10: Updated Copyright Notice:
The MIT License header now reflects the year 2025, ensuring that all components of the project are up to date.

include/cppcore/Memory/TDefaultAllocator.h (1)

1-10: License Header Update:
The license header has been updated to “2014-2025”, maintaining uniformity with the rest of the project. No functional changes have been introduced.

test/container/TListTest.cpp (1)

1-8: License Header Update in Tests:
The copyright notice in the license header is now updated to “2014-2025”. This minor change enhances consistency across testing files.

include/cppcore/Random/RandomGenerator.h (1)

1-6: License Header Update
The copyright header has been updated correctly from "2014-2024" to "2014-2025". There are no functional changes in this file, and the update helps maintain legal accuracy and consistency with the current year.

include/cppcore/Container/THashMap.h (1)

1-7: Consistent Copyright Update
The license header now reflects "2014-2025" instead of the previous year. This textual update is consistent with other project files and does not impact any functionality.

test/memory/TStackAllocatorTest.cpp (3)

1-7: License and Header Validation
The license header is updated correctly along with the inclusion of necessary headers and namespace usage. This ensures consistency with the rest of the project.


29-39: Allocation and Exception Safety Tests
The CreateTest ensures that the allocator can be constructed without exceptions. The test structure is clear and well-organized.


41-60: Comprehensive Allocation and Release Testing
The tests cover key scenarios for the stack allocator:

  • Valid allocation and memory usage reduction.
  • Correct restoration of free memory upon release.
  • Handling of bad allocations and releases.
    This provides a good level of coverage for basic functionality.
test/common/TBitFieldTest.cpp (2)

1-8: License and Setup Check
The header license has been updated appropriately, and the required headers and namespace declarations are intact.


29-77: TBitField Functionality Testing
The test cases for creating a bitfield, manipulating bits (set, clear), and verifying the maximum number of bits for various types are well-structured and comprehensive.

include/cppcore/Memory/TStackAllocator.h (2)

1-7: License Header Update
The header license has been updated to reflect "2014-2025", ensuring legal and historical consistency across files.


153-170: Release Function Verification
The release method properly locates and subtracts the allocated block (including its header) from the top pointer. It correctly decrements the allocation counter.

Ensure that in scenarios with misordered releases (which are not supported), the caller is aware that the behavior is undefined.

include/cppcore/Common/Variant.h (1)

4-4: Update Copyright Notice in Variant.h.
The copyright notice has been updated to reflect the current year (2025). This is a purely textual change that maintains consistency without affecting functionality.

test/common/VariantTest.cpp (1)

4-4: Update Copyright Notice in VariantTest.cpp.
The copyright header is updated consistently to 2025. No functional changes are introduced.

include/cppcore/Memory/MemUtils.h (1)

4-4: Update Copyright Notice in MemUtils.h.
The copyright notice has been updated from "2014-2024" to "2014-2025", which aligns with the other project files. There are no changes to functionality.

test/random/RandomGeneratorTest.cpp (1)

4-4: LGTM: Copyright year updated.

The copyright year has been updated to reflect 2025.

include/cppcore/Container/TArray.h (1)

4-4: LGTM: Copyright year updated.

The copyright year has been updated to reflect 2025.

CMakeLists.txt (2)

80-80: New Sort.h header file integration looks good.

The Sort.h header has been properly added to the common source files, enabling the new sorting functionality to be included in the build.


137-137: New SortTest.cpp integration looks good.

The SortTest.cpp file has been properly added to the common test files, ensuring the new sorting functionality will be tested through the unit test framework.

test/container/THashMapTest.cpp (2)

5-5: LGTM: Copyright year updated.

The copyright year has been updated to reflect 2025.


31-31: Code style improvement.

The class declaration has been simplified by removing the redundant // empty comment while preserving functionality.

test/memory/TPoolAllocatorTest.cpp (3)

4-4: LGTM: Copyright year updated.

The copyright year has been updated to reflect 2025.


37-37: LGTM: Code formatting update.

The constructor has been reformatted to a single line, improving readability.


52-52: Good modernization: Using constexpr instead of const.

Changing from static const to static constexpr is a good practice as it enables compile-time evaluation and potential optimizations.

test/memory/TScratchAllocatorTest.cpp (2)

4-4: Copyright year updated to reflect 2025.

The copyright year has been updated from the previous range to include 2025, which keeps the license information current.


31-31: Good enhancement with static constexpr.

The change from const size_t to static constexpr size_t improves the implementation by:

  1. Making the constant truly compile-time
  2. Ensuring only one instance exists across all class instances
  3. Following modern C++ best practices

Comment on lines +41 to +45
TEST_F(SortTest, isSortedTest ) {
int32_t arr[] = {1,2,3,4,5};
bool sorted = isSorted(arr, 5, sizeof(int32_t), compDescending<int32_t>);
EXPECT_TRUE(sorted);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Verify comparison function usage in isSortedTest.

The test is using compDescending but expecting a sorted array in ascending order to return true. This seems contradictory and may lead to unexpected behavior.

-    bool sorted = isSorted(arr, 5, sizeof(int32_t), compDescending<int32_t>);
+    bool sorted = isSorted(arr, 5, sizeof(int32_t), compAscending<int32_t>);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TEST_F(SortTest, isSortedTest ) {
int32_t arr[] = {1,2,3,4,5};
bool sorted = isSorted(arr, 5, sizeof(int32_t), compDescending<int32_t>);
EXPECT_TRUE(sorted);
}
TEST_F(SortTest, isSortedTest ) {
int32_t arr[] = {1,2,3,4,5};
bool sorted = isSorted(arr, 5, sizeof(int32_t), compAscending<int32_t>);
EXPECT_TRUE(sorted);
}

Comment on lines +47 to +51
TEST_F(SortTest, isNotSortedTest) {
int32_t arr[] = { 1, 2, 3, 5, 4 };
bool sorted = isSorted(arr, 5, sizeof(int32_t), compDescending<int32_t>);
EXPECT_FALSE(sorted);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Verify comparison function usage in isNotSortedTest.

Similar to the previous test, this is using compDescending on an array that appears to be in ascending order. Ensure this is the intended behavior.

-    bool sorted = isSorted(arr, 5, sizeof(int32_t), compDescending<int32_t>);
+    bool sorted = isSorted(arr, 5, sizeof(int32_t), compAscending<int32_t>);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TEST_F(SortTest, isNotSortedTest) {
int32_t arr[] = { 1, 2, 3, 5, 4 };
bool sorted = isSorted(arr, 5, sizeof(int32_t), compDescending<int32_t>);
EXPECT_FALSE(sorted);
}
TEST_F(SortTest, isNotSortedTest) {
int32_t arr[] = { 1, 2, 3, 5, 4 };
bool sorted = isSorted(arr, 5, sizeof(int32_t), compAscending<int32_t>);
EXPECT_FALSE(sorted);
}

Comment on lines +60 to +65
TEST_F(SortTest, binSearchTest) {
int32_t arr[] = { 1, 2, 3, 5, 4 };
quicksort(arr, 5, sizeof(int32_t), compDescending<int32_t>);
int32_t idx = binSearch(3, arr, 5, compDescending<int32_t>);
EXPECT_EQ(idx, 2);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix and enhance the binary search test.

The current test has several issues:

  1. No verification that the search returns -1 for values not in the array
  2. Uses the same comparison function for sorting and searching
 TEST_F(SortTest, binSearchTest) {
     int32_t arr[] = { 1, 2, 3, 5, 4 };
-    quicksort(arr, 5, sizeof(int32_t), compDescending<int32_t>);
-    int32_t idx = binSearch(3, arr, 5, compDescending<int32_t>);
+    quicksort(arr, 5, sizeof(int32_t), compAscending<int32_t>);
+    int32_t idx = binSearch(3, arr, 5, compAscending<int32_t>);
     EXPECT_EQ(idx, 2);
+    
+    // Test searching for a value not in the array
+    idx = binSearch(6, arr, 5, compAscending<int32_t>);
+    EXPECT_LT(idx, 0);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TEST_F(SortTest, binSearchTest) {
int32_t arr[] = { 1, 2, 3, 5, 4 };
quicksort(arr, 5, sizeof(int32_t), compDescending<int32_t>);
int32_t idx = binSearch(3, arr, 5, compDescending<int32_t>);
EXPECT_EQ(idx, 2);
}
TEST_F(SortTest, binSearchTest) {
int32_t arr[] = { 1, 2, 3, 5, 4 };
quicksort(arr, 5, sizeof(int32_t), compAscending<int32_t>);
int32_t idx = binSearch(3, arr, 5, compAscending<int32_t>);
EXPECT_EQ(idx, 2);
// Test searching for a value not in the array
idx = binSearch(6, arr, 5, compAscending<int32_t>);
EXPECT_LT(idx, 0);
}

Comment on lines +117 to +132
inline int32_t binSearchImpl(void *key, void *data, size_t num, size_t stride, ComparisonFn func) {
size_t offset = 0;
uint8_t *_data = (uint8_t *)data;
for (size_t i = num; offset < i;) {
size_t idx = (offset + i) / 2;
int32_t result = func(key, &_data[i * stride]);
if (result < 0) {
i = idx;
} else if (result > 0) {
offset = idx + 1;
} else {
return idx;
}
}
return ~offset;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix critical bug in binary search implementation.

There's a serious bug in the binary search implementation: the comparison is done with &_data[i * stride] where i can be as large as num, potentially causing out-of-bounds memory access.

inline int32_t binSearchImpl(void *key, void *data, size_t num, size_t stride, ComparisonFn func) {
    size_t offset = 0;
    uint8_t *_data = (uint8_t *)data;
    for (size_t i = num; offset < i;) {
        size_t idx = (offset + i) / 2;
-        int32_t result = func(key, &_data[i * stride]);
+        int32_t result = func(key, &_data[idx * stride]);
        if (result < 0) {
            i = idx;
        } else if (result > 0) {
            offset = idx + 1;
        } else {
            return idx;
        }
    }
    return ~offset;
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
inline int32_t binSearchImpl(void *key, void *data, size_t num, size_t stride, ComparisonFn func) {
size_t offset = 0;
uint8_t *_data = (uint8_t *)data;
for (size_t i = num; offset < i;) {
size_t idx = (offset + i) / 2;
int32_t result = func(key, &_data[i * stride]);
if (result < 0) {
i = idx;
} else if (result > 0) {
offset = idx + 1;
} else {
return idx;
}
}
return ~offset;
}
inline int32_t binSearchImpl(void *key, void *data, size_t num, size_t stride, ComparisonFn func) {
size_t offset = 0;
uint8_t *_data = (uint8_t *)data;
for (size_t i = num; offset < i;) {
size_t idx = (offset + i) / 2;
int32_t result = func(key, &_data[idx * stride]);
if (result < 0) {
i = idx;
} else if (result > 0) {
offset = idx + 1;
} else {
return idx;
}
}
return ~offset;
}

Comment on lines +102 to +115
bool isSorted(const void *data, size_t num, size_t stride, ComparisonFn func) {
if (num < 2) {
return true;
}
uint8_t *data_ = (uint8_t *)data;
for (size_t i=1; i<num; ++i) {
const int32_t result = func(&data_[(i-1)*stride], &data_[i * stride]);
if (result == -1) {
return false;
}
}

return true;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Make the isSorted check more robust.

The function checks if result == -1 to determine if an array is not sorted, but this assumes the comparison function returns specific values. It would be more robust to check if result < 0.

bool isSorted(const void *data, size_t num, size_t stride, ComparisonFn func) {
    if (num  < 2) {
        return true;
    }
    uint8_t *data_ = (uint8_t *)data;
    for (size_t i=1; i<num; ++i) {
        const int32_t result = func(&data_[(i-1)*stride], &data_[i * stride]);
-        if (result == -1) {
+        if (result < 0) {
            return false;
        }
    }

    return true;
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
bool isSorted(const void *data, size_t num, size_t stride, ComparisonFn func) {
if (num < 2) {
return true;
}
uint8_t *data_ = (uint8_t *)data;
for (size_t i=1; i<num; ++i) {
const int32_t result = func(&data_[(i-1)*stride], &data_[i * stride]);
if (result == -1) {
return false;
}
}
return true;
}
bool isSorted(const void *data, size_t num, size_t stride, ComparisonFn func) {
if (num < 2) {
return true;
}
uint8_t *data_ = (uint8_t *)data;
for (size_t i=1; i<num; ++i) {
const int32_t result = func(&data_[(i-1)*stride], &data_[i * stride]);
if (result < 0) {
return false;
}
}
return true;
}

@kimkulling kimkulling deleted the feature/add_sort branch April 2, 2025 18:29
Copy link

sonarqubecloud bot commented Apr 2, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
B Maintainability Rating on New Code (required ≥ A)
E Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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