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 event listeners to RocksJava #7425

Closed
wants to merge 22 commits into from
Closed

Conversation

alucarded
Copy link
Contributor

@alucarded alucarded commented Sep 22, 2020

Allows adding event listeners in RocksJava.

  • Adds listeners getter and setter in Options and DBOptions classes.
  • Adds EventListener Java interface and base class for implementing custom event listener callbacks - AbstractEventListener, which has an underlying native callback class implementing C++ EventListener class.
  • AbstractEventListener class has mechanism for selectively enabling its callback methods in order to prevent invoking Java method if it is not implemented. This decreases performance cost in case only subset of event listener callback methods is needed - the JNI code for remaining "no-op" callbacks is not executed.
  • The code is covered by unit tests in EventListenerTest.java, there are also tests added for setting/getting listeners field in OptionsTest.java and DBOptionsTest.java.

@alucarded
Copy link
Contributor Author

alucarded commented Sep 23, 2020

As regards fix to RTTI issue (avoid dynamic_cast) added in the commit:

Another solution (which would seem better at first glance) would be to hold native object EventListenerJniCallback for AbstractEventListener Java class and static_cast it to EventListener type pointer when setting listeners. Then, when getting listeners, we would reinterpret_cast EventListener pointers to EventListenerJniCallback pointers to get the jobject on whhich we would call callback method.

Unfortunately...

...we cannot static_cast from derived to base class pointer
and then reinterpret_cast from base to derived pointer.
See experiments such as: https://stackoverflow.com/a/60203479
https://hacksoflife.blogspot.com/2007/02/c-objects-part-3-multiple-inheritance.html
Docs:
https://timsong-cpp.github.io/cppwp/n4659/basic.compound#4
https://timsong-cpp.github.io/cppwp/n4659/class#7

Even if we redesign EventListenerJniCallback to have single inheritance (JniCallback would be a member class) we will not get standard-layout class (because of virtual methods in EventListener) and thus EventListener and EventListenerJniCallback would not be pointer-interconvertible.

Copy link
Collaborator

@adamretter adamretter left a comment

Choose a reason for hiding this comment

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

We have been through several rounds of internal review with @alucarded already here at Evolved Binary. I am happy this PR is now in a good shape.

Unless anyone has some suggestions about the RTTI issue for avoiding dynamic_cast, then I think it is good to merge.

@pdillinger @siying any comments?

@pdillinger
Copy link
Contributor

Unless anyone has some suggestions about the RTTI issue for avoiding dynamic_cast, then I think it is good to merge.

If you're considering reinterpret_cast, I assume you know it's an EventListenerJniCallback object. If the jlong came from an EventListener*, wouldn't you want to reinterpret_cast from jlong back to EventListener* and static_cast from EventListener* to EventListenerJniCallback*?

@alucarded
Copy link
Contributor Author

alucarded commented Sep 25, 2020

@pdillinger It all makes sense now... For some reason I assumed I cannot downcast in this case, which is actually false. I am making the change. Thank you.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@jay-zhuang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

* @param flushJobInfo the flush job info, contains data copied from
* respective native structure.
*/
void onFlushCompleted(final RocksDB db, final FlushJobInfo flushJobInfo);
Copy link
Contributor

Choose a reason for hiding this comment

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

Great Work Do you mind move onFlushBegin before onFlushCompleted ?

@@ -5,6 +5,8 @@

package org.rocksdb;

import java.util.Objects;
Copy link
Contributor

Choose a reason for hiding this comment

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

why import this package?

Copy link
Contributor

Choose a reason for hiding this comment

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

or just say "unused import"

@facebook-github-bot
Copy link
Contributor

@alucarded has updated the pull request. You must reimport the pull request before landing.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@jay-zhuang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@jay-zhuang merged this pull request in 6528ecc.

codingrhythm pushed a commit to SafetyCulture/rocksdb that referenced this pull request Mar 5, 2021
Summary:
Allows adding event listeners in RocksJava.

* Adds listeners getter and setter in `Options` and `DBOptions` classes.
* Adds `EventListener` Java interface and base class for implementing custom event listener callbacks - `AbstractEventListener`, which has an underlying native callback class implementing C++ `EventListener` class.
* `AbstractEventListener` class has mechanism for selectively enabling its callback methods in order to prevent invoking Java method if it is not implemented. This decreases performance cost in case only subset of event listener callback methods is needed - the JNI code for remaining "no-op" callbacks is not executed.
* The code is covered by unit tests in `EventListenerTest.java`, there are also tests added for setting/getting listeners field in `OptionsTest.java` and `DBOptionsTest.java`.

Pull Request resolved: facebook#7425

Reviewed By: pdillinger

Differential Revision: D24063390

Pulled By: jay-zhuang

fbshipit-source-id: 508c359538983d6b765e70d9989c351794a944ee
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants