cleanup various comparators

This commit is contained in:
Luck 2018-05-31 23:41:37 +01:00
parent 07b003c77a
commit bcb4e5ca64
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
4 changed files with 68 additions and 61 deletions

View File

@ -53,22 +53,19 @@ public class ContextSetComparator implements Comparator<ImmutableContextSet> {
return 0; return 0;
} }
boolean o1ServerSpecific = o1.containsKey(Contexts.SERVER_KEY); int result = Boolean.compare(o1.containsKey(Contexts.SERVER_KEY), o2.containsKey(Contexts.SERVER_KEY));
boolean o2ServerSpecific = o2.containsKey(Contexts.SERVER_KEY); if (result != 0) {
if (o1ServerSpecific != o2ServerSpecific) { return result;
return o1ServerSpecific ? 1 : -1;
} }
boolean o1WorldSpecific = o1.containsKey(Contexts.WORLD_KEY); result = Boolean.compare(o1.containsKey(Contexts.WORLD_KEY), o2.containsKey(Contexts.WORLD_KEY));
boolean o2WorldSpecific = o2.containsKey(Contexts.WORLD_KEY); if (result != 0) {
if (o1WorldSpecific != o2WorldSpecific) { return result;
return o1WorldSpecific ? 1 : -1;
} }
int o1Size = o1.size(); result = Integer.compare(o1.size(), o2.size());
int o2Size = o2.size(); if (result != 0) {
if (o1Size != o2Size) { return result;
return o1Size > o2Size ? 1 : -1;
} }
// we *have* to maintain transitivity in this comparator. this may be expensive, but it's necessary, as this // we *have* to maintain transitivity in this comparator. this may be expensive, but it's necessary, as this
@ -76,48 +73,36 @@ public class ContextSetComparator implements Comparator<ImmutableContextSet> {
// in order to have consistent ordering, we have to compare the content of the context sets by ordering the // in order to have consistent ordering, we have to compare the content of the context sets by ordering the
// elements and then comparing which set is greater. // elements and then comparing which set is greater.
List<Map.Entry<String, String>> o1Map = new ArrayList<>(o1.toSet()); List<Map.Entry<String, String>> o1Entries = new ArrayList<>(o1.toSet());
List<Map.Entry<String, String>> o2Map = new ArrayList<>(o2.toSet()); List<Map.Entry<String, String>> o2Entries = new ArrayList<>(o2.toSet());
o1Map.sort(STRING_ENTRY_COMPARATOR); o1Entries.sort(STRING_ENTRY_COMPARATOR);
o2Map.sort(STRING_ENTRY_COMPARATOR); o2Entries.sort(STRING_ENTRY_COMPARATOR);
int o1MapSize = o1Map.size();
int o2MapSize = o2Map.size();
if (o1MapSize != o2MapSize) {
return o1MapSize > o2MapSize ? 1 : -1;
}
// size is definitely the same // size is definitely the same
Iterator<Map.Entry<String, String>> it1 = o1Map.iterator(); Iterator<Map.Entry<String, String>> it1 = o1Entries.iterator();
Iterator<Map.Entry<String, String>> it2 = o2Map.iterator(); Iterator<Map.Entry<String, String>> it2 = o2Entries.iterator();
while (it1.hasNext()) { while (it1.hasNext()) {
Map.Entry<String, String> ent1 = it1.next(); Map.Entry<String, String> ent1 = it1.next();
Map.Entry<String, String> ent2 = it2.next(); Map.Entry<String, String> ent2 = it2.next();
// compare these values. int ret = STRING_ENTRY_COMPARATOR.compare(ent1, ent2);
//noinspection StringEquality - strings are intern'd if (ret != 0) {
if (ent1.getKey() == ent2.getKey() && ent1.getValue() == ent2.getValue()) { return ret;
// identical entries. just move on }
continue;
} }
// these entries are at the same position in the ordered sets. throw new AssertionError("sets are equal? " + o1 + " - " + o2);
// if ent1 is "greater" than ent2, then at this first position, o1 has a "greater" entry, and can therefore be considered
// a greater set, and vice versa
return STRING_ENTRY_COMPARATOR.compare(ent1, ent2);
} }
// shouldn't ever reach this point. @SuppressWarnings("StringEquality")
private static final Comparator<String> FAST_STRING_COMPARATOR = (o1, o2) -> o1 == o2 ? 0 : o1.compareTo(o2);
private static final Comparator<Map.Entry<String, String>> STRING_ENTRY_COMPARATOR = (o1, o2) -> {
if (o1 == o2) {
return 0; return 0;
} }
private static final Comparator<String> FAST_STRING_COMPARATOR = (o1, o2) -> {
//noinspection StringEquality
return o1 == o2 ? 0 : o1.compareTo(o2);
};
private static final Comparator<Map.Entry<String, String>> STRING_ENTRY_COMPARATOR = (o1, o2) -> {
int ret = FAST_STRING_COMPARATOR.compare(o1.getKey(), o2.getKey()); int ret = FAST_STRING_COMPARATOR.compare(o1.getKey(), o2.getKey());
if (ret != 0) { if (ret != 0) {
return ret; return ret;

View File

@ -53,21 +53,22 @@ public class InheritanceComparator implements Comparator<Group> {
@Override @Override
public int compare(Group o1, Group o2) { public int compare(Group o1, Group o2) {
int ret = Integer.compare(o1.getWeight().orElse(0), o2.getWeight().orElse(0)); int result = Integer.compare(o1.getWeight().orElse(0), o2.getWeight().orElse(0));
if (ret != 0) { if (result != 0) {
// note negated value - we want higher weights first! // note negated value - we want higher weights first!
return -ret; return -result;
} }
// failing differing group weights, check if one of the groups is a primary group // failing differing group weights, check if one of the groups is a primary group
if (this.origin != null) { if (this.origin != null) {
boolean o1Primary = o1.getName().equalsIgnoreCase(this.origin.getPrimaryGroup().getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME)); // note negative
boolean o2Primary = o2.getName().equalsIgnoreCase(this.origin.getPrimaryGroup().getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME)); result = -Boolean.compare(
o1.getName().equalsIgnoreCase(this.origin.getPrimaryGroup().getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME)),
o2.getName().equalsIgnoreCase(this.origin.getPrimaryGroup().getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME))
);
// one of them is a primary group, and therefore has priority if (result != 0) {
if (o1Primary != o2Primary) { return result;
// we want the primary group to come first
return o1Primary ? -1 : 1;
} }
} }

View File

@ -48,22 +48,42 @@ public class NodeComparator implements Comparator<Node> {
return 0; return 0;
} }
if (o1.isTemporary() != o2.isTemporary()) { int result = Boolean.compare(o1.isOverride(), o2.isOverride());
return o1.isTemporary() ? 1 : -1; if (result != 0) {
return result;
} }
if (o1.isWildcard() != o2.isWildcard()) { result = Boolean.compare(o1.isTemporary(), o2.isTemporary());
return o1.isWildcard() ? 1 : -1; if (result != 0) {
return result;
}
result = Boolean.compare(o1.isWildcard(), o2.isWildcard());
if (result != 0) {
return result;
} }
if (o1.isTemporary()) { if (o1.isTemporary()) {
return o1.getSecondsTilExpiry() < o2.getSecondsTilExpiry() ? 1 : -1; // note vvv
result = -Long.compare(o1.getSecondsTilExpiry(), o2.getSecondsTilExpiry());
if (result != 0) {
return result;
}
} }
if (o1.isWildcard()) { if (o1.isWildcard()) {
return o1.getWildcardLevel() > o2.getWildcardLevel() ? 1 : -1; result = Integer.compare(o1.getWildcardLevel(), o2.getWildcardLevel());
if (result != 0) {
return result;
}
} }
return o1.getPermission().compareTo(o2.getPermission()) > 0 ? -1 : 1; // note vvv
result = -o1.getPermission().compareTo(o2.getPermission());
if (result != 0) {
return result;
}
throw new AssertionError("nodes are equal? " + o1 + " - " + o2);
} }
} }

View File

@ -54,17 +54,18 @@ public class NodeWithContextComparator implements Comparator<Node> {
return 0; return 0;
} }
if (o1.isOverride() != o2.isOverride()) { int result = Boolean.compare(o1.isOverride(), o2.isOverride());
return o1.isOverride() ? 1 : -1; if (result != 0) {
return result;
} }
int i = ContextSetComparator.normal().compare( result = ContextSetComparator.normal().compare(
o1.getFullContexts().makeImmutable(), o1.getFullContexts().makeImmutable(),
o2.getFullContexts().makeImmutable() o2.getFullContexts().makeImmutable()
); );
if (i != 0) { if (result != 0) {
return i; return result;
} }
return NodeComparator.normal().compare(o1, o2); return NodeComparator.normal().compare(o1, o2);