# T_DICT_DB **Repository Path**: xr_jesse/t_dict_db ## Basic Information - **Project Name**: T_DICT_DB - **Description**: T_DICT_DB C++23 MIT 内存级轻量化类文件系统数据库 高性能并发支持安全字典,任意数据类型存储 特性 68方法 CRUD 权限 拦截 维护 运算 持久化 日志 回收站 1.三级用户SU/HU/VU 权限rw, r_, __ O(path_length)的权限算法 2.四级锁:操作/冻结/节点/拦截 3.动态路径 4.回收站 5.事务 6.二进制/JSON持久化 7.轻量化事件监听 - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2025-07-23 - **Last Updated**: 2025-08-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: 线程安全, 数据库, 管理系统 ## README # T_DICT - C++23 安全嵌套字典数据库(自用项目) ## 数据库最基本功能完工可以运行,可以尝鲜,但是bug没改多少,也没大量测试 ## C++23 原生 无外部依赖 复制粘贴即部署 ## License MIT ## T_DICT 是一个高性能、线程安全的字典容器,提供细粒度权限控制和嵌套数据结构,适用于需要严格数据访问管理的场景。 ## 核心特性 - 🔒 三级权限系统:SU(超级管理员)/HU(高级用户)/VU(访客)权限控制 - 🧵 细粒度锁机制:节点级读写锁与全局锁,自动锁传播 - 🗺️ 路径化操作:{key0,key1,...} 路径访问嵌套数据 - ♻️ 安全回收站:异步线程安全节点回收 - 💾 持久化支持:二进制/JSON序列化接口 ## 快速开始 拷贝主代码到项目,确保您的C++编译器支持C++20 ## 基本用法 ```cpp import; import; import; import; //项目自写的模块 import T_DICT; using namespace std; int main() { { try { DICT::Dict db( "su", "my_db", "root", //仅在把本dict整体插入另一个dict时使用 1000ULL, //最大监听数量(与以下三个参数无关,当到达最大数量时,新注册的监听会被拒绝) 100, //su最大监听数量 100, //hu最大监听数量 100, //vu最大监听数量 true, //开启日志ROM存储(开启同时开启自动清理防止内存溢出) true, //开启错误日志记录到日志流 true, //开启日志打印到控制台(谨慎开启,严重消耗性能) false, //自动保存日志到文件 "", //日志保存路径(开启日志保存却不设置保存路径时无法开启日志报错,并报错) true, //是否开启回收站功能,自动回收弃用节点,当不需要时可以关闭(比如静态大小数据库运算时) true //是否开启操作计数功能 ); try { db.unlock_operation("su"); cout << "unlocked" << endl; } catch (const exception& e) { cerr << "Exception: " << e.what() << endl; } try { //添加字典 std::vector dict_path; dict_path.push_back("my_dict"); db.add("su", "su", DICT::Dict::add_type::dict, NULL, dict_path, false); cout << "dict added" << endl; std::vector value_path = dict_path; value_path.push_back("my_value"); db.add("su", "su", DICT::Dict::add_type::value, std::string("Hello, world!"), value_path, false); cout << "value added" << endl; //su无需显式设置权限即可读取 std::any value = db.get_value("su", "su", value_path); cout << "value: " << std::any_cast(value) << endl; //添加用户 db.add_user("su","su","hu_1", DICT::Dict::UserType::hu, DICT::Dict::Permission::rw); db.add_user("su","su","hu_2", DICT::Dict::UserType::hu, DICT::Dict::Permission::rw); cout << "users added" << endl; //设置权限 db.set_permission( "su", "su", "hu_1", DICT::Dict::SetType::node, DICT::Dict::Permission::rw, true, false, {}, value_path ); db.set_permission( "su", "su", "hu_2", DICT::Dict::SetType::node, DICT::Dict::Permission::rw, true, false, {}, value_path ); cout << "permissions set" << endl; //有权限后尝试读取 value = {}; value = db.get_value("su", "hu_1", value_path); cout << "value: " << std::any_cast(value) << endl;//应成功_0 value = {}; value = db.get_value("su", "hu_2", value_path); cout << "value: " << std::any_cast(value) << endl;//应成功_1 //尝试无权限读取 db.add("su", "su", DICT::Dict::add_type::value, std::string("Hello T_DICT !"), {"my_dict","value_1"}, false); try { value = {}; value = db.get_value("su", "hu_1", { "my_dict","value_1" }); cout << "value_1_____: " << std::any_cast(value) << endl;//应失败_2 } catch (const exception& e) { cerr << "Exception: " << e.what() << endl; } try { value = {}; value = db.get_value("su", "hu_2", { "my_dict","value_1" }); cout << "value_2_____: " << std::any_cast(value) << endl;//应失败_3 } catch (const exception& e) { cerr << "Exception: " << e.what() << endl; } //设置时间权限 db.set_permission( "su", "su", "hu_1", DICT::Dict::SetType::node, DICT::Dict::Permission::rw, true, true, { {"2025/01/01/00/00/00/000","2025/12/31/23/59/59/999"}},//在时间内,读取应成功_4 { "my_dict","value_1" } ); db.set_permission( "su", "su", "hu_2", DICT::Dict::SetType::node, DICT::Dict::Permission::rw, true, true, { {"2025/01/01/00/00/00/000","2025/03/31/23/59/59/999"} },//在过去,读取应失败_5 { "my_dict","value_1" } ); cout << "permissions set" << endl; //有权限后尝试读取 try { value = {}; value = db.get_value("su", "hu_1", { "my_dict","value_1" }); cout << "value_1_____: " << std::any_cast(value) << endl;//4->应成功_6 } catch (const exception& e) { cerr << "Exception: " << e.what() << endl; } try { value = {}; value = db.get_value("su", "hu_2", { "my_dict","value_1" }); cout << "value_2_____: " << std::any_cast(value) << endl;//5->应失败_7 } catch (const exception& e) { cerr << "Exception: " << e.what() << endl; } db.del("su", "su", value_path); cout << "value deleted" << endl; } catch (const exception& e) { cerr << "Exception: " << e.what() << endl; } } catch (const exception& e) { cerr << "Exception: " << e.what() << endl; } } // 给日志系统额外时间刷新输出 std::this_thread::sleep_for(std::chrono::milliseconds(100)); return 0; } 2025/08/19/19/08/15/972 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/972][user_father:su][user:su][operation_type:1][path:]Log function set successfully. 2025/08/19/19/08/15/975 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/974][user_father:su][user:su][operation_type:1][path:]Auto recycle clean function set successfully. 2025/08/19/19/08/15/977 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/976][user_father:su][user:su][operation_type:1][path:]Operation counter function set successfully. 2025/08/19/19/08/15/978 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/978][user_father:su][user:su][operation_type:1][path:]Dict initialized successfully. unlocked 2025/08/19/19/08/15/981 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/980][user_father:su][user:su][operation_type:36][path:]Success dict added 2025/08/19/19/08/15/984 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/983][user_father:su][user:su][operation_type:36][path:]Success value added 2025/08/19/19/08/15/986 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/985][user_father:su][user:su][operation_type:42][path:]Success value: Hello, world! 2025/08/19/19/08/15/988 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/988][user_father:su][user:su][operation_type:14][path:]Success 2025/08/19/19/08/15/990 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/990][user_father:su][user:su][operation_type:14][path:]Success users added 2025/08/19/19/08/15/993 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/992][user_father:su][user:su][operation_type:21][path:]Success 2025/08/19/19/08/15/995 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/995][user_father:su][user:su][operation_type:21][path:]Success permissions set 2025/08/19/19/08/15/997 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/997][user_father:su][user:hu_1][operation_type:42][path:]Success value: Hello, world! 2025/08/19/19/08/15/999 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/15/999][user_father:su][user:hu_2][operation_type:42][path:]Success value: Hello, world! 2025/08/19/19/08/16/002 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/16/001][user_father:su][user:su][operation_type:36][path:]Success 2025/08/19/19/08/16/004 [T_DICT_DB][ERR_LOG][__ERROR__TIME:2025/08/19/19/08/16/004][user_father:su][user:hu_1][operation_type:42][path:/my_dict/value_1][error_type:permission_not_enough]Final permission insufficient: 0 < 2 (No permission records in path) Exception: 2025/08/19/19/08/16/004[T_DICT][ERROR][fu:su cu:hu_1][operation_type:42][permission_not_enough][parh: /my_dict/value_1]Final permission insufficient: 0 < 2 (No permission records in path) 2025/08/19/19/08/16/007 [T_DICT_DB][ERR_LOG][__ERROR__TIME:2025/08/19/19/08/16/007][user_father:su][user:hu_2][operation_type:42][path:/my_dict/value_1][error_type:permission_not_enough]Final permission insufficient: 0 < 2 (No permission records in path) Exception: 2025/08/19/19/08/16/007[T_DICT][ERROR][fu:su cu:hu_2][operation_type:42][permission_not_enough][parh: /my_dict/value_1]Final permission insufficient: 0 < 2 (No permission records in path) 2025/08/19/19/08/16/010 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/16/010][user_father:su][user:su][operation_type:21][path:]Success 2025/08/19/19/08/16/012 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/16/012][user_father:su][user:su][operation_type:21][path:]Success permissions set 2025/08/19/19/08/16/014 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/16/014][user_father:su][user:hu_1][operation_type:42][path:]Success value_1_____: Hello T_DICT ! //6成功 2025/08/19/19/08/16/017 [T_DICT_DB][ERR_LOG][__ERROR__TIME:2025/08/19/19/08/16/017][user_father:su][user:hu_2][operation_type:42][path:/my_dict/value_1][error_type:permission_not_enough]Final permission insufficient: 0 < 2。//7失败 Exception: 2025/08/19/19/08/16/017[T_DICT][ERROR][fu:su cu:hu_2][operation_type:42][permission_not_enough][parh: /my_dict/value_1]Final permission insufficient: 0 < 2 2025/08/19/19/08/16/020 [T_DICT_DB][OPT_LOG][OP_START_TIME:2025/08/19/19/08/16/019][user_father:su][user:su][operation_type:38][path:]Success value deleted D:\lib\Desktop\T_DICT\x64\Debug\main.exe (进程 18364)已退出,代码为 3 (0x3)。 按任意键关闭此窗口. . . ``` ## 应用场景 - 多用户配置管理系统 - 权限敏感的运行时数据存储 - 安全关键型应用的配置中心 - 需要细粒度访问控制的缓存系统 ## 🚀 T_DICT - 高性能并发内存数据库 - 性能测试报告 - 📊 综合摘要 - T_DICT 在高并发、高竞争及深度路径访问等多种极端场景下,均表现出 卓越的吞吐量、完美的一致性(零错误)和极高的资源效率。其性能指标已达到甚至超越许多工业级嵌入式数据库水平。 | 测试场景 | 线程数 | 总操作数 (读写对) | 耗时 (ms) | 吞吐量 (Ops/s) | 错误数 | 关键特性 | |----------------|--------|-------------------|-----------|----------------|--------|----------------------| | 基础并发 | 5 | 500,000 | 6,550 | 76,336 | 0 | 无竞争访问 | | 高并发 | 14 | 1,400,000 | 15,932 | 87,874 | 0 | 无竞争访问 | | 极限并发 | 128 | 12,800,000 | 148,744 | 86,054 | 0 | 无竞争访问 | | 地狱级竞争 | 14 | 140,000 | 1,523 | 91,924 | 0 | 11层深度,竞争同一节点 | - - 🧪 详细测试报告 - 测试环境 - CPU: Intel Xeon E5-2450 (8核16线程) - - 内存: ECC 海力士 DDR3 8+8G - - OS: Windows - - 测试代码: TEST.cpp - - 编译器: MSVC (Release模式) - - 1. 无竞争并行访问测试 - 目的:测试系统在处理多用户独立读写自身数据路径时的基本性能。 - - 操作:每个 hu 用户在各自独立的路径上进行 set 和 get_value 操作。 - - 结论:系统展现了优异的并行扩展能力,从5线程扩展到128线程,吞吐量保持稳定在 8.6万+ Ops/s,总处理请求超 1280万次,零错误。 - - 2. 高竞争深度路径访问测试 (地狱难度) - 目的:在最极端场景下测试锁机制、权限校验和路径遍历的性能瓶颈。 - - 操作:14个线程 竞争读写 同一个深度为11的路径末端节点,操作混合比为 7:3 (读:写)。 - - 结论: - - 性能不降反升:吞吐量达到惊人的 91,924 Ops/s (~18.4万 QPS),证明其锁实现极其高效,且对CPU缓存利用充分。 - - 完美的一致性:14万次 高竞争操作后,数据完好无损,零错误。 - - - 🏆 核心亮点 - 💨 卓越性能: 轻松达到 万级TPS 和 十万级QPS,满足高性能应用核心需求。 - - 🔒 强一致性: 在总计超 1400万次 的操作中,始终保持数据一致,错误数为零。 - - ⚡ 极致效率: 低CPU占用、低内存开销,资源利用率极高。 - - 🧩 高扩展性: 从个位数到远超CPU核心数的线程规模,性能表现稳定,扩展性极佳。 - - 🛡️ 安全可靠: 完整的权限系统、锁机制和监听拦截功能,保障系统安全。 - - 🎯 应用场景建议 - T_DICT 是以下场景的理想选择: - - 高性能应用的核心状态存储(游戏服务器、实时交易系统) - - 配置中心与动态规则引擎 - - 实时排行榜与会话存储(Session Storage) - - 高并发环境下的特征存储(Feature Store) - - 需要极细粒度权限控制的内部数据管理平台 - - 💡 结论 - T_DICT 并非一个简单的玩具项目,而是一个经过严格压力测试、具备 生产级应用潜力 的高性能并发内存数据库内核。其表现出的性能、稳定性和资源效率,充分证明了其背后架构设计的先进性与实现的质量。 - - 欢迎 Star & Fork! 我们期待您的反馈与贡献。 - - 备注:以上测试数据均在特定环境下获得,实际性能可能因硬件、操作系统和负载特征而异。 - ## 文档(部分如下) - //==========T_DICT.ixx========== - - //=====模块说明===== - //本模块实现C++原生、带权限系统的字典类内存级类磁盘文件系统数据库 - //设计特性类似Linux下的ext磁盘文件系统,su可以删除操作中的数据(实际上是su标记弃用节点,回收站延迟直到节点/子节点操作完毕后删除) - - - //=====权限系统===== - //用户体系:su>hu>vu - //权限:rw(读写)、r_(只读)、__(无权限) - //su用户无论何时何处都拥有rw权限 - //hu用户在全局或节点上可能有rw(读写)、r_(只读)、__(无权限) - //vu用户在全局或节点上可能有r_(只读)、__(无权限) - //谁操作校验谁的权限 - //hu的全局权限小于节点权限不影响su对其任意修改 - //vu的全局权限小于节点权限不影响hu在全局权限为rw时对其任意修改 - //hu读写时,全局权限效果>节点权限效果,如全局为r_,节点为rw,则操作时临时降级为r_,临时只读,但不修改权限记录信息 - //vu读写时,全局权限效果>节点权限效果,如全局为__,节点为r_,则操作时临时降级为__,临时不允许读写,但不修改权限记录信息 - //权限时间格式:YYYY/MM/DD/HH/MM/SS/mmm(被动式权限记录,当操作到有该权限记录时,会自动校验) - //时间权限是区间式权限记录(某时间点之前/后有权限 或 从某时间点开始到某时间点结束),要判断是否启用时间权限以及当前时间是否在记录的区间内 - //时间权限可启用或不启用 - //同等级操作时会考虑锁 - //在path中: - // 1.如果一整个path无权限记录,则无权限 - // 2.如果在访问的路径上的非末端节点的记录终止传播权限,则后方无权限,该用户在该路径不可操作 - // 3.如果存在多个传播的记录且都传播,则取这多个中的最小值 - // 4.如果存在多个传播的记录,任意节点有显式无权限"__"则无权限 - // 5.任意节点若启用时间权限,则判断当前时间是否在时间权限记录内, - // 如果当前时间不在任何时间权限记录内,则无权限,且视为显式无权限"__",但不改变权限记录信息 - // 5.除了以上有权限 - //=====路径访问===== - //path的结构为{key0,key1,...,keyn}(便于动态合成路径访问) - //可以使用kvt("key0/key1/key2/.../keyn")来简便表示死路径 - //大部分不需要显式提供key,key是path最后一位 - - //=====日志与错误===== - //所有方法使用抛出错误的形式返回错误 - //错误抛出格式time_str + "[T_DICT][ERROR][fu:" + user_father + " cu:" + user + "][operation_type:" + std::to_string(static_cast(operation_type)) + "][" + error_type + "][parh: " + path_str + "]" + message; - //错误类型详见Error - - //=====特性说明===== - // get_node__ 函数(核心方法)流程: - // 1. 用户存在性验证: - // if 用户不存在 then 报错(error_.user_not_found_error), 退出 - // 2. 全局权限验证: - // if 用户全局权限 < 操作所需权限 then 报错(error_.permission_not_enough), 退出 - // 3.生成3个操作key,用于判断事件监听触发 - // 1."user_father user" - // 2."OPT_type" - // 3."time_str" - // 4. 路径遍历(从根节点开始逐级处理): - // for 路径中的每一级: - // a. 节点存在性: - // if 当前节点不存在子节点(name) then 报错(error_.path_not_found_error), 退出 - // b. 节点状态检查: - // if 节点被弃用 then 报错(error_.path_abandoned_error), 退出 - // if 节点被拦截 then - // if 非超级用户操作 then 报错(error_.operation_intercepted_error), 退出 - // if 节点损坏 then 报错(error_.operation_failed_error), 退出 - // c. 路径中断检查(值节点出现在非终点): - // if 当前节点是值节点且非最后一级 then 报错(error_.invalid_path_error), 退出 - // d. 权限检查(每级节点): - // if 节点权限不足 then 报错(error_., permission_not_enough), 退出 - // e. 事件触发检查 - // if 存在经过型事件监听 then 判断是否匹配 if 匹配则触发事件回调函数,否则继续 - // f. 进入下一级节点 - // 5. 终点处理: - // a. 节点类型检查: - // if 操作要求值节点但终点是字典节点 then 报错(error_.invalid_operation_type_error), 退出 - // if 操作要求字典节点但终点是值节点 then 报错(error_.invalid_end_node_type_error), 退出 - // b. 节点状态检查: - // if 节点被弃用 then 报错(error_.path_abandoned_error), 退出 - // if 节点被拦截 then - // if 非超级用户操作 then 报错(error_.operation_intercepted_error), 退出 - // if 节点损坏 then 报错(error_.operation_failed_error), 退出 - // c. 锁定状态检查: - // if 节点被锁定 then - // if 非超级用户操作 then 报 error_.locked_error, 退出 - // d. 权限检查(终点): - // if 路径最小权限 < 操作所需权限 then 报错(error_.permission_not_enough), 操作 - // e. 锁定节点(防止并发修改): - // - 锁定节点(超级用户操作不锁定) - // f. 返回节点指针(调用者负责解锁) - // - //get_node__以手把手锁经过路径时顺便收集权限信息,实现了O(path_path_length * M + N)一次函数级别的极简权限校验时间复杂度, - // 且在未到达终点前权限不足时提前退出,所以权限不足时的时间复杂度小于等于O(path_path_length * M + N), - // 其中M(经过每个节点的权限采样,损坏、锁定、拦截判断等固定步骤)、N(全局权限采样,末端节点最小权限计算等固定步骤)为常数,path_size为路径长度 - //不提供权限缓存是为了避免缓存攻击、路径权限高频变更等攻击方式,提高系统安全性 - - //一般方法实现流程: - //1.调用check_global_users_value__() 获取父子用户组合和类型和用户名 - //2.根据操作类型合理调用get_node__() - //3.操作数据 - //4.判断是否有匹配的监听,如果有则触发回调函数 - //5.根据设置确定是否记录日志 - - //拦截机制:(仅su可以使用拦截系统) - // 当调用拦截函数时,如果是点拦截,则未到达该节点的操作会被拦截,报错并退出,如果是区间拦截,则在该区间内的请求都会被拦截,则在该区间内的操作会被拦截,报错并退出。 - // 设置支持拦截的操作才会被拦截,并且被拦截后会回滚操作 - //拦截方法: - // 1.预注册拦截点 - // 2.调用拦截函数 - // 3.根据需要取消注册拦截点 - - //监听机制: - // su可以删除任意用户的监听钩子 - // 监听可以被su拦截 - // 某些类型的监听可以因锁定而失败 - // get_node__经过时即触发监听,实现O(1)级别的事件触发查找时间复杂度 - // 节点上存有监听分段二进制掩码map,实现无遍历事件触发查找 - // 不要在监听回调函数中进行耗时操作,最好只是简单的数值比较之类的,否则会影响其他操作 - ## 贡献指南 ### 未完工,暂不支持推送更新、分支等等 ## 许可证 ### 本项目采用 MIT 许可证