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

User Storage System #886

Closed
wants to merge 5 commits into from
Closed

Conversation

ShadowOfHeaven-Me
Copy link
Contributor

@ShadowOfHeaven-Me ShadowOfHeaven-Me commented Jul 11, 2024

Added a system that allows developers to associate a certain value with the PacketEvent User class, making it easier and faster to identify the user on any PacketEvent at all times. MethodHandle was used instead of VarHandle, as I found it to be slightly faster, with, and without warmup calls. Here's the benchmark with 1000 warmup calls and 10000 evaluation calls: https://paste.md-5.net/exedugixog.cpp

Added a system that allows developers to associate a certain value with the PacketEvent User class, making it easier and faster to identify the user on any PacketEvent at all times.
MethodHandle was used instead of VarHandle, as I found it to be slightly faster, with, and without warmup calls.
Here's the benchmark with 1000 warmup calls and 10000 evaluation calls: https://paste.md-5.net/
Copy link
Collaborator

@booky10 booky10 left a comment

Choose a reason for hiding this comment

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

aside from the comments, your javadoc formatting is a bit inconsistent - but that's just a minor nitpick


private Object get0(int index) {
if (index >= data.length) {
this.regrow();
Copy link
Collaborator

Choose a reason for hiding this comment

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

why are you growing here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On any data access, be it write or read, if the class that creates the identifier is initialized later on the initial data size won't be enough. The grow happens only when we're implicitly told that this has happened. It's also safe to do this, since the id is provided internally only

//It was found to be slightly faster than VarHandles with excessive amount of calls
private static final MethodHandle setElement = MethodHandles.arrayElementSetter(Object[].class);//array, index, value
private static final MethodHandle getElement = MethodHandles.arrayElementGetter(Object[].class);//array, index
private static final Map<Object, Integer> pluginToId = new ConcurrentHashMap<>(2);
Copy link
Collaborator

Choose a reason for hiding this comment

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

if the keys here are plugin instances, this should definetely be a WeakHashMap
otherwhise this will cause memory leaks when a plugin gets disabled or unloaded

because of this you will need to do manual synchronization, see some coment below for mor info

Copy link
Collaborator

Choose a reason for hiding this comment

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

im also not sure if its a good idea to key these ids by "plugin" instance - in my opinion it makes more sense to key the id map by the class of the identifier type, so you can create multiple keys per plugin

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if the keys here are plugin instances, this should definetely be a WeakHashMap otherwhise this will cause memory leaks when a plugin gets disabled or unloaded

because of this you will need to do manual synchronization, see some coment below for mor info

Guava's MapMaker is the best solution then

Copy link
Contributor Author

Choose a reason for hiding this comment

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

im also not sure if its a good idea to key these ids by "plugin" instance - in my opinion it makes more sense to key the id map by the class of the identifier type, so you can create multiple keys per plugin

The main idea behind this is that you create one key, which holds one custom object, that can encapsulate all the other values associated. Otherwise this could lead to memory being wasted

@@ -0,0 +1,26 @@
package com.github.retrooper.packetevents.protocol.player.storage;

public final class StorageValueId extends StorageIdBase {
Copy link
Collaborator

Choose a reason for hiding this comment

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

is there any reason for this to exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can be useful for example if a developer wants to store different types of data throught different parts of joining, where the automatic casting would be only an obstacle

@ShadowOfHeaven-Me
Copy link
Contributor Author

This won't be very useful unless only 1 instance of PE is used. Channel attributes are more useful for that.
Even tho this storage system is about ~15x times faster compared to any Map after JIT optimizations, it still shouldn't be a bottleneck.
Closed - unnecessary

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