2ecad1543f
v8.1 — 极致性能 (SIMD + LockFree + Transaction + NUMA): - simd_vector.h: Vec4d/Vec4f SSE/AVX/NEON auto-detect, batch AABB, SoA transpose - concurrent_data: LockFreeQueue (MPMC CAS), LockFreeStack (Treiber), ConcurrentHashMap (64-segment sharded) - transaction: Command pattern, UndoManager (infinite undo/redo), crash-recovery journal - performance_tuning: NUMA-aware, cache_line aligned, prefetch, hot/cold separation - 20 tests (concurrent + transaction), ~2600 lines v8.2 — CAM 全面优化 + 装配模式: - cam_optimization: chip_thinning, HSM, constant_engagement, trochoidal_turn_milling - tool_life_management, probing_cycle, thread_milling - cam_advanced enhanced: Mazak/Okuma/Haas/DMG post-processors (8 total) - assembly_patterns: Circular/Rectangular/Mirror/PatternDriven/fill arrays - assembly_feature enhanced: assembly-level PMI propagation, batch interference check - 28 tests, compiled 0 errors (~2800 lines) v8.3 — 可视化+压缩+IGA+质量闭环: - visualization_quality: ambient_occlusion, edge_highlighting, wireframe, normals - topology_compression: Brep compression, Edgebreaker, vertex quantization - iga_prep: knot_insertion, degree_elevation, Bezier extraction for IGA analysis - quality_feedback: design_rule_check, manufacturability, cost_estimation, quality_score (0-100) - 28 tests, ~2349 lines 27 files, ~7750 lines, 76 tests
284 lines
9.2 KiB
C++
284 lines
9.2 KiB
C++
#pragma once
|
||
/**
|
||
* @file transaction.h
|
||
* @brief 极致性能 — 事务系统 + Command模式 + 无限撤销/重做 + 崩溃恢复
|
||
*
|
||
* 核心组件:
|
||
* - Transaction : begin/commit/rollback 事务
|
||
* - Command : 可撤销操作的抽象基类
|
||
* - UndoManager : 无限撤销/重做栈 + 事务日志
|
||
* - BrepCommand : BrepModel 操作的具体 Command 实现
|
||
*
|
||
* @ingroup core
|
||
*/
|
||
#include <vector>
|
||
#include <string>
|
||
#include <memory>
|
||
#include <functional>
|
||
#include <deque>
|
||
#include <fstream>
|
||
#include <sstream>
|
||
#include <ctime>
|
||
#include <chrono>
|
||
#include <cstdint>
|
||
#include <atomic>
|
||
|
||
namespace vde::core {
|
||
|
||
// ═══════════════════════════════════════════════════════════════════════════
|
||
// Command 模式
|
||
// ═══════════════════════════════════════════════════════════════════════════
|
||
|
||
/// 可撤销操作的抽象基类
|
||
///
|
||
/// 每个 Command 封装一个原子操作,支持执行和撤销。
|
||
/// 子类需实现 execute() 和 undo()。
|
||
class Command {
|
||
public:
|
||
virtual ~Command() = default;
|
||
|
||
/// 执行操作
|
||
virtual void execute() = 0;
|
||
|
||
/// 撤销操作(将状态恢复到执行前)
|
||
virtual void undo() = 0;
|
||
|
||
/// 获取操作描述
|
||
[[nodiscard]] virtual std::string description() const { return "Command"; }
|
||
|
||
/// 合并两个命令(可选优化)
|
||
/// @return true 若合并成功(this 吸收了 other)
|
||
virtual bool merge(Command* /*other*/) { return false; }
|
||
|
||
/// 命令 ID(用于日志)
|
||
[[nodiscard]] int64_t id() const { return id_; }
|
||
void set_id(int64_t id) { id_ = id; }
|
||
|
||
private:
|
||
int64_t id_ = 0;
|
||
};
|
||
|
||
/// 可调用对象包装的 Command
|
||
///
|
||
/// @code
|
||
/// auto cmd = make_command(
|
||
/// []{ do_something(); },
|
||
/// []{ undo_it(); },
|
||
/// "My operation");
|
||
/// @endcode
|
||
class LambdaCommand : public Command {
|
||
public:
|
||
using Func = std::function<void()>;
|
||
|
||
LambdaCommand(Func exec, Func undo_fn, std::string desc = "")
|
||
: exec_(std::move(exec))
|
||
, undo_(std::move(undo_fn))
|
||
, desc_(std::move(desc)) {}
|
||
|
||
void execute() override { if (exec_) exec_(); }
|
||
void undo() override { if (undo_) undo_(); }
|
||
[[nodiscard]] std::string description() const override { return desc_; }
|
||
|
||
private:
|
||
Func exec_;
|
||
Func undo_;
|
||
std::string desc_;
|
||
};
|
||
|
||
/// 便捷工厂函数
|
||
inline std::unique_ptr<Command> make_command(
|
||
std::function<void()> exec,
|
||
std::function<void()> undo_fn,
|
||
std::string desc = "")
|
||
{
|
||
return std::make_unique<LambdaCommand>(
|
||
std::move(exec), std::move(undo_fn), std::move(desc));
|
||
}
|
||
|
||
// ═══════════════════════════════════════════════════════════════════════════
|
||
// 事务日志条目
|
||
// ═══════════════════════════════════════════════════════════════════════════
|
||
|
||
/// 事务日志条目
|
||
///
|
||
/// 持久化到事务日志文件,用于崩溃恢复。
|
||
struct TransactionLogEntry {
|
||
enum class Type : uint8_t {
|
||
BEGIN = 0, ///< 事务开始
|
||
COMMAND = 1, ///< 命令执行
|
||
COMMIT = 2, ///< 事务提交
|
||
ROLLBACK = 3, ///< 事务回滚
|
||
CHECKPOINT = 4, ///< 检查点
|
||
};
|
||
|
||
Type type;
|
||
int64_t transaction_id;
|
||
int64_t command_id;
|
||
int64_t timestamp; ///< unix 微秒时间戳
|
||
std::string description; ///< 命令描述(COMMAND 类型时有效)
|
||
|
||
/// 序列化为一行
|
||
[[nodiscard]] std::string serialize() const;
|
||
/// 从一行反序列化
|
||
static TransactionLogEntry deserialize(const std::string& line);
|
||
};
|
||
|
||
// ═══════════════════════════════════════════════════════════════════════════
|
||
// Transaction
|
||
// ═══════════════════════════════════════════════════════════════════════════
|
||
|
||
/// 事务
|
||
///
|
||
/// 封装一组 Command 的原子执行。支持 begin/commit/rollback。
|
||
/// 事务在 commit 时将命令推送到 UndoManager。
|
||
///
|
||
/// @code
|
||
/// Transaction txn;
|
||
/// txn.begin();
|
||
/// txn.execute(make_command(...));
|
||
/// txn.execute(make_command(...));
|
||
/// txn.commit(); // 或 txn.rollback()
|
||
/// @endcode
|
||
class Transaction {
|
||
public:
|
||
Transaction();
|
||
~Transaction();
|
||
|
||
Transaction(const Transaction&) = delete;
|
||
Transaction& operator=(const Transaction&) = delete;
|
||
|
||
/// 开始事务
|
||
void begin();
|
||
|
||
/// 执行一条命令(加入事物缓冲区)
|
||
/// @param cmd 要执行的命令
|
||
void execute(std::unique_ptr<Command> cmd);
|
||
|
||
/// 提交事务(执行所有命令 → 加入 UndoManager)
|
||
void commit();
|
||
|
||
/// 回滚事务(撤销已执行命令 → 丢弃)
|
||
void rollback();
|
||
|
||
/// 是否处于活跃事务中
|
||
[[nodiscard]] bool is_active() const { return active_; }
|
||
|
||
/// 当前缓冲命令数
|
||
[[nodiscard]] size_t command_count() const { return commands_.size(); }
|
||
|
||
private:
|
||
bool active_ = false;
|
||
std::vector<std::unique_ptr<Command>> commands_;
|
||
int64_t txn_id_ = 0;
|
||
|
||
static std::atomic<int64_t> next_txn_id_;
|
||
};
|
||
|
||
// ═══════════════════════════════════════════════════════════════════════════
|
||
// UndoManager — 无限撤销/重做
|
||
// ═══════════════════════════════════════════════════════════════════════════
|
||
|
||
/// 撤销管理器
|
||
///
|
||
/// 维护无限撤销栈和重做栈。
|
||
/// 支持命令合并(连续同类型操作合并为一个)、事务日志与崩溃恢复。
|
||
///
|
||
/// @code
|
||
/// UndoManager um;
|
||
/// um.execute(make_command(...));
|
||
/// um.undo(); // 撤销最后一步
|
||
/// um.redo(); // 重做
|
||
/// um.save_checkpoint("save/checkpoint.dat"); // 持久化
|
||
/// @endcode
|
||
class UndoManager {
|
||
public:
|
||
UndoManager();
|
||
~UndoManager();
|
||
|
||
UndoManager(const UndoManager&) = delete;
|
||
UndoManager& operator=(const UndoManager&) = delete;
|
||
|
||
/// 执行命令并推入撤销栈
|
||
/// @param cmd 要执行的命令
|
||
/// @param merge 是否尝试与栈顶命令合并
|
||
void execute(std::unique_ptr<Command> cmd, bool merge = false);
|
||
|
||
/// 撤销最近一步操作
|
||
/// @return true 若撤销成功
|
||
bool undo();
|
||
|
||
/// 重做最近撤销的操作
|
||
/// @return true 若重做成功
|
||
bool redo();
|
||
|
||
/// 是否可撤销
|
||
[[nodiscard]] bool can_undo() const { return !undo_stack_.empty(); }
|
||
|
||
/// 是否可重做
|
||
[[nodiscard]] bool can_redo() const { return !redo_stack_.empty(); }
|
||
|
||
/// 撤销栈深度
|
||
[[nodiscard]] size_t undo_depth() const { return undo_stack_.size(); }
|
||
|
||
/// 重做栈深度
|
||
[[nodiscard]] size_t redo_depth() const { return redo_stack_.size(); }
|
||
|
||
/// 清空所有历史
|
||
void clear();
|
||
|
||
/// 获取撤销栈顶命令描述
|
||
[[nodiscard]] std::string undo_description() const;
|
||
|
||
/// 获取重做栈顶命令描述
|
||
[[nodiscard]] std::string redo_description() const;
|
||
|
||
// ── 事务日志 ──
|
||
|
||
/// 开启事务日志(追加模式)
|
||
/// @param filepath 日志文件路径
|
||
/// @return true 若成功
|
||
bool enable_log(const std::string& filepath);
|
||
|
||
/// 关闭事务日志
|
||
void disable_log();
|
||
|
||
/// 是否开启了事务日志
|
||
[[nodiscard]] bool log_enabled() const { return log_enabled_; }
|
||
|
||
/// 写入检查点
|
||
void write_checkpoint();
|
||
|
||
/// 从日志文件恢复(崩溃恢复)
|
||
/// @param filepath 日志文件路径
|
||
/// @return 恢复的命令数(0 表示无日志或恢复失败)
|
||
size_t recover_from_log(const std::string& filepath);
|
||
|
||
/// 设置最大撤销深度(0 = 无限)
|
||
void set_max_undo_depth(size_t max_depth) { max_undo_depth_ = max_depth; }
|
||
|
||
/// 获取已执行命令总数
|
||
[[nodiscard]] int64_t total_commands() const { return cmd_counter_.load(); }
|
||
|
||
private:
|
||
std::deque<std::unique_ptr<Command>> undo_stack_;
|
||
std::deque<std::unique_ptr<Command>> redo_stack_;
|
||
size_t max_undo_depth_ = 0; // 0 = unlimited
|
||
|
||
// 事务日志
|
||
bool log_enabled_ = false;
|
||
std::ofstream log_file_;
|
||
std::string log_path_;
|
||
|
||
std::atomic<int64_t> cmd_counter_{0};
|
||
|
||
/// 将命令序列化到日志文件
|
||
void log_command(const Command& cmd, TransactionLogEntry::Type type);
|
||
/// 从日志中重放一条命令
|
||
std::unique_ptr<Command> replay_from_log(const TransactionLogEntry& entry);
|
||
|
||
/// 清理多余撤销历史
|
||
void trim_undo_stack();
|
||
};
|
||
|
||
} // namespace vde::core
|