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

Improve GetNavigationSource performance #1158

Closed
wants to merge 5 commits into from

Conversation

habbes
Copy link
Contributor

@habbes habbes commented Jan 18, 2024

Fix #1118

Replaces the use of ODataPathNavigationSourceHandler in ODataPath.GetNavigationSource extension method with a simpler reverse loop of the path.

With ODataPathNavigationSourceHandler

  • a new instance of the handler is allocated
  • all the segments of the path are visited
  • a List<string> is created and populated with the string representation of each path segment. This list is used to generate a string representation of the path via a Path property. But this property is not needed to determine the navigation source (it's also not used by existing code).

The new implementation scans the path segments from the end and stops as soon as it finds the navigation source because only the last navigation source in the path matters.

Also, the ODataPath.GetNavigationSource() method didn't have good test coverage, so I added tests to verify all the scenarios the original implementation handled.

The ODataPathNavigationSourceHandler is public so I kept it to avoid breaking changes.

Before

image

After

image

continue;
}

return null;

Choose a reason for hiding this comment

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

Should all other Segments i.e

DynamicPathSegment
PathTemplateSegment
ValueSegment
CountSegment
BatchSegment
MetadataSegment
ODataPathSegment

Return null?
Was this the pre-existing behavour ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, they should return null. That's the existing behaviour. Also handled in tests.

@@ -77,9 +77,59 @@ public static IEdmNavigationSource GetNavigationSource(this ODataPath path)
throw Error.ArgumentNull(nameof(path));
}

ODataPathNavigationSourceHandler handler = new ODataPathNavigationSourceHandler();
Copy link

@wachugamaina wachugamaina Jan 19, 2024

Choose a reason for hiding this comment

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

With this type of of refactors, I think it would be wise to add the comprehensive tests first and have that go in, then come to the refractor. because when the tests come in with the change, it is quite hard to tell if indeed the tests represent the pre-existing behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, let me create a separate PR to add the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've created the tests PR: #1159

[InlineData("Customers(1)/Account/Amount/$value", null, EdmNavigationSourceKind.None)]
[InlineData("$batch", null, EdmNavigationSourceKind.None)]
[InlineData("$metadata", null, EdmNavigationSourceKind.None)]
public void GetNavigationSource_ReturnsCorrectNavigationSource(string path, string expectedNavigationSource, EdmNavigationSourceKind navigationSourceKind)

Choose a reason for hiding this comment

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

I dont belive that all the handler cases are covered in these tests, for example I cannot see
operationImportSegment
operationSegment
TypeSegment
DynamicPathSegment
PathTemplateSegment
ValueSegment
CountSegment
BatchSegment
MetadataSegment
ODataPathSegment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All those scenarios are covered:

  • OperationImportSegment: lines 78 and 79
  • OperationSegment: lines 8-83, 87
  • TypeSegment: 88. 89
  • DynamicPathSegment: 77
  • ValueSegment: 91
  • CountSegment: 90
  • MetadataSegment: 93
  • BatchSegment: 92

PathTemplateSegment is covered separately in the test GetNavigationSource_WhenPathTemplateSegment_ReturnsNull on line 116

ODataPathSegment is the abstract base class. I tested this by creating a new UnknownTestODataPathSegment and verifying that it returns null in GetNavigationSource_WhenUnkownPathSegment_ReturnsNull on line 130.

@habbes
Copy link
Contributor Author

habbes commented Jan 19, 2024

Closing this PR since I'm splitting the test and refactoring in separate PRs. I will re-create the PR once the tests have been merged: #1159

@habbes habbes closed this Jan 19, 2024
@habbes
Copy link
Contributor Author

habbes commented Jan 23, 2024

Replaced with: #1161

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.

Perf: Optimize GetNavigationSource(ODataPath)
2 participants