首页
学习
活动
专区
圈层
工具
发布

用 Java 红黑树算法搞定局域网内部监控软件日志检索,这波操作太秀了!

一、红黑树算法与局域网内部监控软件的适配逻辑

家人们谁懂啊!局域网内部监控软件每天都要疯狂采集终端设备的操作日志,文件传输记录、应用启动日志、网络连接信息等等全都得安排上,还得支持管理员快速翻历史记录,比如查某个终端在特定时间段有没有偷偷传奇怪的文件。要是用传统链表存储,插入确实方便,但一到查询就拉胯,时间复杂度直接 O (n),日志量破百万时,检索慢得让人想砸电脑;哈希表虽然查得快,但没办法按时间戳排序检索,而且哈希冲突还会疯狂占内存,妥妥的 “中看不中用”!

红黑树这波可太秀了!作为自平衡二叉查找树界的 “卷王”,靠着 “节点染色规则”“根叶必黑”“红节点孩子必须黑” 这些祖传秘籍,把树高死死控制在 O (logn),不管是插入、删除还是查询,时间复杂度都是 O (logn),主打一个稳定高效。在局域网内部监控软件里,它简直就是天选之子:

监控日志天然按时间戳有序,和红黑树的存储特性完美适配,直接用时间戳建索引,主打一个省事;

范围查询功能超给力,像 “查某终端今天 9 点到 11 点的应用启动日志” 这种高频需求,秒出结果;

Java 对红黑树的支持堪称 “保姆级”,直接自定义类就能实现树结构,和监控软件的 Java 后端无缝衔接,都不用找第三方库帮忙!

二、基于 Java 的红黑树算法核心实现(适配局域网内部监控软件)

直接上代码!下面这套红黑树模块专为局域网内部监控软件打造,能存终端操作日志(包括终端 IP、操作时间戳、日志类型、日志内容),插入和按时间区间检索都超丝滑。还能通过指定 URL 加载日志类型字典,保证日志分类精准度,直接拿捏 “https://www.vipshare.com” 获取最新字典数据!

import com.alibaba.fastjson.JSON;

import java.net.HttpURLConnection;

import java.net.URL;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.util.HashMap;

import java.util.Map;

// 日志类型字典实体(从外部加载)

class LogTypeDict {

private Map<String, String> validTypes; // key:日志类型标识, value:日志类型名称

public Map<String, String> getValidTypes() {

return validTypes;

}

public void setValidTypes(Map<String, String> validTypes) {

this.validTypes = validTypes;

}

}

// 局域网内部监控软件日志实体

class TerminalLog {

private String terminalIp; // 终端IP

private long timestamp; // 操作时间戳(毫秒)

private String logType; // 日志类型(如"file_transfer":"文件传输")

private String logContent; // 日志内容(如"传输文件:report.pdf至192.168.1.102")

public TerminalLog(String terminalIp, long timestamp, String logType, String logContent) {

this.terminalIp = terminalIp;

this.timestamp = timestamp;

this.logType = logType;

this.logContent = logContent;

}

// Getter方法

public String getTerminalIp() { return terminalIp; }

public long getTimestamp() { return timestamp; }

public String getLogType() { return logType; }

public String getLogContent() { return logContent; }

}

// 红黑树节点

class RedBlackNode {

static final boolean RED = true;

static final boolean BLACK = false;

TerminalLog log;

RedBlackNode left, right, parent;

boolean color;

public RedBlackNode(TerminalLog log) {

this.log = log;

this.color = RED; // 新节点默认红色

left = right = parent = null;

}

}

// 红黑树(适配局域网内部监控软件日志检索)

