Skip to content

Conversation

@tkalkirill
Copy link
Contributor


static {
try {
COUNTER = MethodHandles.lookup().findVarHandle(PartitionProcessingCounter.class, "counter", int.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like a replacement for an AtomicInteger. AtomicInteger would make the code more concise and easier to understand, you could use incrementAndGet() and decrementAndGet() below.

You probably wanted to spare object instances using this approach, but it's just one instance per partition. It seems unlikely that someone will have even a million partitions in the same JVM, so the saving is not worth code complexity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In this case, we will save memory and at the same time the complexity of the code will not increase.

Copy link
Contributor

Choose a reason for hiding this comment

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

The complexity increases in both creation (static block with try and MethodHandles invocation vs new AtomicInteger()) and usage (incrementAndGet() vs getAndAdd(this, 1) + 1). It is slightly simpler, but simpler. And even slight simplification is wortha lot (surely more than saving 10k objects per JVM).

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 do not think that for us it greatly complicates the code.

public void onStartPartitionProcessing() {
assert !future.isDone();

int updatedValue = (int) COUNTER.getAndAdd(this, 1) + 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks analogous to counter.incrementAndGet() (when using AtomicInteger)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is, but it's not complex code.

public void onFinishPartitionProcessing() {
assert !future.isDone();

int updatedValue = (int) COUNTER.getAndAdd(this, -1) - 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks analogous to counter.decrementAndGet() (when using AtomicInteger)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is, but it's not complex code.


static {
try {
STARTED = MethodHandles.lookup().findVarHandle(PageMemoryHashIndexStorage.class, "started", boolean.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use AtomicBoolean instead. It makes the code simpler and the price we pay (one object per index per partition) is tiny. The same relates to all pagemem-based index and MvPartitionStorage implementations.

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 think we should leave it as it is, we use less memory, and the complexity here is minimal.

*/
@ExtendWith(WorkDirectoryExtension.class)
@ExtendWith(ConfigurationExtension.class)
@ExtendWith({ConfigurationExtension.class, WorkDirectoryExtension.class})
Copy link
Contributor

Choose a reason for hiding this comment

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

Both styles seem ok, but why is this (one annotation with an array) seems better to you? It brings some syntactic noise (braces).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's just that I like it better, I suggest leaving it as it is.

@rpuch
Copy link
Contributor

rpuch commented Nov 22, 2022

Also, I wonder, why LongOperationAsyncExecutor launches a fresh thread per async operation instead of using a single-thread executor to run both main tasks and afterAsyncCompletion tasks. This is not in the scope of this PR, I'm just curious.

* @param cause The cause.
*/
public StorageClosedException(String message, Throwable cause) {
super(message, cause);
Copy link
Contributor

Choose a reason for hiding this comment

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

Where's the error code? :)
I guess we should make it soon

Copy link
Contributor Author

Choose a reason for hiding this comment

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

coming soon

Comment on lines 63 to 66
* <p>This method will do nothing if there is no partition by ID, when trying to call methods to read or write (as well as all previous
* open cursors) for {@link MvPartitionStorage}, {@link HashIndexStorage} and {@link SortedIndexStorage}, {@link StorageClosedException}
* will be thrown.
*
Copy link
Contributor

Choose a reason for hiding this comment

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

This description is close to impossible to understand, please use re-structure your text and expand it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What exactly is not clear?

Copy link
Contributor

Choose a reason for hiding this comment

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

The grammatical structure is very convoluted. Maybe something like

This method will ...  if:
 - blah
 - foo
 - bar

will be easier to read

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deleted this comment.

Comment on lines +521 to +522
assertThrows(StorageClosedException.class, storage::lastAppliedIndex);
assertThrows(StorageClosedException.class, storage::lastAppliedTerm);
Copy link
Contributor

Choose a reason for hiding this comment

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

These two don't have to throw exceptions, but ok

return;
}

if (filePageStore.isMarkedToDestroy()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

These checks (whether it's cancelled, whether the store is marked for destroy) are always done together in this method. How about uniting them in a single method like shouldNotProceedWith(FilePageStore) and call it in all places in this method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But for what?

Copy link
Contributor

Choose a reason for hiding this comment

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

To make sure that we always do these checks together in this method. After modifications someone might accidentally add just one check instead of 2.

Copy link
Contributor Author

@tkalkirill tkalkirill Nov 28, 2022

Choose a reason for hiding this comment

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

I think we do not need a separate method for two slightly different checks, this complicates the code a bit.


CompletableFuture<Void> previousFuture = destroyFutureByPartitionId.put(partitionId, new CompletableFuture<>());

assert previousFuture == null : "Previous destruction of the partition has not completed: " + partitionId;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just return the old future?

Copy link
Contributor

Choose a reason for hiding this comment

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

What's up with the future anyway? No one uses it, what's the point?

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 don’t understand why return the current future while no one uses it, but later they will be on the assignment recalculation.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, didn't notice the other usage

Copy link
Contributor

@rpuch rpuch left a comment

Choose a reason for hiding this comment

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

.

@tkalkirill tkalkirill merged commit 0dee583 into apache:main Nov 28, 2022
@tkalkirill tkalkirill deleted the ignite-17132 branch November 28, 2022 10:42
lowka pushed a commit to gridgain/apache-ignite-3 that referenced this pull request Mar 18, 2023
lowka pushed a commit to gridgain/apache-ignite-3 that referenced this pull request Apr 19, 2023
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.

3 participants