Files
cKit/Foundation/c_PtrLinkBag.t.c
T
2026-08-30 01:48:03 +08:00

75 lines
2.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "c_PtrLinkBag.h"
#include <stdlib.h>
#include <stdio.h>
#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;
}