Merge pull request #100 from k9999dot/bugfix

bugfix: 修复删除敏感词中可能出现的并发问题
This commit is contained in:
老马啸西风
2025-02-02 15:26:59 +08:00
committed by GitHub
5 changed files with 70 additions and 58 deletions

View File

@@ -22,10 +22,10 @@ public interface IWordData extends ISensitiveWordDestroy {
/** /**
* 删除敏感词 * 删除敏感词
* @param word 单词 * @param collection 单词
* @since 0.19.0 * @since 0.19.0
*/ */
void removeWord(String word); void removeWord(Collection<String> collection);
/** /**
* 新增敏感词 * 新增敏感词

View File

@@ -639,9 +639,7 @@ public class SensitiveWordBs implements ISensitiveWordDestroy {
// 主要原因是二者没有保持一致,初始化的数据和插入的数据没有做相同的格式化 // 主要原因是二者没有保持一致,初始化的数据和插入的数据没有做相同的格式化
List<String> formatList = InnerWordFormatUtils.formatWordList(collection, context); List<String> formatList = InnerWordFormatUtils.formatWordList(collection, context);
for(String word : formatList) { this.wordData.removeWord(formatList);
this.wordData.removeWord(word);
}
} }
/** /**
@@ -698,9 +696,8 @@ public class SensitiveWordBs implements ISensitiveWordDestroy {
// 主要原因是二者没有保持一致,初始化的数据和插入的数据没有做相同的格式化 // 主要原因是二者没有保持一致,初始化的数据和插入的数据没有做相同的格式化
List<String> formatList = InnerWordFormatUtils.formatWordList(collection, context); List<String> formatList = InnerWordFormatUtils.formatWordList(collection, context);
for(String word : formatList) { this.wordDataAllow.removeWord(formatList);
this.wordDataAllow.removeWord(word);
}
} }
/** /**
* 新增敏感词白名单 * 新增敏感词白名单

View File

@@ -1,6 +1,5 @@
package com.github.houbb.sensitive.word.support.data; package com.github.houbb.sensitive.word.support.data;
import com.github.houbb.heaven.util.lang.StringUtil;
import com.github.houbb.heaven.util.util.CollectionUtil; import com.github.houbb.heaven.util.util.CollectionUtil;
import com.github.houbb.sensitive.word.api.IWordData; import com.github.houbb.sensitive.word.api.IWordData;
import com.github.houbb.sensitive.word.api.context.InnerSensitiveWordContext; import com.github.houbb.sensitive.word.api.context.InnerSensitiveWordContext;
@@ -31,9 +30,9 @@ public abstract class AbstractWordData implements IWordData {
/** /**
* 删除敏感词 * 删除敏感词
* @param word 敏感词 * @param collection
*/ */
protected abstract void doRemoveWord(String word); protected abstract void doRemoveWord(Collection<String> collection);
/** /**
* 新增敏感词 * 新增敏感词
@@ -49,12 +48,12 @@ public abstract class AbstractWordData implements IWordData {
} }
@Override @Override
public void removeWord(String word) { public void removeWord(Collection<String> collection) {
if(StringUtil.isEmpty(word)) { if(CollectionUtil.isEmpty(collection)) {
return; return;
} }
doRemoveWord(word); doRemoveWord(collection);
} }
@Override @Override

View File

@@ -89,7 +89,7 @@ public class WordDataHashMap extends AbstractWordData {
} }
@Override @Override
protected void doRemoveWord(String word) { protected void doRemoveWord(Collection<String> collection) {
} }

View File

@@ -4,7 +4,6 @@ import com.github.houbb.heaven.annotation.ThreadSafe;
import com.github.houbb.heaven.util.lang.ObjectUtil; import com.github.houbb.heaven.util.lang.ObjectUtil;
import com.github.houbb.heaven.util.lang.StringUtil; import com.github.houbb.heaven.util.lang.StringUtil;
import com.github.houbb.sensitive.word.api.IWordContext; import com.github.houbb.sensitive.word.api.IWordContext;
import com.github.houbb.sensitive.word.api.IWordData;
import com.github.houbb.sensitive.word.api.context.InnerSensitiveWordContext; import com.github.houbb.sensitive.word.api.context.InnerSensitiveWordContext;
import com.github.houbb.sensitive.word.constant.enums.WordContainsTypeEnum; import com.github.houbb.sensitive.word.constant.enums.WordContainsTypeEnum;
@@ -84,49 +83,7 @@ public class WordDataTree extends AbstractWordData {
this.root = newRoot; this.root = newRoot;
} }
@Override
protected void doRemoveWord(String word) {
WordDataTreeNode tempNode = root;
//需要删除的
Map<Character, WordDataTreeNode> map = new HashMap<>();
char[] chars = word.toCharArray();
int length = chars.length;
for (int i = 0; i < length; i++) {
//不存在第一个词
WordDataTreeNode subNode = tempNode.getSubNode(chars[i]);
if (subNode == null) {
return;
}
if (i == (length - 1)) {
//尾字符判断是否结束
if (!subNode.end()) {
return;
}
if (subNode.getNodeSize() > 0) {
//尾字符下还存在字符,即标识即可
subNode.end(false);
return;
}
}
if (subNode.end()) {
map.clear();
}
map.put(chars[i], tempNode);
tempNode = subNode;
}
for (Map.Entry<Character, WordDataTreeNode> entry : map.entrySet()) {
WordDataTreeNode value = entry.getValue();
//节点只有一个就置空
if (value.getNodeSize() == 1) {
value.clearNode();
return;
}
//多个就删除
value.removeNode(entry.getKey());
}
}
/** /**
* 新增敏感词 * 新增敏感词
@@ -143,6 +100,21 @@ public class WordDataTree extends AbstractWordData {
} }
} }
@Override
protected synchronized void doRemoveWord(Collection<String> collection) {
for (String word : collection) {
if (StringUtil.isEmpty(word)) {
continue;
}
removeWord(this.root, word);
}
}
/** /**
* 获取当前的 Map * 获取当前的 Map
* @param nowNode 当前节点 * @param nowNode 当前节点
@@ -211,4 +183,48 @@ public class WordDataTree extends AbstractWordData {
tempNode.end(true); tempNode.end(true);
} }
private void removeWord(WordDataTreeNode root, String word){
WordDataTreeNode tempNode = root;
//需要删除的
Map<Character, WordDataTreeNode> map = new HashMap<>();
char[] chars = word.toCharArray();
int length = chars.length;
for (int i = 0; i < length; i++) {
//不存在第一个词
WordDataTreeNode subNode = tempNode.getSubNode(chars[i]);
if (subNode == null) {
return;
}
if (i == (length - 1)) {
//尾字符判断是否结束
if (!subNode.end()) {
return;
}
if (subNode.getNodeSize() > 0) {
//尾字符下还存在字符,即标识即可
subNode.end(false);
return;
}
}
if (subNode.end()) {
map.clear();
}
map.put(chars[i], tempNode);
tempNode = subNode;
}
for (Map.Entry<Character, WordDataTreeNode> entry : map.entrySet()) {
WordDataTreeNode value = entry.getValue();
//节点只有一个就置空
if (value.getNodeSize() == 1) {
value.clearNode();
return;
}
//多个就删除
value.removeNode(entry.getKey());
}
}
} }