#include "c_PtrLinkBag.h" #include #include #include "c_Test.h" typedef struct { int socket_fd; int is_timeout; } Connection_t; TEST_CASE(test_fully_encapsulated_singly_link_bag_and_iter) { c_PtrLinkBag_t conn_bag; // 1. 原地初始化:不需要像以前那样在后续高频手工传递外部内存池,API 极其干净 ASSERT_INT_EQ(C_ERR_OK, c_PtrLinkBag_Init(&conn_bag, NULL)); ASSERT_TRUE(c_PtrLinkBag_IsEmpty(&conn_bag)); ASSERT_INT_EQ(0, c_PtrLinkBag_Size(&conn_bag)); // 2. 模拟挂载 4 个异构的连接 Connection_t c1 = { .socket_fd = 80, .is_timeout = 0 }; Connection_t c2 = { .socket_fd = 443, .is_timeout = 1 }; // 已超时死连接 Connection_t c3 = { .socket_fd = 22, .is_timeout = 1 }; // 已超时死连接,双重死接连最考验迭代器稳定性 Connection_t c4 = { .socket_fd = 8080,.is_timeout = 0 }; // 内部闭环驱动 Add 操作 c_PtrLinkBag_Add(&conn_bag, &c1); c_PtrLinkBag_Add(&conn_bag, &c2); c_PtrLinkBag_Add(&conn_bag, &c3); c_PtrLinkBag_Add(&conn_bag, &c4); // 验证实时计数 O(1) ASSERT_INT_EQ(4, c_PtrLinkBag_Size(&conn_bag)); // 3. 启动自主滑移闭环迭代器清理死物理连接 c_PtrLinkBagIter_t it; c_PtrLinkBagIter_Init(&it, &conn_bag); int touch_count = 0; while (c_PtrLinkBagIter_HasNext(&it)) { Connection_t* current_conn = (Connection_t*)c_PtrLinkBagIter_Get(&it); ASSERT_PTR_NOT_NULL(current_conn); ++touch_count; if (current_conn->is_timeout) { // 自主 Remove 绝招:拓扑裁切、自主寻找宿主内置的 allocator 进行物理 free、联动宿主计数降级 c_PtrLinkBagIter_Remove(&it); // 迭代器已自动优雅对齐到原本的下一跳,补 continue 防止循环逻辑手动滑飞 continue; } c_PtrLinkBagIter_Next(&it); } // 4. 一致性终审 ASSERT_INT_EQ(4, touch_count); // 确认全量 4 个元素都在时空里触碰过 ASSERT_INT_EQ(2, c_PtrLinkBag_Size(&conn_bag)); // 账实完全相符,死连接被剔除清算 // 链表拓扑彻底对齐与完整性校验(由于头插法,排列为 Head -> c4 -> c1 -> NULL) ASSERT_TRUE(conn_bag.head->ptr == &c4); ASSERT_TRUE(conn_bag.head->next->ptr == &c1); // c3 和 c2 的包装节点壳已被内置管理器物理火化 ASSERT_TRUE(conn_bag.head->next->next == NULL); // 完美谢幕! c_PtrLinkBag_Destroy(&conn_bag); } int main(void) { TEST_START(C_Fully_Encapsulated_Singly_Link_Bag_System_Tests); RUN_TEST(test_fully_encapsulated_singly_link_bag_and_iter); TEST_REPORT(); RETURN_TEST_STATUS; }