Skip to content
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

feat(auto-salvage): v2 support #70

Merged
merged 2 commits into from
Oct 24, 2024

Conversation

c3y1huang
Copy link
Contributor

@c3y1huang c3y1huang commented Sep 23, 2024

Which issue(s) this PR fixes:

Issue longhorn/longhorn#8430

What this PR does / why we need it:

Implement a new function to sort the keys of a map in ascending order.

Special notes for your reviewer:

None

Additional documentation or context

None

@c3y1huang c3y1huang self-assigned this Sep 23, 2024
@c3y1huang c3y1huang marked this pull request as ready for review September 23, 2024 05:09
@c3y1huang c3y1huang requested review from derekbit and a team September 23, 2024 05:09
@c3y1huang c3y1huang force-pushed the 8430-feat-v2-auto-salvage branch 2 times, most recently from 10b92b6 to 7fbc273 Compare September 23, 2024 05:15
Copy link

codecov bot commented Sep 23, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 77.58%. Comparing base (8777df9) to head (29da146).
Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #70      +/-   ##
==========================================
+ Coverage   77.44%   77.58%   +0.14%     
==========================================
  Files          35       35              
  Lines        1920     1932      +12     
==========================================
+ Hits         1487     1499      +12     
  Misses        317      317              
  Partials      116      116              
Flag Coverage Δ
unittests 77.58% <100.00%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

Copy link
Contributor

@james-munson james-munson left a comment

Choose a reason for hiding this comment

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

Just one question, but LGTM.

utils/misc.go Outdated
sort.Slice(keys, func(i, j int) bool {
return reflect.ValueOf(keys[i]).String() < reflect.ValueOf(keys[j]).String()
})
case reflect.Uint64:
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a huge deal, but why not make this library method work for any type that CanUint() ?

Copy link
Contributor Author

@c3y1huang c3y1huang Oct 24, 2024

Choose a reason for hiding this comment

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

Thank you. I've made this more general. For the test cases, I am writing this for the v2 volume support auto salvage feature. We can extend with additional cases in future enhancements.

shuo-wu
shuo-wu previously approved these changes Oct 7, 2024
Copy link

@shuo-wu shuo-wu left a comment

Choose a reason for hiding this comment

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

LGTM

utils/misc.go Outdated Show resolved Hide resolved
Copy link

coderabbitai bot commented Oct 18, 2024

📝 Walkthrough

Walkthrough

The changes introduce a new function SortKeys in the utils package, which sorts the keys of a given map in ascending order. This function handles various key types and returns a slice of sorted keys along with an error if applicable. Additionally, a corresponding test function TestSortKeys is added to validate the functionality of SortKeys, covering multiple test cases including different key types and error scenarios.

Changes

File Change Summary
utils/misc.go Added function SortKeys[K constraints.Ordered, V any](mapObj map[K]V) ([]K, error) for sorting map keys.
utils/misc_test.go Added test function TestSortKeys(c *C) to validate SortKeys with various test cases.
go.mod Updated toolchain to go1.23.2 and added dependency golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc.
vendor/golang.org/x/exp/LICENSE Added copyright notice and licensing agreement for Go Authors.
vendor/golang.org/x/exp/PATENTS Introduced "Additional IP Rights Grant (Patents)" section outlining patent license.
vendor/golang.org/x/exp/constraints/constraints.go Added new package defining type constraints for generic programming.
vendor/modules.txt Added new module golang.org/x/exp and submodule golang.org/x/exp/constraints.

Assessment against linked issues

