Skip to content

Commit b56747e

Browse files
committed
Improve performance of Permission or/and logic
Signed-off-by: Irmo van den Berge <[email protected]>
1 parent b1e55c5 commit b56747e

File tree

4 files changed

+99
-16
lines changed

4 files changed

+99
-16
lines changed

cloud-core/src/main/java/cloud/commandframework/CommandTree.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import io.leangen.geantyref.GenericTypeReflector;
4545
import io.leangen.geantyref.TypeToken;
4646
import java.util.ArrayList;
47-
import java.util.Arrays;
4847
import java.util.Collection;
4948
import java.util.Collections;
5049
import java.util.Comparator;
@@ -878,7 +877,7 @@ public void verifyAndRegister() {
878877

879878
CommandPermission permission;
880879
if (existingPermission != null) {
881-
permission = OrPermission.of(Arrays.asList(commandPermission, existingPermission));
880+
permission = commandPermission.or(existingPermission);
882881
} else {
883882
permission = commandPermission;
884883
}
@@ -893,7 +892,7 @@ public void verifyAndRegister() {
893892
.getSetting(CommandManager.ManagerSettings.ENFORCE_INTERMEDIARY_PERMISSIONS)) {
894893
permission = command.getCommandPermission();
895894
} else {
896-
permission = OrPermission.of(Arrays.asList(permission, command.getCommandPermission()));
895+
permission = permission.or(command.getCommandPermission());
897896
}
898897
}
899898

cloud-core/src/main/java/cloud/commandframework/permission/AndPermission.java

+41
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import org.apiguardian.api.API;
3333
import org.checkerframework.checker.nullness.qual.NonNull;
3434

35+
import static java.util.Objects.requireNonNull;
36+
3537
/**
3638
* Accepts if every single permission is accepted.
3739
*/
@@ -67,6 +69,34 @@ public final class AndPermission implements CommandPermission {
6769
return this.permissions;
6870
}
6971

72+
@Override
73+
public @NonNull CommandPermission and(final @NonNull CommandPermission other) {
74+
requireNonNull(other, "other");
75+
76+
if (this.permissions.contains(other)) {
77+
return this;
78+
} else {
79+
final Set<CommandPermission> objects = new HashSet<>(this.permissions);
80+
addToSet(objects, other);
81+
return new AndPermission(objects);
82+
}
83+
}
84+
85+
@Override
86+
public @NonNull CommandPermission and(final @NonNull CommandPermission @NonNull... other) {
87+
if (other.length == 0) {
88+
return this;
89+
} else if (other.length == 1) {
90+
return this.and(other[0]);
91+
} else {
92+
final Set<CommandPermission> objects = new HashSet<>(this.permissions);
93+
for (final CommandPermission permission : other) {
94+
addToSet(objects, permission);
95+
}
96+
return new AndPermission(objects);
97+
}
98+
}
99+
70100
@Override
71101
public String toString() {
72102
final StringBuilder stringBuilder = new StringBuilder();
@@ -97,4 +127,15 @@ public boolean equals(final Object o) {
97127
public int hashCode() {
98128
return Objects.hash(this.getPermissions());
99129
}
130+
131+
private static void addToSet(
132+
@NonNull final Set<CommandPermission> objects,
133+
@NonNull final CommandPermission permission
134+
) {
135+
if (permission instanceof AndPermission) {
136+
objects.addAll(permission.getPermissions());
137+
} else {
138+
objects.add(permission);
139+
}
140+
}
100141
}

cloud-core/src/main/java/cloud/commandframework/permission/CommandPermission.java

+14-8
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,13 @@ public interface CommandPermission {
6363
@API(status = API.Status.STABLE, since = "1.4.0")
6464
default @NonNull CommandPermission or(final @NonNull CommandPermission other) {
6565
requireNonNull(other, "other");
66-
final Set<CommandPermission> permission = new HashSet<>(2);
67-
permission.add(this);
68-
permission.add(other);
69-
return OrPermission.of(permission);
66+
67+
// Performance optimization
68+
if (other instanceof OrPermission) {
69+
return other.or(this);
70+
}
71+
72+
return OrPermission.of(Arrays.asList(this, other));
7073
}
7174

7275
/**
@@ -95,10 +98,13 @@ public interface CommandPermission {
9598
@API(status = API.Status.STABLE, since = "1.4.0")
9699
default @NonNull CommandPermission and(final @NonNull CommandPermission other) {
97100
requireNonNull(other, "other");
98-
final Set<CommandPermission> permission = new HashSet<>(2);
99-
permission.add(this);
100-
permission.add(other);
101-
return AndPermission.of(permission);
101+
102+
// Performance optimization
103+
if (other instanceof AndPermission) {
104+
return other.and(this);
105+
}
106+
107+
return AndPermission.of(Arrays.asList(this, other));
102108
}
103109

104110
/**

cloud-core/src/main/java/cloud/commandframework/permission/OrPermission.java

+42-5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import org.apiguardian.api.API;
3333
import org.checkerframework.checker.nullness.qual.NonNull;
3434

35+
import static java.util.Objects.requireNonNull;
36+
3537
/**
3638
* Accepts as long as at least one of the permissions is accepted
3739
*/
@@ -53,11 +55,7 @@ public final class OrPermission implements CommandPermission {
5355
public static @NonNull CommandPermission of(final @NonNull Collection<CommandPermission> permissions) {
5456
final Set<CommandPermission> objects = new HashSet<>();
5557
for (final CommandPermission permission : permissions) {
56-
if (permission instanceof OrPermission) {
57-
objects.addAll(permission.getPermissions());
58-
} else {
59-
objects.add(permission);
60-
}
58+
addToSet(objects, permission);
6159
}
6260
return new OrPermission(objects);
6361
}
@@ -67,6 +65,34 @@ public final class OrPermission implements CommandPermission {
6765
return this.permissions;
6866
}
6967

68+
@Override
69+
public @NonNull CommandPermission or(final @NonNull CommandPermission other) {
70+
requireNonNull(other, "other");
71+
72+
if (this.permissions.contains(other)) {
73+
return this;
74+
} else {
75+
final Set<CommandPermission> objects = new HashSet<>(this.permissions);
76+
addToSet(objects, other);
77+
return new OrPermission(objects);
78+
}
79+
}
80+
81+
@Override
82+
public @NonNull CommandPermission or(final @NonNull CommandPermission @NonNull... other) {
83+
if (other.length == 0) {
84+
return this;
85+
} else if (other.length == 1) {
86+
return this.or(other[0]);
87+
} else {
88+
final Set<CommandPermission> objects = new HashSet<>(this.permissions);
89+
for (final CommandPermission permission : other) {
90+
addToSet(objects, permission);
91+
}
92+
return new OrPermission(objects);
93+
}
94+
}
95+
7096
@Override
7197
public String toString() {
7298
final StringBuilder stringBuilder = new StringBuilder();
@@ -97,4 +123,15 @@ public boolean equals(final Object o) {
97123
public int hashCode() {
98124
return Objects.hash(this.getPermissions());
99125
}
126+
127+
private static void addToSet(
128+
@NonNull final Set<CommandPermission> objects,
129+
@NonNull final CommandPermission permission
130+
) {
131+
if (permission instanceof OrPermission) {
132+
objects.addAll(permission.getPermissions());
133+
} else {
134+
objects.add(permission);
135+
}
136+
}
100137
}

0 commit comments

Comments
 (0)