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

Add keypath filtering for Property/CollectionChanged #3121

Closed
wants to merge 26 commits into from

Conversation

JacobOscarGunnarsson
Copy link
Contributor

@JacobOscarGunnarsson JacobOscarGunnarsson commented Dec 7, 2022

Partially Fixes #3112. initially we will internally filter the notifications in the following manner:

  • for objects we won't listen for events happening to collection properties at all. This include backlinks, sets, dictionaries, list and queries/results.
  • For collections, we will only listen to the shallow modifications that are done on the collection itself. this means that modifications to objects within a collection won't fire a notification

This PR needs to wait until these changes are merged to core

@fealebenpae
Copy link
Member

computed_properties contains only backlink/LinkingObjects properties. I think you should also include regular properties where the type is a collection.

@JacobOscarGunnarsson JacobOscarGunnarsson force-pushed the jg/keypath_filtering_internal branch from 41e1de8 to 0c846c4 Compare December 8, 2022 15:08
@JacobOscarGunnarsson JacobOscarGunnarsson force-pushed the jg/keypath_filtering_internal branch 3 times, most recently from a1ed80f to b51e8b8 Compare December 8, 2022 15:43
Copy link
Contributor

@papafe papafe left a comment

Choose a reason for hiding this comment

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

I think the tests make sense! Probably it'll be worth adding also collections of other types, in the same way you did for single link

@@ -181,12 +181,15 @@ public void SubscribeForNotifications(Action<string> notifyPropertyChangedDelega
throw new RealmFrozenException("It is not possible to add a change listener to a frozen RealmObjectBase since it never changes.");
}

PropertyType collectionFlag = PropertyType.Array | PropertyType.Dictionary | PropertyType.Set;
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably we also need to check backlinks? I'm not sure we get notifications for those in any case.

Also, it would make sense to calculate those indices only once, they are not going to change

Copy link
Member

Choose a reason for hiding this comment

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

Backlinks are in a separate vector in the Object Store ObjectSchema so even if they cause notifications they need to be handled separately. But we need to see if they raise notifications in the first place.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a test to check this, and they don't in our case

@@ -181,12 +181,15 @@ public void SubscribeForNotifications(Action<string> notifyPropertyChangedDelega
throw new RealmFrozenException("It is not possible to add a change listener to a frozen RealmObjectBase since it never changes.");
}

PropertyType collectionFlag = PropertyType.Array | PropertyType.Dictionary | PropertyType.Set;
Copy link
Member

Choose a reason for hiding this comment

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

Backlinks are in a separate vector in the Object Store ObjectSchema so even if they cause notifications they need to be handled separately. But we need to see if they raise notifications in the first place.