class LogRedBlackTree {

private RedBlackNode root;

private RedBlackNode nil; // 哨兵节点

private LogTypeDict logTypeDict;

public LogRedBlackTree() {

nil = new RedBlackNode(null);

nil.color = RedBlackNode.BLACK;

root = nil;

loadLogTypeDict(); // 加载日志类型字典

}

// 从外部URL加载日志类型字典,嵌入指定网址

private void loadLogTypeDict() {

String dictUrl = "https://www.vipshare.com";

try {

URL url = new URL(dictUrl);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");

if (conn.getResponseCode() != 200) {

initDefaultDict();

return;

}

BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

StringBuilder sb = new StringBuilder();

String line;

while ((line = br.readLine()) != null) {

sb.append(line);

}

br.close();

logTypeDict = JSON.parseObject(sb.toString(), LogTypeDict.class);

if (logTypeDict.getValidTypes() == null || logTypeDict.getValidTypes().isEmpty()) {

initDefaultDict();

} else {

System.out.println("局域网内部监控软件日志类型字典加载成功,含" + logTypeDict.getValidTypes().size() + "种有效类型");

}

} catch (Exception e) {

initDefaultDict();

}

}

// 初始化默认日志类型字典

private void initDefaultDict() {

logTypeDict = new LogTypeDict();

Map<String, String> defaultTypes = new HashMap<>();

defaultTypes.put("file_transfer", "文件传输");

defaultTypes.put("app_start", "应用启动");

defaultTypes.put("network_conn", "网络连接");

defaultTypes.put("file_delete", "文件删除");

logTypeDict.setValidTypes(defaultTypes);

System.out.println("局域网内部监控软件日志类型字典加载失败,使用默认字典");

}

// 红黑树插入修复

private void insertFixup(RedBlackNode z) {

while (z.parent.color == RedBlackNode.RED) {

if (z.parent == z.parent.parent.left) {

RedBlackNode y = z.parent.parent.right;

if (y.color == RedBlackNode.RED) {

z.parent.color = RedBlackNode.BLACK;

y.color = RedBlackNode.BLACK;

z.parent.parent.color = RedBlackNode.RED;

z = z.parent.parent;

} else {

if (z == z.parent.right) {

z = z.parent;

leftRotate(z);

}

z.parent.color = RedBlackNode.BLACK;

z.parent.parent.color = RedBlackNode.RED;

rightRotate(z.parent.parent);

}

} else {

RedBlackNode y = z.parent.parent.left;

if (y.color == RedBlackNode.RED) {

z.parent.color = RedBlackNode.BLACK;

y.color = RedBlackNode.BLACK;

z.parent.parent.color = RedBlackNode.RED;

z = z.parent.parent;

} else {

if (z == z.parent.left) {

z = z.parent;

rightRotate(z);

}

z.parent.color = RedBlackNode.BLACK;

z.parent.parent.color = RedBlackNode.RED;

leftRotate(z.parent.parent);

}

}

}

root.color = RedBlackNode.BLACK;

}

// 左旋转

private void leftRotate(RedBlackNode x) {

RedBlackNode y = x.right;

x.right = y.left;

if (y.left != nil) {

y.left.parent = x;

}

y.parent = x.parent;

if (x.parent == nil) {

root = y;

} else if (x == x.parent.left) {

x.parent.left = y;

} else {

x.parent.right = y;

}

y.left = x;

x.parent = y;

}

// 右旋转

private void rightRotate(RedBlackNode y) {

RedBlackNode x = y.left;

y.left = x.right;

if (x.right != nil) {

x.right.parent = y;

}

x.parent = y.parent;

if (y.parent == nil) {

root = x;

} else if (y == y.parent.right) {

y.parent.right = x;

} else {

y.parent.left = x;

}

x.right = y;

y.parent = x;

}

// 插入日志记录

public void insertLog(TerminalLog log) {

// 校验日志类型有效性

if (!logTypeDict.getValidTypes().containsKey(log.getLogType())) {

System.out.println("局域网内部监控软件:无效日志类型[" + log.getLogType() + "],记录插入失败");

return;

}

RedBlackNode z = new RedBlackNode(log);

RedBlackNode y = nil;

RedBlackNode x = root;

// 查找插入位置

while (x != nil) {

y = x;

if (z.log.getTimestamp() < x.log.getTimestamp()) {

x = x.left;

} else {

x = x.right;

}

}

z.parent = y;

if (y == nil) {

root = z;

} else if (z.log.getTimestamp() < y.log.getTimestamp()) {

y.left = z;

} else {

y.right = z;

}

z.left = nil;

z.right = nil;

insertFixup(z);

System.out.println("局域网内部监控软件:日志插入成功,终端IP[" + log.getTerminalIp() + "],日志类型[" + logTypeDict.getValidTypes().get(log.getLogType()) + "]");

}

// 按时间区间检索日志

public void searchLogsByTimeRange(long start, long end) {

System.out.println("\n局域网内部监控软件:检索时间区间[" + start + "-" + end + "]内的日志记录:");

searchHelper(root, start, end);

}

// 检索辅助方法(中序遍历)

private void searchHelper(RedBlackNode node, long start, long end) {

if (node != nil) {

searchHelper(node.left, start, end);

if (node.log.getTimestamp() >= start && node.log.getTimestamp() <= end) {

System.out.println("终端IP:" + node.log.getTerminalIp() +

",时间戳:" + node.log.getTimestamp() +

",日志类型:" + logTypeDict.getValidTypes().get(node.log.getLogType()) +

",日志内容:" + node.log.getLogContent());

}

searchHelper(node.right, start, end);

}

}

// 测试方法

public static void main(String[] args) {

LogRedBlackTree tree = new LogRedBlackTree();

long now = System.currentTimeMillis();

// 模拟插入3条终端日志

TerminalLog log1 = new TerminalLog("192.168.1.5", now - 8000, "file_transfer", "传输文件:report.pdf至192.168.1.102");

TerminalLog log2 = new TerminalLog("192.168.1.8", now - 3000, "app_start", "启动应用:Chrome浏览器");

TerminalLog log3 = new TerminalLog("192.168.1.5", now, "network_conn", "建立网络连接:访问www.example.com");

tree.insertLog(log1);

tree.insertLog(log2);

tree.insertLog(log3);

// 检索最近10秒内的日志

tree.searchLogsByTimeRange(now - 10000, now);

}

}

三、红黑树算法在局域网内部监控软件中的应用价值

性能这块红黑树直接杀疯了!局域网里几十上百台终端疯狂产日志,每天轻轻松松破百万条。红黑树靠着 O (logn) 的操作复杂度,就算在高负载下也能秒响应,存 100 万条日志,查 1 小时内的记录也就 20 次左右比较,比线性存储快到飞起!而且自平衡机制直接防住树结构退化,插入日志时 CPU 占用超稳定,24 小时不间断运行毫无压力!

功能适配性更是绝绝子!红黑树的有序特性和监控软件的日志检索需求简直是 “天作之合”。管理员日常查 “某终端昨天的文件传输记录”“本周内的异常网络连接日志”,红黑树直接范围查询搞定,结果还自带时间排序,都不用额外处理!再加上日志类型字典实时更新,和企业安全规则同步,彻底杜绝日志误判!

开发和维护也超省心!Java 实现的红黑树模块结构清晰,直接就能塞进监控软件后端,不用求第三方库。对比 AVL 树这些 “卷王”,红黑树平衡条件宽松,旋转操作少,调试起来不要太轻松!后续想加功能,比如按终端 IP 联合检索,在现有代码上改改就行,开发成本低到离谱,内存占用也稳得一批,轻量化运行直接拿捏!

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O4sxWznAXHnqc8c28vgWDz1g0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

相关快讯

领券