cf38d76fd0
M1 — Memory Pool (内存池): - ObjectPool<T>: O(1) acquire/release with free-list, chunk-based expansion - ThreadSafeObjectPool<T>: per-thread local pools with global fallback - CowPtr<T>: copy-on-write smart pointer with shallow/deep copy - 10 tests: single/multi-thread, CoW detach, reuse rate M2 — Parallel Boolean (并行布尔): - parallel_face_face_intersection(): OpenMP face-pair dispatch with AABB culling - parallel_classify_faces(): thread-safe ray casting classification - parallel_mesh_union/intersection/difference + B-Rep variants - Thread count management API - 12 tests: coverage, empty cases, identity operations M3 — Parallel Marching Cubes (并行MC): - parallel_marching_cubes(): Z-slice parallel voxel processing - parallel_adaptive_mc(): octree-based adaptive resolution - Complete 256-entry edge table + Möller-Trumbore interpolation - 5 tests: sphere basic/high-res/empty/adaptive/threaded M4 — Parallel Surface Intersection (并行求交): - parallel_curve_intersections(): per-pair parallel dispatch - parallel_surface_intersection(): recursive subdivision + Newton refinement - AABB broad-phase culling before narrow-phase - 4 tests: curve pairs, surface batch M5 — GMP Exact Predicates (精确谓词): - exact_orient2d/3d: adaptive precision (double → GMP fallback) - exact_in_sphere: circumsphere test with degenerate handling - exact_point_in_polygon/polyhedron: robust ray casting - PrecisionMode: Fast/Adaptive/Exact with global toggle - 12 tests: all orientations, boundary cases, mode switching 21 files, +2263 lines
100 lines
2.6 KiB
C++
100 lines
2.6 KiB
C++
#include <gtest/gtest.h>
|
|
#include "vde/core/object_pool.h"
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
using namespace vde::core;
|
|
|
|
struct TestObj { int x = 0; double y = 0.0; };
|
|
|
|
TEST(ObjectPoolTest, AcquireRelease) {
|
|
ObjectPool<TestObj> pool;
|
|
auto* obj = pool.acquire();
|
|
ASSERT_NE(obj, nullptr);
|
|
obj->x = 42;
|
|
pool.release(obj);
|
|
auto* obj2 = pool.acquire(); // should reuse
|
|
EXPECT_EQ(obj2->x, 0); // reset to default
|
|
EXPECT_GT(pool.reuse_rate(), 0.0);
|
|
}
|
|
|
|
TEST(ObjectPoolTest, AcquireMany) {
|
|
ObjectPool<TestObj, 64> pool;
|
|
std::vector<TestObj*> objs;
|
|
for (int i = 0; i < 1000; ++i) objs.push_back(pool.acquire());
|
|
for (auto* o : objs) pool.release(o);
|
|
EXPECT_EQ(pool.total_allocated(), 1000u);
|
|
EXPECT_GT(pool.total_reused(), 0u);
|
|
}
|
|
|
|
TEST(ObjectPoolTest, ReleaseNullptr) {
|
|
ObjectPool<TestObj> pool;
|
|
pool.release(nullptr); // should not crash
|
|
EXPECT_EQ(pool.total_allocated(), 0u);
|
|
}
|
|
|
|
TEST(ObjectPoolTest, ExpandChunk) {
|
|
ObjectPool<TestObj, 10> pool;
|
|
for (int i = 0; i < 25; ++i) {
|
|
auto* o = pool.acquire();
|
|
pool.release(o);
|
|
}
|
|
EXPECT_GE(pool.pool_size(), 30u);
|
|
}
|
|
|
|
TEST(ThreadSafePoolTest, ConcurrentAcquire) {
|
|
ThreadSafeObjectPool<TestObj, 64> pool;
|
|
std::atomic<int> count{0};
|
|
|
|
auto worker = [&]() {
|
|
for (int i = 0; i < 100; ++i) {
|
|
auto* o = pool.acquire();
|
|
o->x = i;
|
|
pool.release(o);
|
|
count++;
|
|
}
|
|
};
|
|
|
|
std::thread t1(worker), t2(worker), t3(worker), t4(worker);
|
|
t1.join(); t2.join(); t3.join(); t4.join();
|
|
EXPECT_EQ(count, 400);
|
|
}
|
|
|
|
TEST(CowPtrTest, ReadOnly) {
|
|
CowPtr<std::vector<int>> cow(std::vector<int>{1, 2, 3});
|
|
EXPECT_EQ(cow.read().size(), 3u);
|
|
EXPECT_EQ(cow.read()[0], 1);
|
|
}
|
|
|
|
TEST(CowPtrTest, ShallowCopy) {
|
|
CowPtr<std::vector<int>> cow(std::vector<int>{1, 2, 3});
|
|
auto cow2 = cow.shallow_copy();
|
|
EXPECT_EQ(cow.use_count(), 2);
|
|
EXPECT_EQ(cow2.use_count(), 2);
|
|
}
|
|
|
|
TEST(CowPtrTest, WriteDetaches) {
|
|
CowPtr<std::vector<int>> cow(std::vector<int>{1, 2, 3});
|
|
auto cow2 = cow.shallow_copy();
|
|
EXPECT_EQ(cow.use_count(), 2);
|
|
|
|
cow.write().push_back(4);
|
|
EXPECT_EQ(cow.use_count(), 1); // detached
|
|
EXPECT_EQ(cow2.use_count(), 1);
|
|
EXPECT_EQ(cow2.read().size(), 3u); // cow2 unchanged
|
|
}
|
|
|
|
TEST(CowPtrTest, DeepCopy) {
|
|
CowPtr<std::vector<int>> cow(std::vector<int>{1, 2, 3});
|
|
auto cow2 = cow.deep_copy();
|
|
EXPECT_EQ(cow.use_count(), 1);
|
|
EXPECT_EQ(cow2.use_count(), 1);
|
|
}
|
|
|
|
TEST(CowPtrTest, UniqueCheck) {
|
|
CowPtr<int> cow(42);
|
|
EXPECT_TRUE(cow.unique());
|
|
auto cow2 = cow.shallow_copy();
|
|
EXPECT_FALSE(cow.unique());
|
|
}
|