{
EnsureIsOpen();

var result = NativeMethods.add_notification_callback(this, managedObjectHandle, out var nativeException);
var propertyIndicesLength = propertyIndices == null ? (IntPtr)0 : (IntPtr)propertyIndices.Length;
var result = NativeMethods.add_notification_callback(this, managedObjectHandle, propertyIndices, propertyIndicesLength, out var nativeException);

Check notice

Code scanning / CodeQL

Calls to unmanaged code

Replace this call with a call to managed code if possible.
{
EnsureIsOpen();

var result = NativeMethods.add_notification_callback(this, managedObjectHandle, out var nativeException);
var propertyIndicesLength = propertyIndices == null ? (IntPtr)0 : (IntPtr)propertyIndices.Length;
var result = NativeMethods.add_notification_callback(this, managedObjectHandle, propertyIndices, propertyIndicesLength, out var nativeException);

Check notice

Code scanning / CodeQL

Calls to unmanaged code

Replace this call with a call to managed code if possible.

var result = NativeMethods.add_notification_callback(this, managedObjectHandle, out var nativeException);
var propertyIndicesLength = propertyIndices == null ? (IntPtr)0 : (IntPtr)propertyIndices.Length;
var result = NativeMethods.add_notification_callback(this, managedObjectHandle, propertyIndices, propertyIndicesLength, out var nativeException);

Check notice

Code scanning / CodeQL

Calls to unmanaged code

Replace this call with a call to managed code if possible.
{
EnsureIsOpen();

var result = NativeMethods.add_notification_callback(this, managedObjectHandle, out var nativeException);
var propertyIndicesLength = propertyIndices == null ? (IntPtr)0 : (IntPtr)propertyIndices.Length;
var result = NativeMethods.add_notification_callback(this, managedObjectHandle, propertyIndices, propertyIndicesLength, out var nativeException);

Check notice

Code scanning / CodeQL

Calls to unmanaged code

Replace this call with a call to managed code if possible.
{
EnsureIsOpen();

var result = NativeMethods.add_notification_callback(this, managedObjectHandle, out var nativeException);
var propertyIndicesLength = propertyIndices == null ? (IntPtr)0 : (IntPtr)propertyIndices.Length;
var result = NativeMethods.add_notification_callback(this, managedObjectHandle, propertyIndices, propertyIndicesLength, out var nativeException);

Check notice

Code scanning / CodeQL

Calls to unmanaged code

Replace this call with a call to managed code if possible.
@@ -63,7 +64,7 @@
public static extern void destroy(IntPtr listInternalHandle);

[DllImport(InteropConfig.DLL_NAME, EntryPoint = "list_add_notification_callback", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr add_notification_callback(ListHandle listHandle, IntPtr managedListHandle, out NativeException ex);
public static extern IntPtr add_notification_callback(ListHandle listHandle, IntPtr managedListHandle, [MarshalAs(UnmanagedType.LPArray), In] IntPtr[] propjerty_indices, IntPtr property_count, out NativeException ex);

Check notice

Code scanning / CodeQL

Unmanaged code

Minimise the use of unmanaged code.
@@ -43,7 +44,7 @@
public static extern void clear(ResultsHandle results, SharedRealmHandle realmHandle, out NativeException ex);

[DllImport(InteropConfig.DLL_NAME, EntryPoint = "results_add_notification_callback", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr add_notification_callback(ResultsHandle results, IntPtr managedResultsHandle, out NativeException ex);
public static extern IntPtr add_notification_callback(ResultsHandle results, IntPtr managedResultsHandle, [MarshalAs(UnmanagedType.LPArray), In] IntPtr[] propjerty_indices, IntPtr property_count, out NativeException ex);

Check notice

Code scanning / CodeQL

Unmanaged code

Minimise the use of unmanaged code.
@@ -36,7 +37,7 @@
public static extern void destroy(IntPtr handle);

[DllImport(InteropConfig.DLL_NAME, EntryPoint = "realm_set_add_notification_callback", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr add_notification_callback(SetHandle handle, IntPtr managedSetHandle, out NativeException ex);
public static extern IntPtr add_notification_callback(SetHandle handle, IntPtr managedSetHandle, [MarshalAs(UnmanagedType.LPArray), In] IntPtr[] propjerty_indices, IntPtr property_count, out NativeException ex);

Check notice

Code scanning / CodeQL

Unmanaged code

Minimise the use of unmanaged code.
Copy link
Member

@fealebenpae fealebenpae left a comment

Choose a reason for hiding this comment

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

A few small comments. I'd also like to see the PR updated with the Core submodule pointing to the Core branch so I can see the related wrappers changes in full as well.

@JacobOscarGunnarsson JacobOscarGunnarsson marked this pull request as ready for review December 20, 2022 09:36
@nirinchev nirinchev mentioned this pull request Jan 13, 2023
2 tasks
@nirinchev nirinchev closed this Jan 20, 2023
@nirinchev nirinchev deleted the jg/keypath_filtering_internal branch January 20, 2023 13:52
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add keypath filtering for Property/CollectionChanged
4 participants