Objective Addressed Explanation
Support for sorting map keys (related to #8430) The changes do not address the feature request as it is unrelated to auto salvage functionality.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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 resolve resolve all the CodeRabbit review comments.
  • @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.

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.

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

🧹 Outside diff range and nitpick comments (1)
utils/misc_test.go (1)

247-300: LGTM! Well-structured test function with good coverage.

The TestSortKeys function is well-structured and covers a good range of scenarios, including edge cases. The test cases are clearly defined, and the assertions are appropriate.

Consider the following improvements:

  1. Add a test case for a map with mixed key types to ensure the function handles this scenario correctly.
  2. For numeric key types (e.g., uint64), add an explicit check to verify the correct ordering of the sorted keys.
  3. Enhance the error messages in the assertions to provide more context. For example:
c.Assert(err, IsNil, Commentf("Expected no error for %s, but got: %v", testName, err))
c.Assert(result, DeepEquals, testCase.expected, Commentf("Unexpected result for %s. Got %v, expected %v", testName, result, testCase.expected))

These improvements will make the tests more robust and easier to debug if they fail.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a2a9589 and 86c4cfa.

📒 Files selected for processing (2)
  • utils/misc.go (2 hunks)
  • utils/misc_test.go (1 hunks)
🧰 Additional context used
🔇 Additional comments (1)
utils/misc.go (1)

10-10: LGTM: Import statement added correctly.

The sort package import is necessary for the new SortKeys function and is placed correctly in alphabetical order.

utils/misc.go Outdated Show resolved Hide resolved
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.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 86c4cfa and 6818500.

📒 Files selected for processing (2)
  • utils/misc.go (2 hunks)
  • utils/misc_test.go (1 hunks)
🧰 Additional context used
🔇 Additional comments (1)
utils/misc.go (1)

125-154: 🛠️ Refactor suggestion

Consider enhancing the flexibility and performance of the SortKeys function.

While the current implementation is a good start, there are several areas for improvement:

  1. Limited type support: The function only handles string and uint64 key types. Consider extending this to support more types or allowing custom comparison functions.

  2. Use of reflection: The current implementation uses reflection, which may impact performance for large maps. Consider using type switches or type constraints for better performance.

  3. Error handling: The error for unsupported types is returned after creating and partially processing the slice. It would be more efficient to check the type earlier.

  4. PR objectives: It's not clear how this function relates to the PR objectives of implementing v2 volume support for auto salvage. Consider adding a comment explaining its role in the larger feature implementation.

Here's a suggested refactor that addresses these points:

import (
    "golang.org/x/exp/constraints"
    "sort"
)

func SortKeys[K constraints.Ordered, V any](mapObj map[K]V) ([]K, error) {
    if mapObj == nil {
        return nil, fmt.Errorf("input object cannot be nil")
    }

    keys := make([]K, 0, len(mapObj))
    for key := range mapObj {
        keys = append(keys, key)
    }

    sort.Slice(keys, func(i, j int) bool {
        return keys[i] < keys[j]
    })

    return keys, nil
}

This version:

  • Uses the constraints.Ordered interface to support all ordered types.
  • Avoids reflection for better performance.
  • Simplifies the implementation by leveraging Go's type system.

To ensure this change doesn't break existing usage, please run the following command:

Would you like me to provide an implementation that allows for custom comparison functions, or to explain how this utility fits into the larger auto salvage feature?

✅ Verification successful

The review comment regarding the SortKeys function is valid and can be implemented safely.

  • The function is primarily used in utils/misc_test.go and vendor packages, minimizing the risk of impacting the main codebase.
  • Enhancing flexibility and performance as suggested will improve utility without adverse effects.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all usages of SortKeys in the codebase
rg "SortKeys\(" --type go

Length of output: 746

utils/misc_test.go Outdated Show resolved Hide resolved
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

🧹 Outside diff range and nitpick comments (3)
utils/misc.go (1)

125-141: LGTM with suggestions for further improvements.

The SortKeys function is well-implemented and addresses the main objective of sorting map keys in ascending order. It uses generics with constraints.Ordered, which provides good type safety and flexibility. The error handling for nil input is a good practice.

However, there are a few potential improvements to consider:

  1. Performance: For large maps, using sort.Slice might not be the most efficient approach due to its use of reflection.
  2. Customization: The function doesn't allow for custom sorting logic, which might be useful in some scenarios.

Consider the following enhancements:

  1. For better performance, you could use sort.Sort with a custom sorter implementation instead of sort.Slice.
  2. To allow for custom sorting logic, you could add an optional comparison function parameter.

Here's a potential signature that addresses these points:

func SortKeys[K constraints.Ordered, V any](mapObj map[K]V, less func(K, K) bool) ([]K, error)

This would allow callers to provide their own sorting logic if needed, while still using the default comparison if no function is provided.

Would you like me to provide an example implementation of this more flexible approach?

utils/misc_test.go (2)

248-288: LGTM: Comprehensive test cases for SortKeys function.

The TestSortKeys function provides good coverage for various scenarios, including edge cases (nil and empty maps) and different key types (string and uint64). The use of generics allows for efficient testing of multiple key types.

Consider adding a test case with a larger number of keys to ensure the sorting works correctly for bigger datasets.


296-308: LGTM: Well-implemented generic test runner.

The runTestSortKeys function effectively executes the test cases for different key types. It properly handles both error and success scenarios.

Consider enhancing the error messages to provide more context:

c.Assert(err, IsNil, Commentf("Unexpected error in %v: %v", testName, err))
c.Assert(result, DeepEquals, tc.expected, Commentf("Unexpected result in %v. Got: %v, Expected: %v", testName, result, tc.expected))
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6818500 and c59189e.

📒 Files selected for processing (7)
  • go.mod (1 hunks)
  • utils/misc.go (2 hunks)
  • utils/misc_test.go (2 hunks)
  • vendor/golang.org/x/exp/LICENSE (1 hunks)
  • vendor/golang.org/x/exp/PATENTS (1 hunks)
  • vendor/golang.org/x/exp/constraints/constraints.go (1 hunks)
  • vendor/modules.txt (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • vendor/golang.org/x/exp/LICENSE
🧰 Additional context used
🔇 Additional comments (7)
vendor/golang.org/x/exp/PATENTS (1)

1-22: Verify the necessity and implications of including this patent grant.

The addition of the "Additional IP Rights Grant (Patents)" file from Google's Go project is a significant legal document. While it provides patent protection for users of the Go implementation, it's important to consider the following:

  1. Ensure that including this file aligns with your project's licensing strategy and doesn't conflict with existing licenses.
  2. Verify that your project actually uses code from golang.org/x/exp that necessitates including this patent grant.
  3. Be aware that this grant includes a termination clause in case of patent litigation, which could affect your project's users.

To confirm the necessity of this file, please run the following script:

This change seems tangential to the main objective of implementing a function to sort map keys. Please clarify how this relates to the PR's primary goal of adding v2 volume support for auto salvage.

go.mod (2)

Line range hint 5-5: Verify compatibility with the new Go toolchain version.

The toolchain has been updated from go1.22.0 to go1.23.2, which is a significant version jump. This change may introduce new features or potential breaking changes.

Please ensure that:

  1. All dependencies are compatible with Go 1.23.2.
  2. The codebase has been tested thoroughly with the new toolchain version.
  3. CI/CD pipelines have been updated to use Go 1.23.2.

Run the following script to check for any compatibility issues:


16-16: Clarify the purpose of the new experimental dependency.

A new experimental dependency has been added: golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc

Please provide information on:

  1. The specific features or functions from this package that are being used in the project.
  2. Why this experimental package was chosen over stable alternatives, if any exist.
  3. Any potential risks or limitations associated with using this experimental package.

Additionally, consider adding a comment in the code or documentation explaining the purpose of this dependency for future reference.

To verify the usage of this package, run the following script:

utils/misc_test.go (3)

6-6: LGTM: New import for constraints package.

The addition of the golang.org/x/exp/constraints import is appropriate for the use of the Ordered constraint in the new generic types and functions.


290-294: LGTM: Well-defined generic test case type.

The testCaseSortKeys type is well-structured and uses appropriate generic constraints. It provides all necessary fields for comprehensive testing of the SortKeys function.


248-308: Great job on implementing comprehensive tests for SortKeys!

The new test implementation for SortKeys is well-structured, uses generics effectively, and covers various scenarios. It integrates seamlessly with the existing test suite and follows consistent coding patterns.

Some minor suggestions for further improvement:

  1. Consider adding a test case with a larger number of keys.
  2. Enhance error messages in assertions to provide more context.
  3. Add a test case for unsupported key types to ensure proper error handling.

Overall, excellent work on expanding the test coverage!

vendor/modules.txt (1)

146-148: LGTM: Addition of golang.org/x/exp module

The addition of the golang.org/x/exp module, specifically the constraints submodule, is appropriate for implementing generic sorting functions. This aligns well with the PR objective of sorting map keys.

Let's verify the usage of this new module in the codebase:

✅ Verification successful

Verified: golang.org/x/exp/constraints Usage Confirmed

The usage of the golang.org/x/exp/constraints module has been confirmed in the following files:

  • utils/misc_test.go (lines 290, 296)
  • utils/misc.go (line 126)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for the usage of golang.org/x/exp/constraints in the codebase

# Test: Search for import statements using the new module
echo "Checking for import statements:"
rg -n 'import.*"golang.org/x/exp/constraints"'

# Test: Search for usage of types from the constraints package (e.g., Ordered)
echo "Checking for usage of constraints.Ordered:"
rg -n 'constraints\.Ordered'

Length of output: 551

Copy link
Member

@derekbit derekbit left a comment

Choose a reason for hiding this comment

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

LGTM.

@c3y1huang Ready to merge?

longhorn/longhorn-8430

Signed-off-by: Chin-Ya Huang <[email protected]>
longhorn/longhorn-8430

Signed-off-by: Chin-Ya Huang <[email protected]>
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

🧹 Outside diff range and nitpick comments (3)
utils/misc_test.go (3)

6-6: Consider documenting the use of experimental package.

The golang.org/x/exp/constraints package is experimental. While it's the recommended way to implement generic constraints, it's worth documenting this dependency and potential future migration needs when the package becomes stable.


248-288: Consider adding more comprehensive test cases.

The test coverage is good for basic scenarios, but consider adding these test cases:

  1. Maps with duplicate values but unique keys
  2. Maps with special characters or unicode strings
  3. Large maps to verify performance
  4. Maps with maximum uint64 values

Example:

"SortKeys(...): unicode strings": {
    inputMap: map[string]any{
        "世界": "",
        "Hello": "",
        "你好": "",
    },
    expected: []string{"Hello", "世界", "你好"},
},
"SortKeys(...): large numbers": {
    inputMap: map[uint64]any{
        math.MaxUint64: "",
        math.MaxUint64 - 1: "",
    },
    expected: []uint64{0, math.MaxUint64 - 1, math.MaxUint64},
},

296-308: Consider enhancing error messages for better debugging.

While the test runner is well-structured, the error messages could be more descriptive. Consider:

-c.Assert(err, NotNil, Commentf("Expected error in %v", testName))
+c.Assert(err, NotNil, Commentf("Expected error for test case %v with input: %v", testName, tc.inputMap))

-c.Assert(err, IsNil, Commentf("Unexpected error in %v", testName))
+c.Assert(err, IsNil, Commentf("Unexpected error in %v: %v", testName, err))

-c.Assert(result, DeepEquals, tc.expected, Commentf("Unexpected result in %v", testName))
+c.Assert(result, DeepEquals, tc.expected, Commentf("Test case %v: expected %v but got %v", testName, tc.expected, result))
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c59189e and 29da146.

⛔ Files ignored due to path filters (5)
  • go.mod is excluded by !go.mod
  • vendor/golang.org/x/exp/LICENSE is excluded by !vendor/**
  • vendor/golang.org/x/exp/PATENTS is excluded by !vendor/**
  • vendor/golang.org/x/exp/constraints/constraints.go is excluded by !vendor/**
  • vendor/modules.txt is excluded by !vendor/**
📒 Files selected for processing (2)
  • utils/misc.go (2 hunks)
  • utils/misc_test.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • utils/misc.go
🔇 Additional comments (1)
utils/misc_test.go (1)

290-294: LGTM! Well-structured test case type.

The generic type definition with constraints.Ordered constraint is well-designed and provides good type safety.

@c3y1huang
Copy link
Contributor Author

LGTM.

@c3y1huang Ready to merge?

Yes! It's just a general-purposed lib and is ready for merge. Thank you!

Copy link
Member

@derekbit derekbit left a comment

Choose a reason for hiding this comment

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

Thank you @c3y1huang

@derekbit derekbit merged commit 9e7505c into longhorn:main Oct 24, 2024
8 checks passed
@c3y1huang c3y1huang deleted the 8430-feat-v2-auto-salvage branch October 24, 2024 00:45
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.

4 participants