-
Notifications
You must be signed in to change notification settings - Fork 29
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
Use an explicit per-View modification counter [ECR-2804] #658
Use an explicit per-View modification counter [ECR-2804] #658
Conversation
Use an explicit modification counter in each View to get rid of static state in ViewModificationCounter singleton and simplify testing. As previously, a ModificationCounter is associated with each View (either a Fork or Snapshot), but this relationship is now more transparent.
/** | ||
* Notifies this counter that the source object is modified, updating its current value. | ||
* | ||
* @throws IllegalStateException if this counter corresponds to a read-only (immutable) object, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if a counter shall concern itself with immutable things (on top of that, the AbstractIndexProxy does this check itself)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to be safe and throw an exception in case of an immutable counter (as it is now)
}) | ||
@Disabled | ||
// TODO Won't run on Java 10 till Powermock is updated [ECR-1614]. | ||
// TODO Won't run on Junit 5 till Powermock is updated [ECR-1614]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be more precise, till Powermock gains support of JUnit 5 (we use the most recent version)
assertThat(thrown.getMessage(), matchesPattern(pattern)); | ||
|
||
assertFalse(counter.isModifiedSince(initialValue)); | ||
} | ||
|
||
@Test | ||
void notifyModifiedAcceptsFork() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test verifies that the index does use a counter from the Fork. Not sure if we shall add an integration test of Collection + Iterator + ModificationCounter, verifying that modification of another collection created with the same Fork invalidates the iterator of the first collection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
package com.exonum.binding.storage.database; | ||
|
||
/** | ||
* A counter of events-modifications of some objects (e.g., a collection, or a database view). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A counter of modification events
?
/** | ||
* Notifies this counter that the source object is modified, updating its current value. | ||
* | ||
* @throws IllegalStateException if this counter corresponds to a read-only (immutable) object, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to be safe and throw an exception in case of an immutable counter (as it is now)
@@ -32,8 +32,10 @@ | |||
final class ConfigurableRustIter<E> extends AbstractNativeProxy implements RustIter<E> { | |||
|
|||
private final LongFunction<E> nextFunction; | |||
// todo: This view is kept only for diagnostic purposes (to put in error message) — |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Views don't have toString
overridden, so would it be helpful to log things like com.exonum.binding.storage.database.Fork@131ef10
? Or maybe it would make sense to return View#getViewNativeHandle
for diagnostic purposes? If no to both questions, then I'd remove this field.
*/ | ||
boolean isModifiedSince(int lastValue); | ||
|
||
// todo: We _might_ consider adding a special type for this timestamp, but at the moment it feels like an overkill |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe create a task instead of todo? Do you think it's realistic that a counter might overflow int
range? If yes, we could add throwing an exception in notifyModified
for such a case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reasoning was to hide the knowledge of how that timestamp is represented to be able to change later, but in an internal interface it seems to be unnecessary.
I've documented, however, that counters must detect up to 4B modifications, that shall be enough :-)
|
||
final class IncrementalModificationCounter implements ModificationCounter { | ||
|
||
private static final int INITIAL_VALUE = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems excessive to me, as we only use it once in the next line. Or maybe make it public? That way it'd be clear for users what the initial value is (because right now in tests to get initialValue
we call getCurrentValue
which is error-prone. We could use a public field in tests as well). But I do not insist, it's good as it is as well :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think that the clients shall care about the initial value, what they shall is current value (= the value at the moment when an (spl)iterator is bound to source). initial value is an implementation detail of this counter.
The constnant can probably be inlined, and the field renamed to counter
exonum-java-binding-core/src/main/java/com/exonum/binding/storage/database/Fork.java
Outdated
Show resolved
Hide resolved
…age/database/Fork.java Co-Authored-By: dmitry-timofeev <[email protected]>
…num-java-binding-1 into refactor-mod-counter
Overview
Use an explicit modification counter in each View to get rid of
static state in ViewModificationCounter singleton and simplify
testing. As previously, a ModificationCounter is associated with each
View (either a Fork or Snapshot), but this relationship is now more
transparent.
See: https://jira.bf.local/browse/ECR-2804
Definition of Done