Skip to content

Added merge, filter and other functionalities in ThreadSafeDictionary.#1112

Merged
praveek merged 9 commits intoadobe:dev-v5.4.0from
akhiljain1907:feat/ThreadSafeDictionary
Feb 14, 2025
Merged

Added merge, filter and other functionalities in ThreadSafeDictionary.#1112
praveek merged 9 commits intoadobe:dev-v5.4.0from
akhiljain1907:feat/ThreadSafeDictionary

Conversation

@akhiljain1907
Copy link
Copy Markdown
Contributor

@akhiljain1907 akhiljain1907 commented Feb 4, 2025

Description

This PR extends ThreadSafeDictionary with utility functions like filter, contains(where:), removeAll(), and merge(_:uniquingKeysWith:) to align with Dictionary capabilities while ensuring thread safety.

These additions are necessary for the Optimize extension, where we are replacing Dictionary with ThreadSafeDictionary to maintain concurrency safety.

Related Issue

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Copy link
Copy Markdown
Contributor

@cdhoffmann cdhoffmann left a comment

Choose a reason for hiding this comment

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

Can you clarify on the PR description what these functions are needed for specifically.

return filteredDictionary
}

@inlinable public func contains(where predicate: (Element) -> Bool) -> Bool {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you add comments for all these functions?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

}
}

@inlinable public func filter(_ isIncluded: (Element) -> Bool) -> ThreadSafeDictionary<K, V> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I recommend removing this function entirely and handling filtering within optimize.

This function may lead to incorrect usage, such as modifying a thread safe dictionary in place:
threadSafeDict = threadSafeDict.filter(..)
If the goal is only to filter, return a copy of the filtered items instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I feel it would be better to return ThreadSafeDictionary itself while applying filter operation on it. However, the need was to get a dictionary in return. I have modified it to return a dictionary after your concern. Please let me know if this looks better?


}

extension ThreadSafeDictionary: Codable where K: Codable, V: Codable {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is this needed? Is Optimize serializing thread safe dictionary?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We need to send back the dictionary in event data, but since we can get the shallow copy from thread safe dictionary we don't need this. And thus i have removed it. Thanks a lot for pointing this.

@akhiljain1907
Copy link
Copy Markdown
Contributor Author

@cdhoffmann, @praveek Thanks for reviewing. I have made relevant changes and would request you to verify them.

@praveek praveek changed the base branch from main to dev-v5.3.0 February 12, 2025 16:34
@inlinable public func filter(_ isIncluded: (Element) -> Bool) -> [K: V] {
var filteredDictionary = [K: V]()
queue.sync {
for (key, value) in dictionary where isIncluded((key, value)) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: You can use dictionary.filter(..) method here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

dict.merge([1: "One", 2: "Two", 3: "Three", 4: "Four"]) { _, new in new }

// Apply filter to keep only even keys
var filtered = dict.filter { key, _ in key % 2 == 0 }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This test is not needed as filter returns a regular dictionary.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated test.

@praveek praveek changed the base branch from dev-v5.3.0 to dev-v5.4.0 February 12, 2025 16:47
@praveek praveek merged commit e53cf29 into adobe:dev-v5.4.0 Feb 14, 2025
3 checks passed
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.

5 participants