Fixed checkStyle and ErrorProne warns
This commit is contained in:
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package io.moquette.spi.impl.subscriptions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
class CNode {
|
||||
|
||||
@@ -41,7 +38,7 @@ class CNode {
|
||||
boolean anyChildrenMatch(Token token) {
|
||||
for (INode iNode : children) {
|
||||
final CNode child = iNode.mainNode();
|
||||
if (child.equals(token)) {
|
||||
if (child.equalsToken(token)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -55,15 +52,20 @@ class CNode {
|
||||
INode childOf(Token token) {
|
||||
for (INode iNode : children) {
|
||||
final CNode child = iNode.mainNode();
|
||||
if (child.equals(token)) {
|
||||
if (child.equalsToken(token)) {
|
||||
return iNode;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Asked for a token that doesn't exists in any child [" + token + "]");
|
||||
}
|
||||
|
||||
private boolean equals(Token token) {
|
||||
return this.token != null && this.token.equals(token);
|
||||
private boolean equalsToken(Token token) {
|
||||
return token != null && this.token != null && this.token.equals(token);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(token);
|
||||
}
|
||||
|
||||
CNode copy() {
|
||||
|
||||
+10
-75
@@ -17,12 +17,10 @@ package io.moquette.spi.impl.subscriptions;
|
||||
|
||||
import io.moquette.spi.ClientSession;
|
||||
import io.moquette.spi.impl.SessionsRepository;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
@@ -36,66 +34,18 @@ public class CTrieSubscriptionDirectory implements ISubscriptionsDirectory {
|
||||
INode root;
|
||||
private volatile SessionsRepository sessionsRepository;
|
||||
|
||||
private interface IVisitor<T> {
|
||||
interface IVisitor<T> {
|
||||
|
||||
void visit(CNode node, int deep);
|
||||
|
||||
T getResult();
|
||||
}
|
||||
|
||||
private class DumpTreeVisitor implements IVisitor<String> {
|
||||
|
||||
String s = "";
|
||||
|
||||
@Override
|
||||
public void visit(CNode node, int deep) {
|
||||
String indentTabs = indentTabs(deep);
|
||||
s += indentTabs + (node.token == null ? "''" : node.token.toString()) + prettySubscriptions(node) + "\n";
|
||||
}
|
||||
|
||||
private String prettySubscriptions(CNode node) {
|
||||
if (node instanceof TNode) {
|
||||
return "TNode";
|
||||
}
|
||||
if (node.subscriptions.isEmpty()) {
|
||||
return StringUtil.EMPTY_STRING;
|
||||
}
|
||||
StringBuilder subScriptionsStr = new StringBuilder(" ~~[");
|
||||
int counter = 0;
|
||||
for (Subscription couple : node.subscriptions) {
|
||||
subScriptionsStr
|
||||
.append("{filter=").append(couple.topicFilter).append(", ")
|
||||
.append("client='").append(couple.clientId).append("'}");
|
||||
counter++;
|
||||
if (counter < node.subscriptions.size()) {
|
||||
subScriptionsStr.append(";");
|
||||
}
|
||||
}
|
||||
return subScriptionsStr.append("]").toString();
|
||||
}
|
||||
|
||||
private String indentTabs(int deep) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
if (deep > 0) {
|
||||
s.append(" ");
|
||||
for (int i = 0; i < deep - 1; i++) {
|
||||
s.append("| ");
|
||||
}
|
||||
s.append("|-");
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResult() {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
private enum Action {
|
||||
OK, REPEAT
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(SessionsRepository sessionsRepository) {
|
||||
LOG.info("Initializing CTrie");
|
||||
final CNode mainNode = new CNode();
|
||||
@@ -134,13 +84,11 @@ public class CTrieSubscriptionDirectory implements ISubscriptionsDirectory {
|
||||
return Optional.of(inode.mainNode());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Subscription> matches(Topic topic) {
|
||||
return new ArrayList<>(match(topic));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a topic string return the clients subscriptions that matches it. Topic string can't
|
||||
* contain character # and + because they are reserved to listeners subscriptions, and not topic
|
||||
@@ -177,7 +125,7 @@ public class CTrieSubscriptionDirectory implements ISubscriptionsDirectory {
|
||||
|
||||
Set<Subscription> recursiveMatch(Topic topic, INode inode) {
|
||||
CNode cnode = inode.mainNode();
|
||||
if (cnode.token == Token.MULTI) {
|
||||
if (Token.MULTI.equals(cnode.token)) {
|
||||
return cnode.subscriptions;
|
||||
}
|
||||
if (topic.isEmpty()) {
|
||||
@@ -187,10 +135,10 @@ public class CTrieSubscriptionDirectory implements ISubscriptionsDirectory {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
final Token token = topic.headToken();
|
||||
if (!(cnode.token == Token.SINGLE || cnode.token.equals(token) || cnode.token == ROOT)) {
|
||||
if (!(Token.SINGLE.equals(cnode.token) || cnode.token.equals(token) || ROOT.equals(cnode.token))) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Topic remainingTopic = (cnode.token == ROOT) ? topic : topic.exceptHeadToken();
|
||||
Topic remainingTopic = (ROOT.equals(cnode.token)) ? topic : topic.exceptHeadToken();
|
||||
Set<Subscription> subscriptions = new HashSet<>();
|
||||
if (remainingTopic.isEmpty()) {
|
||||
subscriptions.addAll(cnode.subscriptions);
|
||||
@@ -219,6 +167,7 @@ public class CTrieSubscriptionDirectory implements ISubscriptionsDirectory {
|
||||
return iParent.compareAndSet(iParent.mainNode(), updatedCnode) ? Action.OK : Action.REPEAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Subscription newSubscription) {
|
||||
Action res;
|
||||
do {
|
||||
@@ -282,14 +231,13 @@ public class CTrieSubscriptionDirectory implements ISubscriptionsDirectory {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Removes subscription from CTrie, adds TNode when the last client unsubscribes, then calls for cleanTomb in a
|
||||
* seperate atomic CAS operation.
|
||||
*
|
||||
* separate atomic CAS operation.
|
||||
*
|
||||
* @param topic
|
||||
* @param clientID
|
||||
*/
|
||||
@Override
|
||||
public void removeSubscription(Topic topic, String clientID) {
|
||||
Action res;
|
||||
do {
|
||||
@@ -329,27 +277,14 @@ public class CTrieSubscriptionDirectory implements ISubscriptionsDirectory {
|
||||
}
|
||||
}
|
||||
|
||||
private class SubscriptionCounterVisitor implements IVisitor<Integer> {
|
||||
|
||||
AtomicInteger accumulator = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public void visit(CNode node, int deep) {
|
||||
accumulator.addAndGet(node.subscriptions.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getResult() {
|
||||
return accumulator.get();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
SubscriptionCounterVisitor visitor = new SubscriptionCounterVisitor();
|
||||
dfsVisit(this.root, visitor, 0);
|
||||
return visitor.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dumpTree() {
|
||||
DumpTreeVisitor visitor = new DumpTreeVisitor();
|
||||
dfsVisit(this.root, visitor, 0);
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2017 The original author or authors
|
||||
* ------------------------------------------------------
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Apache License v2.0 which accompanies this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* The Apache License v2.0 is available at
|
||||
* http://www.opensource.org/licenses/apache2.0.php
|
||||
*
|
||||
* You may elect to redistribute this code under either of these licenses.
|
||||
*/
|
||||
package io.moquette.spi.impl.subscriptions;
|
||||
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
class DumpTreeVisitor implements CTrieSubscriptionDirectory.IVisitor<String> {
|
||||
|
||||
String s = "";
|
||||
|
||||
@Override
|
||||
public void visit(CNode node, int deep) {
|
||||
String indentTabs = indentTabs(deep);
|
||||
s += indentTabs + (node.token == null ? "''" : node.token.toString()) + prettySubscriptions(node) + "\n";
|
||||
}
|
||||
|
||||
private String prettySubscriptions(CNode node) {
|
||||
if (node instanceof TNode) {
|
||||
return "TNode";
|
||||
}
|
||||
if (node.subscriptions.isEmpty()) {
|
||||
return StringUtil.EMPTY_STRING;
|
||||
}
|
||||
StringBuilder subScriptionsStr = new StringBuilder(" ~~[");
|
||||
int counter = 0;
|
||||
for (Subscription couple : node.subscriptions) {
|
||||
subScriptionsStr
|
||||
.append("{filter=").append(couple.topicFilter).append(", ")
|
||||
.append("client='").append(couple.clientId).append("'}");
|
||||
counter++;
|
||||
if (counter < node.subscriptions.size()) {
|
||||
subScriptionsStr.append(";");
|
||||
}
|
||||
}
|
||||
return subScriptionsStr.append("]").toString();
|
||||
}
|
||||
|
||||
private String indentTabs(int deep) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
if (deep > 0) {
|
||||
s.append(" ");
|
||||
for (int i = 0; i < deep - 1; i++) {
|
||||
s.append("| ");
|
||||
}
|
||||
s.append("|-");
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResult() {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2017 The original author or authors
|
||||
* ------------------------------------------------------
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Apache License v2.0 which accompanies this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* The Apache License v2.0 is available at
|
||||
* http://www.opensource.org/licenses/apache2.0.php
|
||||
*
|
||||
* You may elect to redistribute this code under either of these licenses.
|
||||
*/
|
||||
package io.moquette.spi.impl.subscriptions;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
class SubscriptionCounterVisitor implements CTrieSubscriptionDirectory.IVisitor<Integer> {
|
||||
|
||||
private AtomicInteger accumulator = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public void visit(CNode node, int deep) {
|
||||
accumulator.addAndGet(node.subscriptions.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getResult() {
|
||||
return accumulator.get();
|
||||
}
|
||||
}
|
||||
@@ -35,11 +35,11 @@ public class Token {
|
||||
}
|
||||
|
||||
protected boolean match(Token t) {
|
||||
if (t == MULTI || t == SINGLE) {
|
||||
if (MULTI.equals(t) || SINGLE.equals(t)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this == MULTI || this == SINGLE) {
|
||||
if (MULTI.equals(this) || SINGLE.equals(this)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ public class Topic implements Serializable {
|
||||
int i = 0;
|
||||
for (; i < subscriptionTokens.size(); i++) {
|
||||
Token subToken = subscriptionTokens.get(i);
|
||||
if (subToken != Token.MULTI && subToken != Token.SINGLE) {
|
||||
if (!Token.MULTI.equals(subToken) && !Token.SINGLE.equals(subToken)) {
|
||||
if (i >= msgTokens.size()) {
|
||||
return false;
|
||||
}
|
||||
@@ -174,18 +174,14 @@ public class Topic implements Serializable {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (subToken == Token.MULTI) {
|
||||
if (Token.MULTI.equals(subToken)) {
|
||||
return true;
|
||||
}
|
||||
if (subToken == Token.SINGLE) {
|
||||
// skip a step forward
|
||||
}
|
||||
// if (Token.SINGLE.equals(subToken)) {
|
||||
// // skip a step forward
|
||||
// }
|
||||
}
|
||||
}
|
||||
// if last token was a SINGLE then treat it as an empty
|
||||
// if (subToken == Token.SINGLE && (i - msgTokens.size() == 1)) {
|
||||
// i--;
|
||||
// }
|
||||
return i == msgTokens.size();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user